diff options
| author | iwubcode <iwubcode@users.noreply.github.com> | 2025-03-15 17:29:13 -0500 |
|---|---|---|
| committer | iwubcode <iwubcode@users.noreply.github.com> | 2025-03-22 15:22:00 -0500 |
| commit | 8e253518e6f8b918dffe7361faf897c16eabc6d3 (patch) | |
| tree | 7d53662ef01ceb75cf8d8b556284733d110e93cf /Source/Core/VideoCommon/UberShaderPixel.cpp | |
| parent | 0afbeae70c94b72318035c300ef085d4753f7462 (diff) | |
VideoCommon: move to a 'process_fragment()' function to simplify custom shaders and provide a direct override of the tev stage logic
Diffstat (limited to 'Source/Core/VideoCommon/UberShaderPixel.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/UberShaderPixel.cpp | 406 |
1 files changed, 2 insertions, 404 deletions
diff --git a/Source/Core/VideoCommon/UberShaderPixel.cpp b/Source/Core/VideoCommon/UberShaderPixel.cpp index ef59414619..94ce2e2dbb 100644 --- a/Source/Core/VideoCommon/UberShaderPixel.cpp +++ b/Source/Core/VideoCommon/UberShaderPixel.cpp @@ -17,263 +17,6 @@ namespace UberShader { -namespace -{ -void WriteCustomShaderStructImpl(ShaderCode* out, u32 num_texgen, bool per_pixel_lighting) -{ - out->Write("\tCustomShaderData custom_data;\n"); - if (per_pixel_lighting) - { - out->Write("\tcustom_data.position = WorldPos;\n"); - out->Write("\tcustom_data.normal = Normal;\n"); - } - else - { - out->Write("\tcustom_data.position = float3(0, 0, 0);\n"); - out->Write("\tcustom_data.normal = float3(0, 0, 0);\n"); - } - - if (num_texgen == 0) [[unlikely]] - { - out->Write("\tcustom_data.texcoord[0] = float3(0, 0, 0);\n"); - } - else - { - for (u32 i = 0; i < num_texgen; ++i) - { - out->Write("\tif (tex{0}.z == 0.0)\n", i); - out->Write("\t{{\n"); - out->Write("\t\tcustom_data.texcoord[{0}] = tex{0};\n", i); - out->Write("\t}}\n"); - out->Write("\telse {{\n"); - out->Write("\t\tcustom_data.texcoord[{0}] = float3(tex{0}.xy / tex{0}.z, 0);\n", i); - out->Write("\t}}\n"); - } - } - - out->Write("\tcustom_data.texcoord_count = {};\n", num_texgen); - - for (u32 i = 0; i < 8; i++) - { - // Shader compilation complains if every index isn't initialized - out->Write("\tcustom_data.texmap_to_texcoord_index[{0}] = {0};\n", i); - } - - for (u32 i = 0; i < NUM_XF_COLOR_CHANNELS; i++) - { - out->Write("\tcustom_data.base_material[{}] = vec4(0, 0, 0, 1);\n", i); - out->Write("\tcustom_data.ambient_lighting[{}] = vec4(0, 0, 0, 1);\n", i); - - // Shader compilation errors can throw if not everything is initialized - for (u32 light_count_index = 0; light_count_index < 8; light_count_index++) - { - // Color - out->Write("\tcustom_data.lights_chan{}_color[{}].direction = float3(0, 0, 0);\n", i, - light_count_index); - out->Write("\tcustom_data.lights_chan{}_color[{}].position = float3(0, 0, 0);\n", i, - light_count_index); - out->Write("\tcustom_data.lights_chan{}_color[{}].color = float3(0, 0, 0);\n", i, - light_count_index); - out->Write("\tcustom_data.lights_chan{}_color[{}].cosatt = float4(0, 0, 0, 0);\n", i, - light_count_index); - out->Write("\tcustom_data.lights_chan{}_color[{}].distatt = float4(0, 0, 0, 0);\n", i, - light_count_index); - out->Write("\tcustom_data.lights_chan{}_color[{}].attenuation_type = 0;\n", i, - light_count_index); - - // Alpha - out->Write("\tcustom_data.lights_chan{}_alpha[{}].direction = float3(0, 0, 0);\n", i, - light_count_index); - out->Write("\tcustom_data.lights_chan{}_alpha[{}].position = float3(0, 0, 0);\n", i, - light_count_index); - out->Write("\tcustom_data.lights_chan{}_alpha[{}].color = float3(0, 0, 0);\n", i, - light_count_index); - out->Write("\tcustom_data.lights_chan{}_alpha[{}].cosatt = float4(0, 0, 0, 0);\n", i, - light_count_index); - out->Write("\tcustom_data.lights_chan{}_alpha[{}].distatt = float4(0, 0, 0, 0);\n", i, - light_count_index); - out->Write("\tcustom_data.lights_chan{}_alpha[{}].attenuation_type = 0;\n", i, - light_count_index); - } - - out->Write("\tcustom_data.light_chan{}_color_count = 0;\n", i); - out->Write("\tcustom_data.light_chan{}_alpha_count = 0;\n", i); - } - - if (num_texgen > 0) [[likely]] - { - out->Write("\n"); - out->Write("\tfor(uint stage = 0u; stage <= num_stages; stage++)\n"); - out->Write("\t{{\n"); - out->Write("\t\tStageState ss;\n"); - out->Write("\t\tss.order = bpmem_tevorder(stage>>1);\n"); - out->Write("\t\tif ((stage & 1u) == 1u)\n"); - out->Write("\t\t\tss.order = ss.order >> {};\n\n", - int(TwoTevStageOrders().enable_tex_odd.StartBit() - - TwoTevStageOrders().enable_tex_even.StartBit())); - out->Write("\t\tuint texmap = {};\n", - BitfieldExtract<&TwoTevStageOrders::texcoord_even>("ss.order")); - // Shader compilation is weird, shader arrays can't use indexing by variable - // to set values unless the variable is an index in a for loop. - // So instead we have to do this if check nonsense - for (u32 i = 0; i < 8; i++) - { - out->Write("\t\tif (texmap == {})\n", i); - out->Write("\t\t{{\n"); - out->Write("\t\t\tcustom_data.texmap_to_texcoord_index[{}] = selectTexCoordIndex(texmap);\n", - i); - out->Write("\t\t}}\n"); - } - out->Write("\t}}\n"); - } - - if (per_pixel_lighting) - { - out->Write("\tuint light_count = 0;\n"); - out->Write("\tfor (uint chan = 0u; chan < {}u; chan++)\n", NUM_XF_COLOR_CHANNELS); - out->Write("\t{{\n"); - out->Write("\t\tuint colorreg = xfmem_color(chan);\n"); - out->Write("\t\tuint alphareg = xfmem_alpha(chan);\n"); - for (const auto& color_type : std::array<std::string_view, 2>{"colorreg", "alphareg"}) - { - if (color_type == "colorreg") - { - out->Write("\t\tcustom_data.base_material[0] = " I_MATERIALS "[2u] / 255.0; \n"); - out->Write("\t\tif ({} != 0u)\n", BitfieldExtract<&LitChannel::enablelighting>(color_type)); - out->Write("\t\t\tcustom_data.base_material[0] = colors_0; \n"); - } - else - { - out->Write("custom_data.base_material[1].w = " I_MATERIALS "[3u].w / 255.0; \n"); - out->Write("\t\tif ({} != 0u)\n", BitfieldExtract<&LitChannel::enablelighting>(color_type)); - out->Write("\t\t\tcustom_data.base_material[1].w = colors_1.w; \n"); - } - out->Write("\t\tif ({} != 0u)\n", BitfieldExtract<&LitChannel::enablelighting>(color_type)); - out->Write("\t\t{{\n"); - out->Write("\t\t\tuint light_mask = {} | ({} << 4u);\n", - BitfieldExtract<&LitChannel::lightMask0_3>(color_type), - BitfieldExtract<&LitChannel::lightMask4_7>(color_type)); - out->Write("\t\t\tuint attnfunc = {};\n", BitfieldExtract<&LitChannel::attnfunc>(color_type)); - out->Write("\t\t\tfor (uint light_index = 0u; light_index < 8u; light_index++)\n"); - out->Write("\t\t\t{{\n"); - out->Write("\t\t\t\tif ((light_mask & (1u << light_index)) != 0u)\n"); - out->Write("\t\t\t\t{{\n"); - // Shader compilation is weird, shader arrays can't use indexing by variable - // to set values unless the variable is an index in a for loop. - // So instead we have to do this if check nonsense - for (u32 light_count_index = 0; light_count_index < 8; light_count_index++) - { - out->Write("\t\t\t\t\tif (light_index == {})\n", light_count_index); - out->Write("\t\t\t\t\t{{\n"); - if (color_type == "colorreg") - { - for (u32 channel_index = 0; channel_index < NUM_XF_COLOR_CHANNELS; channel_index++) - { - out->Write("\t\t\t\t\t\tif (chan == {})\n", channel_index); - out->Write("\t\t\t\t\t\t{{\n"); - out->Write("\t\t\t\t\t\t\tcustom_data.lights_chan{}_color[{}].direction = " I_LIGHTS - "[light_index].dir.xyz;\n", - channel_index, light_count_index); - out->Write("\t\t\t\t\t\t\tcustom_data.lights_chan{}_color[{}].position = " I_LIGHTS - "[light_index].pos.xyz;\n", - channel_index, light_count_index); - out->Write("\t\t\t\t\t\t\tcustom_data.lights_chan{}_color[{}].cosatt = " I_LIGHTS - "[light_index].cosatt;\n", - channel_index, light_count_index); - out->Write("\t\t\t\t\t\t\tcustom_data.lights_chan{}_color[{}].distatt = " I_LIGHTS - "[light_index].distatt;\n", - channel_index, light_count_index); - out->Write( - "\t\t\t\t\t\t\tcustom_data.lights_chan{}_color[{}].attenuation_type = attnfunc;\n", - channel_index, light_count_index); - out->Write("\t\t\t\t\t\t\tcustom_data.lights_chan{}_color[{}].color = " I_LIGHTS - "[light_index].color.rgb / float3(255.0, 255.0, 255.0);\n", - channel_index, light_count_index); - out->Write("\t\t\t\t\t\t\tcustom_data.light_chan{}_color_count += 1;\n", channel_index); - out->Write("\t\t\t\t\t\t}}\n"); - } - } - else - { - for (u32 channel_index = 0; channel_index < NUM_XF_COLOR_CHANNELS; channel_index++) - { - out->Write("\t\t\t\t\t\tif (chan == {})\n", channel_index); - out->Write("\t\t\t\t\t\t{{\n"); - out->Write("\t\t\t\t\t\t\tcustom_data.lights_chan{}_alpha[{}].direction = " I_LIGHTS - "[light_index].dir.xyz;\n", - channel_index, light_count_index); - out->Write("\t\t\t\t\t\t\tcustom_data.lights_chan{}_alpha[{}].position = " I_LIGHTS - "[light_index].pos.xyz;\n", - channel_index, light_count_index); - out->Write("\t\t\t\t\t\t\tcustom_data.lights_chan{}_alpha[{}].cosatt = " I_LIGHTS - "[light_index].cosatt;\n", - channel_index, light_count_index); - out->Write("\t\t\t\t\t\t\tcustom_data.lights_chan{}_alpha[{}].distatt = " I_LIGHTS - "[light_index].distatt;\n", - channel_index, light_count_index); - out->Write( - "\t\t\t\t\t\t\tcustom_data.lights_chan{}_alpha[{}].attenuation_type = attnfunc;\n", - channel_index, light_count_index); - out->Write("\t\t\t\t\t\t\tcustom_data.lights_chan{}_alpha[{}].color = float3(" I_LIGHTS - "[light_index].color.a) / float3(255.0, 255.0, 255.0);\n", - channel_index, light_count_index); - out->Write("\t\t\t\t\t\t\tcustom_data.light_chan{}_alpha_count += 1;\n", channel_index); - out->Write("\t\t\t\t\t\t}}\n"); - } - } - - out->Write("\t\t\t\t\t}}\n"); - } - out->Write("\t\t\t\t}}\n"); - out->Write("\t\t\t}}\n"); - out->Write("\t\t}}\n"); - } - out->Write("\t}}\n"); - } - - for (u32 i = 0; i < 16; i++) - { - // Shader compilation complains if every struct isn't initialized - - // Color Input - for (u32 j = 0; j < 4; j++) - { - out->Write("\tcustom_data.tev_stages[{}].input_color[{}].input_type = " - "CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_UNUSED;\n", - i, j); - out->Write("\tcustom_data.tev_stages[{}].input_color[{}].value = " - "float3(0, 0, 0);\n", - i, j); - } - - // Alpha Input - for (u32 j = 0; j < 4; j++) - { - out->Write("\tcustom_data.tev_stages[{}].input_alpha[{}].input_type = " - "CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_UNUSED;\n", - i, j); - out->Write("\tcustom_data.tev_stages[{}].input_alpha[{}].value = " - "float(0);\n", - i, j); - } - - // Texmap - out->Write("\tcustom_data.tev_stages[{}].texmap = 0u;\n", i); - - // Output - out->Write("\tcustom_data.tev_stages[{}].output_color = " - "float4(0, 0, 0, 0);\n", - i); - } - - // Actual data will be filled out in the tev stage code, just set the - // stage count for now - out->Write("\tcustom_data.tev_stage_count = num_stages;\n"); - - // Time - out->Write("\tcustom_data.time_ms = time_ms;\n"); -} -} // namespace PixelShaderUid GetPixelShaderUid() { PixelShaderUid out; @@ -313,8 +56,7 @@ void ClearUnusedPixelShaderUidBits(APIType api_type, const ShaderHostConfig& hos } ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, - const pixel_ubershader_uid_data* uid_data, - const CustomPixelShaderContents& custom_details) + const pixel_ubershader_uid_data* uid_data) { const bool per_pixel_lighting = host_config.per_pixel_lighting; const bool msaa = host_config.msaa; @@ -333,13 +75,7 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, out.Write("// {}\n", *uid_data); WriteBitfieldExtractHeader(out, api_type, host_config); - WritePixelShaderCommonHeader(out, api_type, host_config, bounding_box, custom_details); - WriteCustomShaderStructDef(&out, numTexgen); - for (std::size_t i = 0; i < custom_details.shaders.size(); i++) - { - const auto& shader_details = custom_details.shaders[i]; - out.Write(fmt::runtime(shader_details.custom_shader), i); - } + WritePixelShaderCommonHeader(out, api_type, host_config, bounding_box); if (per_pixel_lighting) WriteLightingFunction(out); @@ -769,25 +505,6 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, "return int3(0, 0, 0);", // ZERO }; - static constexpr Common::EnumMap<std::string_view, TevColorArg::Zero> tev_c_input_type{ - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_PREV;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_PREV;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_COLOR;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_COLOR;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_COLOR;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_COLOR;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_COLOR;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_COLOR;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_TEX;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_TEX;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_RAS;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_RAS;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_NUMERIC;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_NUMERIC;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_KONST;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_NUMERIC;", - }; - static constexpr Common::EnumMap<std::string_view, TevAlphaArg::Zero> tev_a_input_table{ "return s.Reg[0].a;", // APREV, "return s.Reg[1].a;", // A0, @@ -799,17 +516,6 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, "return 0;", // ZERO }; - static constexpr Common::EnumMap<std::string_view, TevAlphaArg::Zero> tev_a_input_type{ - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_PREV;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_COLOR;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_COLOR;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_COLOR;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_TEX;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_RAS;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_KONST;", - "return CUSTOM_SHADER_TEV_STAGE_INPUT_TYPE_NUMERIC;", - }; - static constexpr Common::EnumMap<std::string_view, TevOutput::Color2> tev_regs_lookup_table{ "return s.Reg[0];", "return s.Reg[1];", @@ -851,16 +557,6 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, out.Write("}}\n" "\n"); - out.Write("// Helper function for Custom Shader Input Type\n" - "uint getColorInputType(uint index) {{\n"); - WriteSwitch(out, api_type, "index", tev_c_input_type, 2, false); - out.Write("}}\n" - "\n" - "uint getAlphaInputType(uint index) {{\n"); - WriteSwitch(out, api_type, "index", tev_a_input_type, 2, false); - out.Write("}}\n" - "\n"); - // Since the fixed-point texture coodinate variables aren't global, we need to pass // them to the select function. This applies to all backends. if (numTexgen > 0) @@ -880,14 +576,6 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, out.Write(" uint num_stages = {};\n\n", BitfieldExtract<&GenMode::numtevstages>("bpmem_genmode")); - bool has_custom_shader_details = false; - if (std::any_of(custom_details.shaders.begin(), custom_details.shaders.end(), - [](const std::optional<CustomPixelShader>& ps) { return ps.has_value(); })) - { - WriteCustomShaderStructImpl(&out, numTexgen, per_pixel_lighting); - has_custom_shader_details = true; - } - if (use_framebuffer_fetch) { // Store off a copy of the initial framebuffer value. @@ -1239,78 +927,6 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, "\n" " // Write result to the correct input register of the next stage\n"); WriteSwitch(out, api_type, "alpha_dest", tev_a_set_table, 6, true); - if (has_custom_shader_details) - { - for (u32 stage_index = 0; stage_index < 16; stage_index++) - { - out.Write("\tif (stage == {}u) {{\n", stage_index); - // Color input - out.Write("\t\tcustom_data.tev_stages[{}].input_color[0].value = color_A / float3(255.0, " - "255.0, 255.0);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].input_color[0].input_type = " - "getColorInputType(color_a);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].input_color[1].value = color_B / float3(255.0, " - "255.0, 255.0);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].input_color[1].input_type = " - "getColorInputType(color_b);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].input_color[2].value = color_C / float3(255.0, " - "255.0, 255.0);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].input_color[2].input_type = " - "getColorInputType(color_c);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].input_color[3].value = color_D / float3(255.0, " - "255.0, 255.0);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].input_color[3].input_type = " - "getColorInputType(color_c);\n", - stage_index); - - // Alpha input - out.Write("\t\tcustom_data.tev_stages[{}].input_alpha[0].value = alpha_A / float(255.0);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].input_alpha[0].input_type = " - "getAlphaInputType(alpha_a);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].input_alpha[1].value = alpha_B / float(255.0);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].input_alpha[1].input_type = " - "getAlphaInputType(alpha_b);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].input_alpha[2].value = alpha_C / float(255.0);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].input_alpha[2].input_type = " - "getAlphaInputType(alpha_c);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].input_alpha[3].value = alpha_D / float(255.0);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].input_alpha[3].input_type = " - "getAlphaInputType(alpha_d);\n", - stage_index); - - if (numTexgen != 0) - { - // Texmap - out.Write("\t\tif (texture_enabled) {{\n"); - out.Write("\t\t\tuint sampler_num = {};\n", - BitfieldExtract<&TwoTevStageOrders::texmap_even>("ss.order")); - out.Write("\t\tcustom_data.tev_stages[{}].texmap = sampler_num;\n", stage_index); - out.Write("\t\t}}\n"); - } - - // Output - out.Write("\t\tcustom_data.tev_stages[{}].output_color.rgb = color / float3(255.0, 255.0, " - "255.0);\n", - stage_index); - out.Write("\t\tcustom_data.tev_stages[{}].output_color.a = alpha / float(255.0);\n", - stage_index); - out.Write("\t}}\n"); - } - } out.Write(" }}\n"); out.Write(" }} // Main TEV loop\n"); out.Write("\n"); @@ -1508,24 +1124,6 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, " }}\n" "\n"); - for (std::size_t i = 0; i < custom_details.shaders.size(); i++) - { - const auto& shader_details = custom_details.shaders[i]; - - if (!shader_details.custom_shader.empty()) - { - out.Write("\t{{\n"); - out.Write("\t\tcustom_data.final_color = float4(TevResult.r / 255.0, TevResult.g / 255.0, " - "TevResult.b / 255.0, TevResult.a / 255.0);\n"); - out.Write("\t\tCustomShaderOutput custom_output = {}_{}(custom_data);\n", - CUSTOM_PIXELSHADER_COLOR_FUNC, i); - out.Write( - "\t\tTevResult = int4(custom_output.main_rt.r * 255, custom_output.main_rt.g * 255, " - "custom_output.main_rt.b * 255, custom_output.main_rt.a * 255);\n"); - out.Write("\t}}\n\n"); - } - } - if (use_framebuffer_fetch) { static constexpr std::array<const char*, 16> logic_op_mode{ |
