GPU/HW: Use UIDs for shader generation

shader-uid
Stenzek 3 months ago
parent 1ffee71757
commit 431567d41a
No known key found for this signature in database

@ -1226,8 +1226,16 @@ bool GPU_HW::CompilePipelines(Error* error)
batch_fragment_shaders.enumerate(destroy_shader); batch_fragment_shaders.enumerate(destroy_shader);
}); });
GPU_HW_ShaderGen::BatchVertexShaderSelector vssel = {};
vssel.upscaled = upscaled;
vssel.msaa = msaa;
vssel.per_sample_shading = per_sample_shading;
vssel.pgxp_depth = m_pgxp_depth_buffer;
vssel.disable_color_perspective = disable_color_perspective;
for (u8 textured = 0; textured < 2; textured++) for (u8 textured = 0; textured < 2; textured++)
{ {
vssel.textured = (textured != 0);
for (u8 palette = 0; palette < 3; palette++) for (u8 palette = 0; palette < 3; palette++)
{ {
if (palette && !textured) if (palette && !textured)
@ -1235,17 +1243,18 @@ bool GPU_HW::CompilePipelines(Error* error)
if (palette == 2 && !needs_page_texture) if (palette == 2 && !needs_page_texture)
continue; continue;
vssel.palette = (palette == 1);
vssel.page_texture = (palette == 2);
for (u8 sprite = 0; sprite < 2; sprite++) for (u8 sprite = 0; sprite < 2; sprite++)
{ {
if (sprite && (!textured || !m_allow_sprite_mode)) if (sprite && (!textured || !m_allow_sprite_mode))
continue; continue;
const bool uv_limits = ShouldClampUVs(sprite ? m_sprite_texture_filtering : m_texture_filtering); vssel.uv_limits = ShouldClampUVs(sprite ? m_sprite_texture_filtering : m_texture_filtering);
const std::string vs = shadergen.GenerateBatchVertexShader( vssel.force_round_texcoords = !sprite && force_round_texcoords;
upscaled, msaa, per_sample_shading, textured != 0, palette == 1, palette == 2, uv_limits, if (!(batch_vertex_shaders[textured][palette][sprite] = g_gpu_device->CreateShader(
!sprite && force_round_texcoords, m_pgxp_depth_buffer, disable_color_perspective); GPUShaderStage::Vertex, shadergen.GetLanguage(), shadergen.GenerateBatchVertexShader(vssel), error)))
if (!(batch_vertex_shaders[textured][palette][sprite] =
g_gpu_device->CreateShader(GPUShaderStage::Vertex, shadergen.GetLanguage(), vs, error)))
{ {
return false; return false;
} }
@ -1256,6 +1265,15 @@ bool GPU_HW::CompilePipelines(Error* error)
} }
} }
GPU_HW_ShaderGen::BatchFragmentShaderSelector fssel = {};
fssel.upscaled = upscaled;
fssel.msaa = msaa;
fssel.per_sample_shading = per_sample_shading;
fssel.modulation_crop = modulation_crop;
fssel.true_color = true_color;
fssel.disable_color_perspective = disable_color_perspective;
fssel.write_mask_as_depth = m_write_mask_as_depth;
for (u8 depth_test = 0; depth_test < 2; depth_test++) for (u8 depth_test = 0; depth_test < 2; depth_test++)
{ {
if (depth_test && !needs_rov_depth) if (depth_test && !needs_rov_depth)
@ -1266,6 +1284,8 @@ bool GPU_HW::CompilePipelines(Error* error)
for (u8 render_mode = 0; render_mode < 5; render_mode++) for (u8 render_mode = 0; render_mode < 5; render_mode++)
{ {
fssel.render_mode = static_cast<BatchRenderMode>(render_mode);
for (u8 transparency_mode = 0; transparency_mode < 5; transparency_mode++) for (u8 transparency_mode = 0; transparency_mode < 5; transparency_mode++)
{ {
if ( if (
@ -1290,6 +1310,12 @@ bool GPU_HW::CompilePipelines(Error* error)
continue; continue;
} }
fssel.transparency = static_cast<GPUTransparencyMode>(transparency_mode);
fssel.use_rov = (fssel.render_mode == BatchRenderMode::ShaderBlend && m_use_rov_for_shader_blend);
fssel.use_rov_depth = (fssel.use_rov && needs_rov_depth);
fssel.rov_depth_test = (fssel.use_rov && depth_test != 0);
fssel.rov_depth_write = (fssel.rov_depth_test && fssel.transparency == GPUTransparencyMode::Disabled);
for (u8 texture_mode = 0; texture_mode < max_active_texture_modes; texture_mode++) for (u8 texture_mode = 0; texture_mode < max_active_texture_modes; texture_mode++)
{ {
if (!needs_page_texture && (texture_mode == static_cast<u8>(BatchTextureMode::PageTexture) || if (!needs_page_texture && (texture_mode == static_cast<u8>(BatchTextureMode::PageTexture) ||
@ -1298,6 +1324,15 @@ bool GPU_HW::CompilePipelines(Error* error)
continue; continue;
} }
const bool sprite = (static_cast<BatchTextureMode>(texture_mode) >= BatchTextureMode::SpriteStart);
fssel.uv_limits = ShouldClampUVs(sprite ? m_sprite_texture_filtering : m_texture_filtering);
fssel.force_round_texcoords = !sprite && force_round_texcoords;
fssel.texture_mode =
static_cast<BatchTextureMode>(texture_mode - (sprite ? static_cast<u8>(BatchTextureMode::SpriteStart) : 0));
fssel.texture_filtering = sprite ? m_sprite_texture_filtering : m_texture_filtering;
fssel.is_blended_texture_filtering =
(fssel.texture_mode != BatchTextureMode::Disabled && IsBlendedTextureFiltering(fssel.texture_filtering));
for (u8 check_mask = 0; check_mask < 2; check_mask++) for (u8 check_mask = 0; check_mask < 2; check_mask++)
{ {
if (check_mask && render_mode != static_cast<u8>(BatchRenderMode::ShaderBlend)) if (check_mask && render_mode != static_cast<u8>(BatchRenderMode::ShaderBlend))
@ -1312,41 +1347,30 @@ bool GPU_HW::CompilePipelines(Error* error)
continue; continue;
} }
fssel.check_mask = ConvertToBoolUnchecked(check_mask);
for (u8 dithering = 0; dithering < 2; dithering++) for (u8 dithering = 0; dithering < 2; dithering++)
{ {
// Never going to draw with dithering on in true color. // Never going to draw with dithering on in true color.
if (dithering && true_color) if (dithering && true_color)
continue; continue;
fssel.dithering = ConvertToBoolUnchecked(dithering);
fssel.scaled_dithering = (fssel.dithering && scaled_dithering);
for (u8 interlacing = 0; interlacing < 2; interlacing++) for (u8 interlacing = 0; interlacing < 2; interlacing++)
{ {
// Never going to draw with line skipping in force progressive. // Never going to draw with line skipping in force progressive.
if (interlacing && force_progressive_scan) if (interlacing && force_progressive_scan)
continue; continue;
const bool sprite = (static_cast<BatchTextureMode>(texture_mode) >= BatchTextureMode::SpriteStart); fssel.interlacing = ConvertToBoolUnchecked(interlacing);
const bool uv_limits = ShouldClampUVs(sprite ? m_sprite_texture_filtering : m_texture_filtering); fssel.scaled_interlacing = (fssel.interlacing && scaled_interlacing);
const BatchTextureMode shader_texmode = static_cast<BatchTextureMode>(
texture_mode - (sprite ? static_cast<u8>(BatchTextureMode::SpriteStart) : 0));
const GPUTextureFilter texture_filter = sprite ? m_sprite_texture_filtering : m_texture_filtering;
const bool texture_filter_is_blended =
(shader_texmode != BatchTextureMode::Disabled && IsBlendedTextureFiltering(texture_filter));
const bool use_rov =
(render_mode == static_cast<u8>(BatchRenderMode::ShaderBlend) && m_use_rov_for_shader_blend);
const bool rov_depth_test = (use_rov && depth_test != 0);
const bool rov_depth_write = (rov_depth_test && static_cast<GPUTransparencyMode>(transparency_mode) ==
GPUTransparencyMode::Disabled);
const std::string fs = shadergen.GenerateBatchFragmentShader(
static_cast<BatchRenderMode>(render_mode), static_cast<GPUTransparencyMode>(transparency_mode),
shader_texmode, texture_filter, texture_filter_is_blended, upscaled, msaa, per_sample_shading,
uv_limits, !sprite && force_round_texcoords, modulation_crop, true_color,
ConvertToBoolUnchecked(dithering), scaled_dithering, disable_color_perspective,
ConvertToBoolUnchecked(interlacing), scaled_interlacing, ConvertToBoolUnchecked(check_mask),
m_write_mask_as_depth, use_rov, needs_rov_depth, rov_depth_test, rov_depth_write);
if (!(batch_fragment_shaders[depth_test][render_mode][transparency_mode][texture_mode][check_mask] if (!(batch_fragment_shaders[depth_test][render_mode][transparency_mode][texture_mode][check_mask]
[dithering][interlacing] = g_gpu_device->CreateShader( [dithering][interlacing] = g_gpu_device->CreateShader(
GPUShaderStage::Fragment, shadergen.GetLanguage(), fs, error))) GPUShaderStage::Fragment, shadergen.GetLanguage(),
shadergen.GenerateBatchFragmentShader(fssel), error)))
{ {
return false; return false;
} }

@ -72,58 +72,56 @@ std::string GPU_HW_ShaderGen::GenerateScreenVertexShader() const
return std::move(ss).str(); return std::move(ss).str();
} }
std::string GPU_HW_ShaderGen::GenerateBatchVertexShader(bool upscaled, bool msaa, bool per_sample_shading, std::string GPU_HW_ShaderGen::GenerateBatchVertexShader(const BatchVertexShaderSelector sel) const
bool textured, bool palette, bool page_texture, bool uv_limits,
bool force_round_texcoords, bool pgxp_depth,
bool disable_color_perspective) const
{ {
std::stringstream ss; std::stringstream ss;
WriteHeader(ss); WriteHeader(ss);
DefineMacro(ss, "TEXTURED", textured); DefineMacro(ss, "TEXTURED", sel.textured);
DefineMacro(ss, "PALETTE", palette); DefineMacro(ss, "PALETTE", sel.palette);
DefineMacro(ss, "PAGE_TEXTURE", page_texture); DefineMacro(ss, "PAGE_TEXTURE", sel.page_texture);
DefineMacro(ss, "UV_LIMITS", uv_limits); DefineMacro(ss, "UV_LIMITS", sel.uv_limits);
DefineMacro(ss, "FORCE_ROUND_TEXCOORDS", force_round_texcoords); DefineMacro(ss, "FORCE_ROUND_TEXCOORDS", sel.force_round_texcoords);
DefineMacro(ss, "PGXP_DEPTH", pgxp_depth); DefineMacro(ss, "PGXP_DEPTH", sel.pgxp_depth);
DefineMacro(ss, "UPSCALED", upscaled); DefineMacro(ss, "UPSCALED", sel.upscaled);
WriteBatchUniformBuffer(ss); WriteBatchUniformBuffer(ss);
if (textured && page_texture) if (sel.textured && sel.page_texture)
{ {
if (uv_limits) if (sel.uv_limits)
{ {
DeclareVertexEntryPoint( DeclareVertexEntryPoint(
ss, {"float4 a_pos", "float4 a_col0", "uint a_texcoord", "uint a_texpage", "float4 a_uv_limits"}, 1, 1, ss, {"float4 a_pos", "float4 a_col0", "uint a_texcoord", "uint a_texpage", "float4 a_uv_limits"}, 1, 1,
{{"nointerpolation", "float4 v_uv_limits"}}, false, "", msaa, per_sample_shading, disable_color_perspective); {{"nointerpolation", "float4 v_uv_limits"}}, false, "", sel.msaa, sel.per_sample_shading,
sel.disable_color_perspective);
} }
else else
{ {
DeclareVertexEntryPoint(ss, {"float4 a_pos", "float4 a_col0", "uint a_texcoord", "uint a_texpage"}, 1, 1, {}, DeclareVertexEntryPoint(ss, {"float4 a_pos", "float4 a_col0", "uint a_texcoord", "uint a_texpage"}, 1, 1, {},
false, "", msaa, per_sample_shading, disable_color_perspective); false, "", sel.msaa, sel.per_sample_shading, sel.disable_color_perspective);
} }
} }
else if (textured) else if (sel.textured)
{ {
if (uv_limits) if (sel.uv_limits)
{ {
DeclareVertexEntryPoint( DeclareVertexEntryPoint(
ss, {"float4 a_pos", "float4 a_col0", "uint a_texcoord", "uint a_texpage", "float4 a_uv_limits"}, 1, 1, ss, {"float4 a_pos", "float4 a_col0", "uint a_texcoord", "uint a_texpage", "float4 a_uv_limits"}, 1, 1,
{{"nointerpolation", palette ? "uint4 v_texpage" : "uint2 v_texpage"}, {{"nointerpolation", sel.palette ? "uint4 v_texpage" : "uint2 v_texpage"},
{"nointerpolation", "float4 v_uv_limits"}}, {"nointerpolation", "float4 v_uv_limits"}},
false, "", msaa, per_sample_shading, disable_color_perspective); false, "", sel.msaa, sel.per_sample_shading, sel.disable_color_perspective);
} }
else else
{ {
DeclareVertexEntryPoint(ss, {"float4 a_pos", "float4 a_col0", "uint a_texcoord", "uint a_texpage"}, 1, 1, DeclareVertexEntryPoint(ss, {"float4 a_pos", "float4 a_col0", "uint a_texcoord", "uint a_texpage"}, 1, 1,
{{"nointerpolation", palette ? "uint4 v_texpage" : "uint2 v_texpage"}}, false, "", msaa, {{"nointerpolation", sel.palette ? "uint4 v_texpage" : "uint2 v_texpage"}}, false, "",
per_sample_shading, disable_color_perspective); sel.msaa, sel.per_sample_shading, sel.disable_color_perspective);
} }
} }
else else
{ {
DeclareVertexEntryPoint(ss, {"float4 a_pos", "float4 a_col0"}, 1, 0, {}, false, "", msaa, per_sample_shading, DeclareVertexEntryPoint(ss, {"float4 a_pos", "float4 a_col0"}, 1, 0, {}, false, "", sel.msaa,
disable_color_perspective); sel.per_sample_shading, sel.disable_color_perspective);
} }
ss << R"( ss << R"(
@ -2142,59 +2140,54 @@ void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limi
} }
} }
std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader( std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader(const BatchFragmentShaderSelector sel) const
GPU_HW::BatchRenderMode render_mode, GPUTransparencyMode transparency, GPU_HW::BatchTextureMode texture_mode,
GPUTextureFilter texture_filtering, bool is_blended_texture_filtering, bool upscaled, bool msaa,
bool per_sample_shading, bool uv_limits, bool force_round_texcoords, bool modulation_crop, bool true_color,
bool dithering, bool scaled_dithering, bool disable_color_perspective, bool interlacing, bool scaled_interlacing,
bool check_mask, bool write_mask_as_depth, bool use_rov, bool use_rov_depth, bool rov_depth_test,
bool rov_depth_write) const
{ {
DebugAssert(!true_color || !dithering); // Should not be doing dithering+true color. DebugAssert(!sel.true_color || !sel.dithering); // Should not be doing dithering+true color.
DebugAssert(transparency == GPUTransparencyMode::Disabled || render_mode == GPU_HW::BatchRenderMode::ShaderBlend); DebugAssert(sel.transparency == GPUTransparencyMode::Disabled ||
DebugAssert((!rov_depth_test && !rov_depth_write) || (use_rov && use_rov_depth)); sel.render_mode == GPU_HW::BatchRenderMode::ShaderBlend);
DebugAssert((!sel.rov_depth_test && !sel.rov_depth_write) || (sel.use_rov && sel.use_rov_depth));
const bool textured = (texture_mode != GPU_HW::BatchTextureMode::Disabled); const bool textured = (sel.texture_mode != GPU_HW::BatchTextureMode::Disabled);
const bool palette = const bool palette = (sel.texture_mode == GPU_HW::BatchTextureMode::Palette4Bit ||
(texture_mode == GPU_HW::BatchTextureMode::Palette4Bit || texture_mode == GPU_HW::BatchTextureMode::Palette8Bit); sel.texture_mode == GPU_HW::BatchTextureMode::Palette8Bit);
const bool page_texture = (texture_mode == GPU_HW::BatchTextureMode::PageTexture); const bool page_texture = (sel.texture_mode == GPU_HW::BatchTextureMode::PageTexture);
const bool shader_blending = (render_mode == GPU_HW::BatchRenderMode::ShaderBlend); const bool shader_blending = (sel.render_mode == GPU_HW::BatchRenderMode::ShaderBlend);
const bool use_dual_source = (!shader_blending && !use_rov && m_supports_dual_source_blend && const bool use_dual_source = (!shader_blending && !sel.use_rov && m_supports_dual_source_blend &&
((render_mode != GPU_HW::BatchRenderMode::TransparencyDisabled && ((sel.render_mode != GPU_HW::BatchRenderMode::TransparencyDisabled &&
render_mode != GPU_HW::BatchRenderMode::OnlyOpaque) || sel.render_mode != GPU_HW::BatchRenderMode::OnlyOpaque) ||
is_blended_texture_filtering)); sel.is_blended_texture_filtering));
std::stringstream ss; std::stringstream ss;
WriteHeader(ss, use_rov, shader_blending && !use_rov, use_dual_source); WriteHeader(ss, sel.use_rov, shader_blending && !sel.use_rov, use_dual_source);
DefineMacro(ss, "TRANSPARENCY", render_mode != GPU_HW::BatchRenderMode::TransparencyDisabled); DefineMacro(ss, "TRANSPARENCY", sel.render_mode != GPU_HW::BatchRenderMode::TransparencyDisabled);
DefineMacro(ss, "TRANSPARENCY_ONLY_OPAQUE", render_mode == GPU_HW::BatchRenderMode::OnlyOpaque); DefineMacro(ss, "TRANSPARENCY_ONLY_OPAQUE", sel.render_mode == GPU_HW::BatchRenderMode::OnlyOpaque);
DefineMacro(ss, "TRANSPARENCY_ONLY_TRANSPARENT", render_mode == GPU_HW::BatchRenderMode::OnlyTransparent); DefineMacro(ss, "TRANSPARENCY_ONLY_TRANSPARENT", sel.render_mode == GPU_HW::BatchRenderMode::OnlyTransparent);
DefineMacro(ss, "TRANSPARENCY_MODE", static_cast<s32>(transparency)); DefineMacro(ss, "TRANSPARENCY_MODE", static_cast<s32>(sel.transparency));
DefineMacro(ss, "SHADER_BLENDING", shader_blending); DefineMacro(ss, "SHADER_BLENDING", shader_blending);
DefineMacro(ss, "CHECK_MASK_BIT", check_mask); DefineMacro(ss, "CHECK_MASK_BIT", sel.check_mask);
DefineMacro(ss, "TEXTURED", textured); DefineMacro(ss, "TEXTURED", textured);
DefineMacro(ss, "PALETTE", palette); DefineMacro(ss, "PALETTE", palette);
DefineMacro(ss, "PALETTE_4_BIT", texture_mode == GPU_HW::BatchTextureMode::Palette4Bit); DefineMacro(ss, "PALETTE_4_BIT", sel.texture_mode == GPU_HW::BatchTextureMode::Palette4Bit);
DefineMacro(ss, "PALETTE_8_BIT", texture_mode == GPU_HW::BatchTextureMode::Palette8Bit); DefineMacro(ss, "PALETTE_8_BIT", sel.texture_mode == GPU_HW::BatchTextureMode::Palette8Bit);
DefineMacro(ss, "PAGE_TEXTURE", page_texture); DefineMacro(ss, "PAGE_TEXTURE", page_texture);
DefineMacro(ss, "DITHERING", dithering); DefineMacro(ss, "DITHERING", sel.dithering);
DefineMacro(ss, "DITHERING_SCALED", dithering && scaled_dithering); DefineMacro(ss, "DITHERING_SCALED", sel.dithering && sel.scaled_dithering);
DefineMacro(ss, "INTERLACING", interlacing); DefineMacro(ss, "INTERLACING", sel.interlacing);
DefineMacro(ss, "INTERLACING_SCALED", interlacing && scaled_interlacing); DefineMacro(ss, "INTERLACING_SCALED", sel.interlacing && sel.scaled_interlacing);
DefineMacro(ss, "MODULATION_CROP", modulation_crop); DefineMacro(ss, "MODULATION_CROP", sel.modulation_crop);
DefineMacro(ss, "TRUE_COLOR", true_color); DefineMacro(ss, "TRUE_COLOR", sel.true_color);
DefineMacro(ss, "TEXTURE_FILTERING", texture_filtering != GPUTextureFilter::Nearest); DefineMacro(ss, "TEXTURE_FILTERING", sel.texture_filtering != GPUTextureFilter::Nearest);
DefineMacro(ss, "TEXTURE_ALPHA_BLENDING", is_blended_texture_filtering); DefineMacro(ss, "TEXTURE_ALPHA_BLENDING", sel.is_blended_texture_filtering);
DefineMacro(ss, "UV_LIMITS", uv_limits); DefineMacro(ss, "UV_LIMITS", sel.uv_limits);
DefineMacro(ss, "USE_ROV", use_rov); DefineMacro(ss, "USE_ROV", sel.use_rov);
DefineMacro(ss, "USE_ROV_DEPTH", use_rov_depth); DefineMacro(ss, "USE_ROV_DEPTH", sel.use_rov_depth);
DefineMacro(ss, "ROV_DEPTH_TEST", rov_depth_test); DefineMacro(ss, "ROV_DEPTH_TEST", sel.rov_depth_test);
DefineMacro(ss, "ROV_DEPTH_WRITE", rov_depth_write); DefineMacro(ss, "ROV_DEPTH_WRITE", sel.rov_depth_write);
DefineMacro(ss, "USE_DUAL_SOURCE", use_dual_source); DefineMacro(ss, "USE_DUAL_SOURCE", use_dual_source);
DefineMacro(ss, "WRITE_MASK_AS_DEPTH", write_mask_as_depth); DefineMacro(ss, "WRITE_MASK_AS_DEPTH", sel.write_mask_as_depth);
DefineMacro(ss, "FORCE_ROUND_TEXCOORDS", force_round_texcoords); DefineMacro(ss, "FORCE_ROUND_TEXCOORDS", sel.force_round_texcoords);
DefineMacro(ss, "UPSCALED", upscaled); DefineMacro(ss, "UPSCALED", sel.upscaled);
// Used for converting to normalized coordinates for sampling. // Used for converting to normalized coordinates for sampling.
ss << "CONSTANT float2 RCP_VRAM_SIZE = float2(1.0 / float(" << VRAM_WIDTH << "), 1.0 / float(" << VRAM_HEIGHT ss << "CONSTANT float2 RCP_VRAM_SIZE = float2(1.0 / float(" << VRAM_WIDTH << "), 1.0 / float(" << VRAM_HEIGHT
@ -2204,10 +2197,10 @@ std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader(
WriteBatchUniformBuffer(ss); WriteBatchUniformBuffer(ss);
DeclareTexture(ss, "samp0", 0); DeclareTexture(ss, "samp0", 0);
if (use_rov) if (sel.use_rov)
{ {
DeclareImage(ss, "rov_color", 0); DeclareImage(ss, "rov_color", 0);
if (use_rov_depth) if (sel.use_rov_depth)
DeclareImage(ss, "rov_depth", 1, true); DeclareImage(ss, "rov_depth", 1, true);
} }
@ -2369,51 +2362,52 @@ float4 SampleFromVRAM(TEXPAGE_VALUE texpage, DECLARE_UV_LIMITS(float2 coords, fl
#endif // TEXTURED #endif // TEXTURED
)"; )";
const u32 num_fragment_outputs = use_rov ? 0 : (use_dual_source ? 2 : 1); const u32 num_fragment_outputs = sel.use_rov ? 0 : (use_dual_source ? 2 : 1);
if (textured && page_texture) if (textured && page_texture)
{ {
if (texture_filtering != GPUTextureFilter::Nearest) if (sel.texture_filtering != GPUTextureFilter::Nearest)
WriteBatchTextureFilter(ss, texture_filtering); WriteBatchTextureFilter(ss, sel.texture_filtering);
if (uv_limits) if (sel.uv_limits)
{ {
DeclareFragmentEntryPoint(ss, 1, 1, {{"nointerpolation", "float4 v_uv_limits"}}, true, num_fragment_outputs, DeclareFragmentEntryPoint(ss, 1, 1, {{"nointerpolation", "float4 v_uv_limits"}}, true, num_fragment_outputs,
use_dual_source, write_mask_as_depth, msaa, per_sample_shading, false, use_dual_source, sel.write_mask_as_depth, sel.msaa, sel.per_sample_shading, false,
disable_color_perspective, shader_blending && !use_rov, use_rov); sel.disable_color_perspective, shader_blending && !sel.use_rov, sel.use_rov);
} }
else else
{ {
DeclareFragmentEntryPoint(ss, 1, 1, {}, true, num_fragment_outputs, use_dual_source, write_mask_as_depth, msaa, DeclareFragmentEntryPoint(ss, 1, 1, {}, true, num_fragment_outputs, use_dual_source, sel.write_mask_as_depth,
per_sample_shading, false, disable_color_perspective, shader_blending && !use_rov, sel.msaa, sel.per_sample_shading, false, sel.disable_color_perspective,
use_rov); shader_blending && !sel.use_rov, sel.use_rov);
} }
} }
else if (textured) else if (textured)
{ {
if (texture_filtering != GPUTextureFilter::Nearest) if (sel.texture_filtering != GPUTextureFilter::Nearest)
WriteBatchTextureFilter(ss, texture_filtering); WriteBatchTextureFilter(ss, sel.texture_filtering);
if (uv_limits) if (sel.uv_limits)
{ {
DeclareFragmentEntryPoint(ss, 1, 1, DeclareFragmentEntryPoint(ss, 1, 1,
{{"nointerpolation", palette ? "uint4 v_texpage" : "uint2 v_texpage"}, {{"nointerpolation", palette ? "uint4 v_texpage" : "uint2 v_texpage"},
{"nointerpolation", "float4 v_uv_limits"}}, {"nointerpolation", "float4 v_uv_limits"}},
true, num_fragment_outputs, use_dual_source, write_mask_as_depth, msaa, true, num_fragment_outputs, use_dual_source, sel.write_mask_as_depth, sel.msaa,
per_sample_shading, false, disable_color_perspective, shader_blending && !use_rov, sel.per_sample_shading, false, sel.disable_color_perspective,
use_rov); shader_blending && !sel.use_rov, sel.use_rov);
} }
else else
{ {
DeclareFragmentEntryPoint(ss, 1, 1, {{"nointerpolation", palette ? "uint4 v_texpage" : "uint2 v_texpage"}}, true, DeclareFragmentEntryPoint(ss, 1, 1, {{"nointerpolation", palette ? "uint4 v_texpage" : "uint2 v_texpage"}}, true,
num_fragment_outputs, use_dual_source, write_mask_as_depth, msaa, per_sample_shading, num_fragment_outputs, use_dual_source, sel.write_mask_as_depth, sel.msaa,
false, disable_color_perspective, shader_blending && !use_rov, use_rov); sel.per_sample_shading, false, sel.disable_color_perspective,
shader_blending && !sel.use_rov, sel.use_rov);
} }
} }
else else
{ {
DeclareFragmentEntryPoint(ss, 1, 0, {}, true, num_fragment_outputs, use_dual_source, write_mask_as_depth, msaa, DeclareFragmentEntryPoint(ss, 1, 0, {}, true, num_fragment_outputs, use_dual_source, sel.write_mask_as_depth,
per_sample_shading, false, disable_color_perspective, shader_blending && !use_rov, sel.msaa, sel.per_sample_shading, false, sel.disable_color_perspective,
use_rov); shader_blending && !sel.use_rov, sel.use_rov);
} }
ss << R"( ss << R"(

@ -9,23 +9,56 @@
class GPU_HW_ShaderGen : public ShaderGen class GPU_HW_ShaderGen : public ShaderGen
{ {
public:
struct BatchVertexShaderSelector
{
bool upscaled : 1;
bool msaa : 1;
bool per_sample_shading : 1;
bool textured : 1;
bool palette : 1;
bool page_texture : 1;
bool uv_limits : 1;
bool force_round_texcoords : 1;
bool pgxp_depth : 1;
bool disable_color_perspective : 1;
};
struct BatchFragmentShaderSelector
{
GPU_HW::BatchRenderMode render_mode;
GPUTransparencyMode transparency;
GPU_HW::BatchTextureMode texture_mode;
GPUTextureFilter texture_filtering;
bool is_blended_texture_filtering;
bool upscaled : 1;
bool msaa : 1;
bool per_sample_shading : 1;
bool uv_limits : 1;
bool force_round_texcoords : 1;
bool modulation_crop : 1;
bool true_color : 1;
bool dithering : 1;
bool scaled_dithering : 1;
bool disable_color_perspective : 1;
bool interlacing : 1;
bool scaled_interlacing : 1;
bool check_mask : 1;
bool write_mask_as_depth : 1;
bool use_rov : 1;
bool use_rov_depth : 1;
bool rov_depth_test : 1;
bool rov_depth_write : 1;
};
public: public:
GPU_HW_ShaderGen(RenderAPI render_api, bool supports_dual_source_blend, bool supports_framebuffer_fetch); GPU_HW_ShaderGen(RenderAPI render_api, bool supports_dual_source_blend, bool supports_framebuffer_fetch);
~GPU_HW_ShaderGen(); ~GPU_HW_ShaderGen();
std::string GenerateScreenVertexShader() const; std::string GenerateScreenVertexShader() const;
std::string GenerateBatchVertexShader(bool upscaled, bool msaa, bool per_sample_shading, bool textured, bool palette, std::string GenerateBatchVertexShader(const BatchVertexShaderSelector sel) const;
bool page_texture, bool uv_limits, bool force_round_texcoords, bool pgxp_depth, std::string GenerateBatchFragmentShader(const BatchFragmentShaderSelector sel) const;
bool disable_color_perspective) const;
std::string GenerateBatchFragmentShader(GPU_HW::BatchRenderMode render_mode, GPUTransparencyMode transparency,
GPU_HW::BatchTextureMode texture_mode, GPUTextureFilter texture_filtering,
bool is_blended_texture_filtering, bool upscaled, bool msaa,
bool per_sample_shading, bool uv_limits, bool force_round_texcoords,
bool modulation_crop, bool true_color, bool dithering, bool scaled_dithering,
bool disable_color_perspective, bool interlacing, bool scaled_interlacing,
bool check_mask, bool write_mask_as_depth, bool use_rov, bool use_rov_depth,
bool rov_depth_test, bool rov_depth_write) const;
std::string GenerateWireframeGeometryShader() const; std::string GenerateWireframeGeometryShader() const;
std::string GenerateWireframeFragmentShader() const; std::string GenerateWireframeFragmentShader() const;
std::string GenerateVRAMReadFragmentShader(u32 resolution_scale, u32 multisamples) const; std::string GenerateVRAMReadFragmentShader(u32 resolution_scale, u32 multisamples) const;

Loading…
Cancel
Save