Depal: Get depth scale factors dynamically

This commit is contained in:
Henrik Rydgård 2023-02-10 00:17:49 +01:00
parent 547ecec074
commit a083a65f77
4 changed files with 21 additions and 15 deletions

View file

@ -51,13 +51,10 @@ void GenerateDepalShader300(ShaderWriter &writer, const DepalConfig &config) {
writer.C(" vec2 texcoord = v_texcoord;\n"); writer.C(" vec2 texcoord = v_texcoord;\n");
// Implement the swizzle we need to simulate, if a game uses 8888 framebuffers and any other mode than "6" to access depth textures. // Implement the swizzle we need to simulate, if a game uses 8888 framebuffers and any other mode than "6" to access depth textures.
// This implements the "2" mode swizzle (it fixes up the Y direction but not X. See comments on issue #15898) // This implements the "2" mode swizzle (it fixes up the Y direction but not X. See comments on issue #15898, Tantalus games)
// NOTE: This swizzle can be made to work with any power-of-2 resolution scaleFactor by shifting // NOTE: This swizzle can be made to work with any power-of-2 resolution scaleFactor by shifting
// the bits around, but not sure how to handle 3x scaling. For now this is 1x-only (rough edges at higher resolutions). // the bits around, but not sure how to handle 3x scaling. For now this is 1x-only (rough edges at higher resolutions).
if (config.bufferFormat == GE_FORMAT_DEPTH16) { if (config.bufferFormat == GE_FORMAT_DEPTH16) {
DepthScaleFactors factors = GetDepthScaleFactors(gstate_c.UseFlags());
writer.ConstFloat("z_scale", factors.ScaleU16());
writer.ConstFloat("z_offset", factors.Offset());
if (config.depthUpperBits == 0x2) { if (config.depthUpperBits == 0x2) {
writer.C(R"( writer.C(R"(
int x = int((texcoord.x / scaleFactor) * texSize.x); int x = int((texcoord.x / scaleFactor) * texSize.x);

View file

@ -39,23 +39,28 @@ static const SamplerDef samplers[1] = {
{ 0, "tex", SamplerFlags::ARRAY_ON_VULKAN }, { 0, "tex", SamplerFlags::ARRAY_ON_VULKAN },
}; };
const UniformDef g_draw2Duniforms[2] = { const UniformDef g_draw2Duniforms[4] = {
{ "vec2", "texSize", 0 }, { "vec2", "texSize", 0 },
{ "float", "scaleFactor", 1}, { "float", "scaleFactor", 1},
{ "float", "z_scale", 2 },
{ "float", "z_offset", 3 },
}; };
struct Draw2DUB { struct Draw2DUB {
float texSizeX; float texSizeX;
float texSizeY; float texSizeY;
float scaleFactor; float scaleFactor;
float zScale;
float zOffset;
}; };
const UniformBufferDesc draw2DUBDesc{ sizeof(Draw2DUB), { const UniformBufferDesc draw2DUBDesc{ sizeof(Draw2DUB), {
{ "texSize", -1, 0, UniformType::FLOAT2, 0 }, { "texSize", -1, 0, UniformType::FLOAT2, 0 },
{ "scaleFactor", -1, 1, UniformType::FLOAT1, 8 }, { "scaleFactor", -1, 1, UniformType::FLOAT1, 8 },
{ "z_scale", -1, 1, UniformType::FLOAT1, 12 },
{ "z_offset", -1, 1, UniformType::FLOAT1, 16 },
} }; } };
Draw2DPipelineInfo GenerateDraw2DCopyColorFs(ShaderWriter &writer) { Draw2DPipelineInfo GenerateDraw2DCopyColorFs(ShaderWriter &writer) {
writer.DeclareSamplers(samplers); writer.DeclareSamplers(samplers);
writer.BeginFSMain(Slice<UniformDef>::empty(), varyings); writer.BeginFSMain(Slice<UniformDef>::empty(), varyings);
@ -95,8 +100,8 @@ Draw2DPipelineInfo GenerateDraw2DCopyDepthFs(ShaderWriter &writer) {
writer.EndFSMain("outColor"); writer.EndFSMain("outColor");
return Draw2DPipelineInfo{ return Draw2DPipelineInfo{
"draw2d_copy_depth", "draw2d_copy_r16_to_depth",
RASTER_DEPTH, RASTER_DEPTH, // Unused in this case, I think.
RASTER_DEPTH, RASTER_DEPTH,
}; };
} }
@ -319,6 +324,10 @@ void Draw2D::DrawStrip2D(Draw::Texture *tex, const Draw2DVertex *verts, int vert
ub.texSizeY = tex ? tex->Height() : texH; ub.texSizeY = tex ? tex->Height() : texH;
ub.scaleFactor = (float)scaleFactor; ub.scaleFactor = (float)scaleFactor;
DepthScaleFactors zScaleFactors = GetDepthScaleFactors(gstate_c.UseFlags());
ub.zScale = zScaleFactors.Scale();
ub.zOffset = zScaleFactors.Offset();
draw_->BindPipeline(pipeline->pipeline); draw_->BindPipeline(pipeline->pipeline);
draw_->UpdateDynamicUniformBuffer(&ub, sizeof(ub)); draw_->UpdateDynamicUniformBuffer(&ub, sizeof(ub));
@ -356,7 +365,7 @@ Draw2DPipeline *FramebufferManagerCommon::Get2DPipeline(Draw2DShader shader) {
pipeline = draw2DPipelineColorRect2Lin_; pipeline = draw2DPipelineColorRect2Lin_;
break; break;
case DRAW2D_COPY_DEPTH: case DRAW2D_COPY_R16_TO_DEPTH:
if (!draw_->GetDeviceCaps().fragmentShaderDepthWriteSupported) { if (!draw_->GetDeviceCaps().fragmentShaderDepthWriteSupported) {
// Can't do it // Can't do it
return nullptr; return nullptr;

View file

@ -13,7 +13,7 @@ struct Draw2DVertex {
enum Draw2DShader { enum Draw2DShader {
DRAW2D_COPY_COLOR, DRAW2D_COPY_COLOR,
DRAW2D_COPY_DEPTH, DRAW2D_COPY_R16_TO_DEPTH,
DRAW2D_565_TO_DEPTH, DRAW2D_565_TO_DEPTH,
DRAW2D_565_TO_DEPTH_DESWIZZLE, DRAW2D_565_TO_DEPTH_DESWIZZLE,
DRAW2D_COPY_COLOR_RECT2LIN, DRAW2D_COPY_COLOR_RECT2LIN,
@ -21,7 +21,7 @@ enum Draw2DShader {
inline RasterChannel Draw2DSourceChannel(Draw2DShader shader) { inline RasterChannel Draw2DSourceChannel(Draw2DShader shader) {
switch (shader) { switch (shader) {
case DRAW2D_COPY_DEPTH: case DRAW2D_COPY_R16_TO_DEPTH:
return RASTER_DEPTH; return RASTER_DEPTH;
case DRAW2D_COPY_COLOR: case DRAW2D_COPY_COLOR:
case DRAW2D_565_TO_DEPTH: case DRAW2D_565_TO_DEPTH:
@ -38,7 +38,7 @@ struct Draw2DPipelineInfo {
Slice<SamplerDef> samplers; Slice<SamplerDef> samplers;
}; };
extern const UniformDef g_draw2Duniforms[2]; extern const UniformDef g_draw2Duniforms[4];
struct Draw2DPipeline { struct Draw2DPipeline {
Draw::Pipeline *pipeline; Draw::Pipeline *pipeline;

View file

@ -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. // 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) { if (useRaster) {
BlitUsingRaster(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, false, dst->renderScaleFactor, Get2DPipeline(Draw2DShader::DRAW2D_COPY_DEPTH), "BlitDepthRaster"); BlitUsingRaster(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, false, dst->renderScaleFactor, Get2DPipeline(Draw2DShader::DRAW2D_COPY_R16_TO_DEPTH), "BlitDepthRaster");
} else if (useCopy) { } 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"); 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"); RebindFramebuffer("After BlitFramebufferDepth");
@ -3036,7 +3036,7 @@ void FramebufferManagerCommon::DrawActiveTexture(float x, float y, float w, floa
// Rearrange to strip form. // Rearrange to strip form.
std::swap(coord[2], coord[3]); std::swap(coord[2], coord[3]);
draw2D_.DrawStrip2D(nullptr, coord, 4, (flags & DRAWTEX_LINEAR) != 0, Get2DPipeline((flags & DRAWTEX_DEPTH) ? DRAW2D_COPY_DEPTH : DRAW2D_COPY_COLOR)); draw2D_.DrawStrip2D(nullptr, coord, 4, (flags & DRAWTEX_LINEAR) != 0, Get2DPipeline((flags & DRAWTEX_DEPTH) ? DRAW2D_COPY_R16_TO_DEPTH : DRAW2D_COPY_COLOR));
gstate_c.Dirty(DIRTY_ALL_RENDER_STATE); gstate_c.Dirty(DIRTY_ALL_RENDER_STATE);
} }
@ -3135,7 +3135,7 @@ void FramebufferManagerCommon::BlitFramebuffer(VirtualFramebuffer *dst, int dstX
draw_->BlitFramebuffer(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, 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); channel == RASTER_COLOR ? Draw::FB_COLOR_BIT : Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, tag);
} else { } else {
Draw2DPipeline *pipeline = Get2DPipeline(channel == RASTER_COLOR ? DRAW2D_COPY_COLOR : DRAW2D_COPY_DEPTH); Draw2DPipeline *pipeline = Get2DPipeline(channel == RASTER_COLOR ? DRAW2D_COPY_COLOR : DRAW2D_COPY_R16_TO_DEPTH);
Draw::Framebuffer *srcFBO = src->fbo; Draw::Framebuffer *srcFBO = src->fbo;
if (src == dst) { if (src == dst) {
Draw::Framebuffer *tempFBO = GetTempFBO(TempFBO::BLIT, src->renderWidth, src->renderHeight); Draw::Framebuffer *tempFBO = GetTempFBO(TempFBO::BLIT, src->renderWidth, src->renderHeight);