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);
});
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++)
{
vssel.textured = (textured != 0);
for (u8 palette = 0; palette < 3; palette++)
{
if (palette && !textured)
@ -1235,17 +1243,18 @@ bool GPU_HW::CompilePipelines(Error* error)
if (palette == 2 && !needs_page_texture)
continue;
vssel.palette = (palette == 1);
vssel.page_texture = (palette == 2);
for (u8 sprite = 0; sprite < 2; sprite++)
{
if (sprite && (!textured || !m_allow_sprite_mode))
continue;
const bool uv_limits = ShouldClampUVs(sprite ? m_sprite_texture_filtering : m_texture_filtering);
const std::string vs = shadergen.GenerateBatchVertexShader(
upscaled, msaa, per_sample_shading, textured != 0, palette == 1, palette == 2, uv_limits,
!sprite && force_round_texcoords, m_pgxp_depth_buffer, disable_color_perspective);
if (!(batch_vertex_shaders[textured][palette][sprite] =
g_gpu_device->CreateShader(GPUShaderStage::Vertex, shadergen.GetLanguage(), vs, error)))
vssel.uv_limits = ShouldClampUVs(sprite ? m_sprite_texture_filtering : m_texture_filtering);
vssel.force_round_texcoords = !sprite && force_round_texcoords;
if (!(batch_vertex_shaders[textured][palette][sprite] = g_gpu_device->CreateShader(
GPUShaderStage::Vertex, shadergen.GetLanguage(), shadergen.GenerateBatchVertexShader(vssel), error)))
{
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++)
{
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++)
{
fssel.render_mode = static_cast<BatchRenderMode>(render_mode);
for (u8 transparency_mode = 0; transparency_mode < 5; transparency_mode++)
{
if (
@ -1290,6 +1310,12 @@ bool GPU_HW::CompilePipelines(Error* error)
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++)
{
if (!needs_page_texture && (texture_mode == static_cast<u8>(BatchTextureMode::PageTexture) ||
@ -1298,6 +1324,15 @@ bool GPU_HW::CompilePipelines(Error* error)
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++)
{
if (check_mask && render_mode != static_cast<u8>(BatchRenderMode::ShaderBlend))
@ -1312,41 +1347,30 @@ bool GPU_HW::CompilePipelines(Error* error)
continue;
}
fssel.check_mask = ConvertToBoolUnchecked(check_mask);
for (u8 dithering = 0; dithering < 2; dithering++)
{
// Never going to draw with dithering on in true color.
if (dithering && true_color)
continue;
fssel.dithering = ConvertToBoolUnchecked(dithering);
fssel.scaled_dithering = (fssel.dithering && scaled_dithering);
for (u8 interlacing = 0; interlacing < 2; interlacing++)
{
// Never going to draw with line skipping in force progressive.
if (interlacing && force_progressive_scan)
continue;
const bool sprite = (static_cast<BatchTextureMode>(texture_mode) >= BatchTextureMode::SpriteStart);
const bool uv_limits = ShouldClampUVs(sprite ? m_sprite_texture_filtering : m_texture_filtering);
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);
fssel.interlacing = ConvertToBoolUnchecked(interlacing);
fssel.scaled_interlacing = (fssel.interlacing && scaled_interlacing);
if (!(batch_fragment_shaders[depth_test][render_mode][transparency_mode][texture_mode][check_mask]
[dithering][interlacing] = g_gpu_device->CreateShader(
GPUShaderStage::Fragment, shadergen.GetLanguage(), fs, error)))
GPUShaderStage::Fragment, shadergen.GetLanguage(),
shadergen.GenerateBatchFragmentShader(fssel), error)))
{
return false;
}

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

@ -9,23 +9,56 @@
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:
GPU_HW_ShaderGen(RenderAPI render_api, bool supports_dual_source_blend, bool supports_framebuffer_fetch);
~GPU_HW_ShaderGen();
std::string GenerateScreenVertexShader() const;
std::string GenerateBatchVertexShader(bool upscaled, bool msaa, bool per_sample_shading, bool textured, bool palette,
bool page_texture, bool uv_limits, bool force_round_texcoords, bool pgxp_depth,
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 GenerateBatchVertexShader(const BatchVertexShaderSelector sel) const;
std::string GenerateBatchFragmentShader(const BatchFragmentShaderSelector sel) const;
std::string GenerateWireframeGeometryShader() const;
std::string GenerateWireframeFragmentShader() const;
std::string GenerateVRAMReadFragmentShader(u32 resolution_scale, u32 multisamples) const;

Loading…
Cancel
Save