mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Split the depth copy shader into depth copy and depth encode, dynamic depth scale in Draw2D
This commit is contained in:
parent
a083a65f77
commit
1938fa44d4
5 changed files with 68 additions and 31 deletions
|
@ -114,7 +114,7 @@ void GenerateDepalShader300(ShaderWriter &writer, const DepalConfig &config) {
|
|||
break;
|
||||
case GE_FORMAT_DEPTH16:
|
||||
// Decode depth buffer.
|
||||
writer.C(" float depth = (color.x - z_offset) * z_scale;\n");
|
||||
writer.C(" float depth = (color.x - z_offset) * z_scale * 65535.0f;\n");
|
||||
|
||||
if (config.bufferFormat == GE_FORMAT_DEPTH16 && config.textureFormat == GE_TFMT_5650) {
|
||||
// Convert depth to 565, without going through a CLUT.
|
||||
|
|
|
@ -39,11 +39,12 @@ static const SamplerDef samplers[1] = {
|
|||
{ 0, "tex", SamplerFlags::ARRAY_ON_VULKAN },
|
||||
};
|
||||
|
||||
const UniformDef g_draw2Duniforms[4] = {
|
||||
const UniformDef g_draw2Duniforms[5] = {
|
||||
{ "vec2", "texSize", 0 },
|
||||
{ "float", "scaleFactor", 1},
|
||||
{ "float", "z_scale", 2 },
|
||||
{ "float", "z_offset", 3 },
|
||||
{ "float", "z_scale_inv", 3 },
|
||||
{ "float", "z_offset", 4 },
|
||||
};
|
||||
|
||||
struct Draw2DUB {
|
||||
|
@ -51,6 +52,7 @@ struct Draw2DUB {
|
|||
float texSizeY;
|
||||
float scaleFactor;
|
||||
float zScale;
|
||||
float zScaleInv;
|
||||
float zOffset;
|
||||
};
|
||||
|
||||
|
@ -58,7 +60,8 @@ const UniformBufferDesc draw2DUBDesc{ sizeof(Draw2DUB), {
|
|||
{ "texSize", -1, 0, UniformType::FLOAT2, 0 },
|
||||
{ "scaleFactor", -1, 1, UniformType::FLOAT1, 8 },
|
||||
{ "z_scale", -1, 1, UniformType::FLOAT1, 12 },
|
||||
{ "z_offset", -1, 1, UniformType::FLOAT1, 16 },
|
||||
{ "z_scale_inv", -1, 1, UniformType::FLOAT1, 16 },
|
||||
{ "z_offset", -1, 1, UniformType::FLOAT1, 20 },
|
||||
} };
|
||||
|
||||
Draw2DPipelineInfo GenerateDraw2DCopyColorFs(ShaderWriter &writer) {
|
||||
|
@ -100,23 +103,41 @@ Draw2DPipelineInfo GenerateDraw2DCopyDepthFs(ShaderWriter &writer) {
|
|||
writer.EndFSMain("outColor");
|
||||
|
||||
return Draw2DPipelineInfo{
|
||||
"draw2d_copy_r16_to_depth",
|
||||
"draw2d_copy_depth",
|
||||
RASTER_DEPTH, // Unused in this case, I think.
|
||||
RASTER_DEPTH,
|
||||
};
|
||||
}
|
||||
|
||||
Draw2DPipelineInfo GenerateDraw2DEncodeDepthFs(ShaderWriter &writer) {
|
||||
writer.SetFlags(ShaderWriterFlags::FS_WRITE_DEPTH);
|
||||
writer.HighPrecisionFloat();
|
||||
writer.DeclareSamplers(samplers);
|
||||
writer.BeginFSMain(g_draw2Duniforms, varyings);
|
||||
writer.C(" vec4 outColor = vec4(0.0, 0.0, 0.0, 0.0);\n");
|
||||
writer.C(" float depthValue = ").SampleTexture2D("tex", "v_texcoord.xy").C(".x;\n");
|
||||
writer.C(" gl_FragDepth = (depthValue * z_scale_inv) + z_offset;\n");
|
||||
writer.EndFSMain("outColor");
|
||||
|
||||
return Draw2DPipelineInfo{
|
||||
"draw2d_copy_r16_to_depth",
|
||||
RASTER_COLOR,
|
||||
RASTER_DEPTH,
|
||||
};
|
||||
}
|
||||
|
||||
Draw2DPipelineInfo GenerateDraw2D565ToDepthFs(ShaderWriter &writer) {
|
||||
writer.SetFlags(ShaderWriterFlags::FS_WRITE_DEPTH);
|
||||
writer.HighPrecisionFloat();
|
||||
writer.DeclareSamplers(samplers);
|
||||
writer.BeginFSMain(Slice<UniformDef>::empty(), varyings);
|
||||
writer.BeginFSMain(g_draw2Duniforms, varyings);
|
||||
writer.C(" vec4 outColor = vec4(0.0, 0.0, 0.0, 0.0);\n");
|
||||
// Unlike when just copying a depth buffer, here we're generating new depth values so we'll
|
||||
// have to apply the scaling.
|
||||
DepthScaleFactors factors = GetDepthScaleFactors(gstate_c.UseFlags());
|
||||
writer.C(" vec3 rgb = ").SampleTexture2D("tex", "v_texcoord.xy").C(".xyz;\n");
|
||||
writer.F(" highp float depthValue = (floor(rgb.x * 31.99) + floor(rgb.y * 63.99) * 32.0 + floor(rgb.z * 31.99) * 2048.0); \n");
|
||||
writer.F(" gl_FragDepth = (depthValue / %f) + %f;\n", factors.ScaleU16(), factors.Offset());
|
||||
writer.F(" float depthValue = ((floor(rgb.x * 31.99) + floor(rgb.y * 63.99) * 32.0 + floor(rgb.z * 31.99) * 2048.0)) / 65535.0; \n");
|
||||
writer.C(" gl_FragDepth = (depthValue * z_scale_inv) + z_offset;\n");
|
||||
writer.EndFSMain("outColor");
|
||||
|
||||
return Draw2DPipelineInfo{
|
||||
|
@ -128,6 +149,7 @@ Draw2DPipelineInfo GenerateDraw2D565ToDepthFs(ShaderWriter &writer) {
|
|||
|
||||
Draw2DPipelineInfo GenerateDraw2D565ToDepthDeswizzleFs(ShaderWriter &writer) {
|
||||
writer.SetFlags(ShaderWriterFlags::FS_WRITE_DEPTH);
|
||||
writer.HighPrecisionFloat();
|
||||
writer.DeclareSamplers(samplers);
|
||||
writer.BeginFSMain(g_draw2Duniforms, varyings);
|
||||
writer.C(" vec4 outColor = vec4(0.0, 0.0, 0.0, 0.0);\n");
|
||||
|
@ -140,9 +162,9 @@ Draw2DPipelineInfo GenerateDraw2D565ToDepthDeswizzleFs(ShaderWriter &writer) {
|
|||
writer.C(" float in_strip = mod(coord.y, strip);\n");
|
||||
writer.C(" coord.y = coord.y - in_strip + strip - in_strip;\n");
|
||||
writer.C(" coord /= tsize;\n");
|
||||
writer.C(" vec3 rgb = ").SampleTexture2D("tex", "coord").C(".xyz;\n");
|
||||
writer.F(" highp float depthValue = (floor(rgb.x * 31.99) + floor(rgb.y * 63.99) * 32.0 + floor(rgb.z * 31.99) * 2048.0); \n");
|
||||
writer.F(" gl_FragDepth = (depthValue / %f) + %f;\n", factors.ScaleU16(), factors.Offset());
|
||||
writer.C(" highp vec3 rgb = ").SampleTexture2D("tex", "coord").C(".xyz;\n");
|
||||
writer.F(" highp float depthValue = floor(rgb.x * 31.99) + floor(rgb.y * 63.99) * 32.0 + floor(rgb.z * 31.99) * 2048.0; \n");
|
||||
writer.C(" gl_FragDepth = z_offset + ((depthValue / 65535.0) * z_scale_inv);\n");
|
||||
writer.EndFSMain("outColor");
|
||||
|
||||
return Draw2DPipelineInfo{
|
||||
|
@ -253,7 +275,7 @@ Draw2DPipeline *Draw2D::Create2DPipeline(std::function<Draw2DPipelineInfo (Shade
|
|||
};
|
||||
InputLayout *inputLayout = draw_->CreateInputLayout(desc);
|
||||
|
||||
BlendState *blend = draw_->CreateBlendState({ false, info.writeChannel == RASTER_COLOR ? 0xF : 0 });
|
||||
BlendState *blend = draw_->CreateBlendState({ false, info.writeChannel == RASTER_COLOR ? 0xF : 0x0 });
|
||||
|
||||
DepthStencilStateDesc dsDesc{};
|
||||
if (info.writeChannel == RASTER_DEPTH) {
|
||||
|
@ -326,6 +348,7 @@ void Draw2D::DrawStrip2D(Draw::Texture *tex, const Draw2DVertex *verts, int vert
|
|||
|
||||
DepthScaleFactors zScaleFactors = GetDepthScaleFactors(gstate_c.UseFlags());
|
||||
ub.zScale = zScaleFactors.Scale();
|
||||
ub.zScaleInv = 1.0f / ub.zScale;
|
||||
ub.zOffset = zScaleFactors.Offset();
|
||||
|
||||
draw_->BindPipeline(pipeline->pipeline);
|
||||
|
@ -352,10 +375,10 @@ Draw2DPipeline *FramebufferManagerCommon::Get2DPipeline(Draw2DShader shader) {
|
|||
|
||||
switch (shader) {
|
||||
case DRAW2D_COPY_COLOR:
|
||||
if (!draw2DPipelineColor_) {
|
||||
draw2DPipelineColor_ = draw2D_.Create2DPipeline(&GenerateDraw2DCopyColorFs);
|
||||
if (!draw2DPipelineCopyColor_) {
|
||||
draw2DPipelineCopyColor_ = draw2D_.Create2DPipeline(&GenerateDraw2DCopyColorFs);
|
||||
}
|
||||
pipeline = draw2DPipelineColor_;
|
||||
pipeline = draw2DPipelineCopyColor_;
|
||||
break;
|
||||
|
||||
case DRAW2D_COPY_COLOR_RECT2LIN:
|
||||
|
@ -364,16 +387,26 @@ Draw2DPipeline *FramebufferManagerCommon::Get2DPipeline(Draw2DShader shader) {
|
|||
}
|
||||
pipeline = draw2DPipelineColorRect2Lin_;
|
||||
break;
|
||||
|
||||
case DRAW2D_COPY_R16_TO_DEPTH:
|
||||
case DRAW2D_COPY_DEPTH:
|
||||
if (!draw_->GetDeviceCaps().fragmentShaderDepthWriteSupported) {
|
||||
// Can't do it
|
||||
return nullptr;
|
||||
}
|
||||
if (!draw2DPipelineDepth_) {
|
||||
draw2DPipelineDepth_ = draw2D_.Create2DPipeline(&GenerateDraw2DCopyDepthFs);
|
||||
if (!draw2DPipelineCopyDepth_) {
|
||||
draw2DPipelineCopyDepth_ = draw2D_.Create2DPipeline(&GenerateDraw2DCopyDepthFs);
|
||||
}
|
||||
pipeline = draw2DPipelineDepth_;
|
||||
pipeline = draw2DPipelineCopyDepth_;
|
||||
break;
|
||||
|
||||
case DRAW2D_ENCODE_R16_TO_DEPTH:
|
||||
if (!draw_->GetDeviceCaps().fragmentShaderDepthWriteSupported) {
|
||||
// Can't do it
|
||||
return nullptr;
|
||||
}
|
||||
if (!draw2DPipelineEncodeDepth_) {
|
||||
draw2DPipelineEncodeDepth_ = draw2D_.Create2DPipeline(&GenerateDraw2DEncodeDepthFs);
|
||||
}
|
||||
pipeline = draw2DPipelineEncodeDepth_;
|
||||
break;
|
||||
|
||||
case DRAW2D_565_TO_DEPTH:
|
||||
|
|
|
@ -13,7 +13,8 @@ struct Draw2DVertex {
|
|||
|
||||
enum Draw2DShader {
|
||||
DRAW2D_COPY_COLOR,
|
||||
DRAW2D_COPY_R16_TO_DEPTH,
|
||||
DRAW2D_COPY_DEPTH,
|
||||
DRAW2D_ENCODE_R16_TO_DEPTH,
|
||||
DRAW2D_565_TO_DEPTH,
|
||||
DRAW2D_565_TO_DEPTH_DESWIZZLE,
|
||||
DRAW2D_COPY_COLOR_RECT2LIN,
|
||||
|
@ -21,9 +22,10 @@ enum Draw2DShader {
|
|||
|
||||
inline RasterChannel Draw2DSourceChannel(Draw2DShader shader) {
|
||||
switch (shader) {
|
||||
case DRAW2D_COPY_R16_TO_DEPTH:
|
||||
case DRAW2D_COPY_DEPTH:
|
||||
return RASTER_DEPTH;
|
||||
case DRAW2D_COPY_COLOR:
|
||||
case DRAW2D_ENCODE_R16_TO_DEPTH:
|
||||
case DRAW2D_565_TO_DEPTH:
|
||||
case DRAW2D_565_TO_DEPTH_DESWIZZLE:
|
||||
default:
|
||||
|
@ -38,7 +40,7 @@ struct Draw2DPipelineInfo {
|
|||
Slice<SamplerDef> samplers;
|
||||
};
|
||||
|
||||
extern const UniformDef g_draw2Duniforms[4];
|
||||
extern const UniformDef g_draw2Duniforms[5];
|
||||
|
||||
struct Draw2DPipeline {
|
||||
Draw::Pipeline *pipeline;
|
||||
|
|
|
@ -974,7 +974,7 @@ void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, Vir
|
|||
|
||||
// Some GPUs can copy depth but only if stencil gets to come along for the ride. We only want to use this if there is no blit functionality.
|
||||
if (useRaster) {
|
||||
BlitUsingRaster(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, false, dst->renderScaleFactor, Get2DPipeline(Draw2DShader::DRAW2D_COPY_R16_TO_DEPTH), "BlitDepthRaster");
|
||||
BlitUsingRaster(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, false, dst->renderScaleFactor, Get2DPipeline(Draw2DShader::DRAW2D_COPY_DEPTH), "BlitDepthRaster");
|
||||
} else if (useCopy) {
|
||||
draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "CopyFramebufferDepth");
|
||||
RebindFramebuffer("After BlitFramebufferDepth");
|
||||
|
@ -2964,9 +2964,10 @@ void FramebufferManagerCommon::ReleasePipelines() {
|
|||
DoRelease(stencilReadbackPipeline_);
|
||||
DoRelease(depthReadbackSampler_);
|
||||
DoRelease(depthReadbackPipeline_);
|
||||
DoRelease(draw2DPipelineColor_);
|
||||
DoRelease(draw2DPipelineCopyColor_);
|
||||
DoRelease(draw2DPipelineColorRect2Lin_);
|
||||
DoRelease(draw2DPipelineDepth_);
|
||||
DoRelease(draw2DPipelineCopyDepth_);
|
||||
DoRelease(draw2DPipelineEncodeDepth_);
|
||||
DoRelease(draw2DPipeline565ToDepth_);
|
||||
DoRelease(draw2DPipeline565ToDepthDeswizzle_);
|
||||
}
|
||||
|
@ -3036,7 +3037,7 @@ void FramebufferManagerCommon::DrawActiveTexture(float x, float y, float w, floa
|
|||
// Rearrange to strip form.
|
||||
std::swap(coord[2], coord[3]);
|
||||
|
||||
draw2D_.DrawStrip2D(nullptr, coord, 4, (flags & DRAWTEX_LINEAR) != 0, Get2DPipeline((flags & DRAWTEX_DEPTH) ? DRAW2D_COPY_R16_TO_DEPTH : DRAW2D_COPY_COLOR));
|
||||
draw2D_.DrawStrip2D(nullptr, coord, 4, (flags & DRAWTEX_LINEAR) != 0, Get2DPipeline((flags & DRAWTEX_DEPTH) ? DRAW2D_ENCODE_R16_TO_DEPTH : DRAW2D_COPY_COLOR));
|
||||
|
||||
gstate_c.Dirty(DIRTY_ALL_RENDER_STATE);
|
||||
}
|
||||
|
@ -3135,7 +3136,7 @@ void FramebufferManagerCommon::BlitFramebuffer(VirtualFramebuffer *dst, int dstX
|
|||
draw_->BlitFramebuffer(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2,
|
||||
channel == RASTER_COLOR ? Draw::FB_COLOR_BIT : Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, tag);
|
||||
} else {
|
||||
Draw2DPipeline *pipeline = Get2DPipeline(channel == RASTER_COLOR ? DRAW2D_COPY_COLOR : DRAW2D_COPY_R16_TO_DEPTH);
|
||||
Draw2DPipeline *pipeline = Get2DPipeline(channel == RASTER_COLOR ? DRAW2D_COPY_COLOR : DRAW2D_COPY_DEPTH);
|
||||
Draw::Framebuffer *srcFBO = src->fbo;
|
||||
if (src == dst) {
|
||||
Draw::Framebuffer *tempFBO = GetTempFBO(TempFBO::BLIT, src->renderWidth, src->renderHeight);
|
||||
|
|
|
@ -605,9 +605,10 @@ protected:
|
|||
Draw::SamplerState *depthReadbackSampler_ = nullptr;
|
||||
|
||||
// Draw2D pipelines
|
||||
Draw2DPipeline *draw2DPipelineColor_ = nullptr;
|
||||
Draw2DPipeline *draw2DPipelineCopyColor_ = nullptr;
|
||||
Draw2DPipeline *draw2DPipelineColorRect2Lin_ = nullptr;
|
||||
Draw2DPipeline *draw2DPipelineDepth_ = nullptr;
|
||||
Draw2DPipeline *draw2DPipelineCopyDepth_ = nullptr;
|
||||
Draw2DPipeline *draw2DPipelineEncodeDepth_ = nullptr;
|
||||
Draw2DPipeline *draw2DPipeline565ToDepth_ = nullptr;
|
||||
Draw2DPipeline *draw2DPipeline565ToDepthDeswizzle_ = nullptr;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue