From 479abde9f4c752aaf1ca113d18159a74bc8aebb1 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Sun, 11 Oct 2015 13:37:41 +1300 Subject: BPMemory: Convert a number of unions to BitFields --- Source/Core/VideoCommon/PixelShaderGen.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index fe4ef11bb0..d70806153e 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -824,7 +824,7 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i const char* tevIndAlphaSel[] = {"", "x", "y", "z"}; const char* tevIndAlphaMask[] = {"248", "224", "240", "248"}; // 0b11111000, 0b11100000, 0b11110000, 0b11111000 - out.Write("alphabump = iindtex%d.%s & %s;\n", tevind.bt, tevIndAlphaSel[tevind.bs], + out.Write("alphabump = iindtex%d.%s & %s;\n", tevind.bt.Value(), tevIndAlphaSel[tevind.bs], tevIndAlphaMask[tevind.fmt]); } else @@ -836,7 +836,8 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i { // format const char* tevIndFmtMask[] = {"255", "31", "15", "7"}; - out.Write("\tint3 iindtevcrd%d = iindtex%d & %s;\n", n, tevind.bt, tevIndFmtMask[tevind.fmt]); + out.Write("\tint3 iindtevcrd%d = iindtex%d & %s;\n", n, tevind.bt.Value(), + tevIndFmtMask[tevind.fmt]); // bias - TODO: Check if this needs to be this complicated.. const char* tevIndBiasField[] = {"", "x", "y", "xy", -- cgit v1.2.3 From 07591e7d5cf1a909a1691492337cda55025c0d20 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 20 Jul 2017 14:15:07 +1000 Subject: PixelShaderGen: Move header generation to seperate function --- Source/Core/VideoCommon/PixelShaderGen.cpp | 86 ++++++++++++++++-------------- 1 file changed, 46 insertions(+), 40 deletions(-) (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index d70806153e..fe0932ba70 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -333,33 +333,8 @@ PixelShaderUid GetPixelShaderUid() return out; } -static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, int n, - APIType ApiType, bool stereo); -static void WriteTevRegular(ShaderCode& out, const char* components, int bias, int op, int clamp, - int shift, bool alpha); -static void SampleTexture(ShaderCode& out, const char* texcoords, const char* texswap, int texmap, - bool stereo, APIType ApiType); -static void WriteAlphaTest(ShaderCode& out, const pixel_shader_uid_data* uid_data, APIType ApiType, - bool per_pixel_depth, bool use_dual_source); -static void WriteFog(ShaderCode& out, const pixel_shader_uid_data* uid_data); -static void WriteColor(ShaderCode& out, const pixel_shader_uid_data* uid_data, - bool use_dual_source); - -ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host_config, - const pixel_shader_uid_data* uid_data) +void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, bool bounding_box) { - ShaderCode out; - - const bool per_pixel_lighting = g_ActiveConfig.bEnablePixelLighting; - const bool msaa = host_config.msaa; - const bool ssaa = host_config.ssaa; - const bool stereo = host_config.stereo; - const u32 numStages = uid_data->genMode_numtevstages + 1; - - out.Write("//Pixel Shader for TEV stages\n"); - out.Write("//%i TEV stages, %i texgens, %i IND stages\n", numStages, uid_data->genMode_numtexgens, - uid_data->genMode_numindstages); - // dot product for integer vectors out.Write("int idot(int3 x, int3 y)\n" "{\n" @@ -422,20 +397,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host "\tfloat4 " I_EFBSCALE ";\n" "};\n"); - if (per_pixel_lighting) - { - out.Write("%s", s_lighting_struct); - - if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) - out.Write("UBO_BINDING(std140, 2) uniform VSBlock {\n"); - else - out.Write("cbuffer VSBlock : register(b1) {\n"); - - out.Write(s_shader_uniforms); - out.Write("};\n"); - } - - if (uid_data->bounding_box) + if (bounding_box) { if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) { @@ -448,6 +410,50 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host out.Write("globallycoherent RWBuffer bbox_data : register(u2);\n"); } } +} + +static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, int n, + APIType ApiType, bool stereo); +static void WriteTevRegular(ShaderCode& out, const char* components, int bias, int op, int clamp, + int shift, bool alpha); +static void SampleTexture(ShaderCode& out, const char* texcoords, const char* texswap, int texmap, + bool stereo, APIType ApiType); +static void WriteAlphaTest(ShaderCode& out, const pixel_shader_uid_data* uid_data, APIType ApiType, + bool per_pixel_depth, bool use_dual_source); +static void WriteFog(ShaderCode& out, const pixel_shader_uid_data* uid_data); +static void WriteColor(ShaderCode& out, const pixel_shader_uid_data* uid_data, + bool use_dual_source); + +ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host_config, + const pixel_shader_uid_data* uid_data) +{ + ShaderCode out; + + const bool per_pixel_lighting = g_ActiveConfig.bEnablePixelLighting; + const bool msaa = host_config.msaa; + const bool ssaa = host_config.ssaa; + const bool stereo = host_config.stereo; + const u32 numStages = uid_data->genMode_numtevstages + 1; + + out.Write("//Pixel Shader for TEV stages\n"); + out.Write("//%i TEV stages, %i texgens, %i IND stages\n", numStages, uid_data->genMode_numtexgens, + uid_data->genMode_numindstages); + + // Stuff that is shared between ubershaders and pixelgen. + WritePixelShaderCommonHeader(out, ApiType, uid_data->bounding_box); + + if (per_pixel_lighting) + { + out.Write("%s", s_lighting_struct); + + if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) + out.Write("UBO_BINDING(std140, 2) uniform VSBlock {\n"); + else + out.Write("cbuffer VSBlock : register(b2) {\n"); + + out.Write(s_shader_uniforms); + out.Write("};\n"); + } out.Write("struct VS_OUTPUT {\n"); GenerateVSOutputMembers(out, ApiType, uid_data->genMode_numtexgens, per_pixel_lighting, ""); -- cgit v1.2.3 From 7d78cf0f6fbca526e748590aeb6dfdc3c016669e Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 20 Jul 2017 15:25:24 +1000 Subject: ShaderGen: Implement pixel ubershaders --- Source/Core/VideoCommon/PixelShaderGen.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index fe0932ba70..036709aa1a 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -394,8 +394,26 @@ void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, bool boundin "\tint4 " I_FOGI ";\n" "\tfloat4 " I_FOGF "[2];\n" "\tfloat4 " I_ZSLOPE ";\n" - "\tfloat4 " I_EFBSCALE ";\n" - "};\n"); + "\tfloat2 " I_EFBSCALE ";\n" + "\tuint bpmem_genmode;\n" + "\tuint bpmem_alphaTest;\n" + "\tuint bpmem_fogParam3;\n" + "\tuint bpmem_fogRangeBase;\n" + "\tuint bpmem_dstalpha;\n" + "\tuint bpmem_ztex_op;\n" + "\tbool bpmem_early_ztest;\n" + "\tbool bpmem_rgba6_format;\n" + "\tbool bpmem_dither;\n" + "\tbool bpmem_bounding_box;\n" + "\tuint4 bpmem_pack1[16];\n" // .xy - combiners, .z - tevind + "\tuint4 bpmem_pack2[8];\n" // .x - tevorder, .y - tevksel + "\tint4 konstLookup[32];\n" + "};\n\n"); + out.Write("#define bpmem_combiners(i) (bpmem_pack1[(i)].xy)\n" + "#define bpmem_tevind(i) (bpmem_pack1[(i)].z)\n" + "#define bpmem_iref(i) (bpmem_pack1[(i)].w)\n" + "#define bpmem_tevorder(i) (bpmem_pack2[(i)].x)\n" + "#define bpmem_tevksel(i) (bpmem_pack2[(i)].y)\n\n"); if (bounding_box) { @@ -449,7 +467,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) out.Write("UBO_BINDING(std140, 2) uniform VSBlock {\n"); else - out.Write("cbuffer VSBlock : register(b2) {\n"); + out.Write("cbuffer VSBlock : register(b1) {\n"); out.Write(s_shader_uniforms); out.Write("};\n"); -- cgit v1.2.3 From 81b4ed2a81d7bada71a115efc7fb2347378fb975 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 20 Jul 2017 15:25:35 +1000 Subject: Vulkan: Uber shader support --- Source/Core/VideoCommon/PixelShaderGen.cpp | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 036709aa1a..61e8f92531 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -354,21 +354,10 @@ void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, bool boundin "int3 iround(float3 x) { return int3(round(x)); }\n" "int4 iround(float4 x) { return int4(round(x)); }\n\n"); - if (ApiType == APIType::OpenGL) + if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) { out.Write("SAMPLER_BINDING(0) uniform sampler2DArray samp[8];\n"); } - else if (ApiType == APIType::Vulkan) - { - out.Write("SAMPLER_BINDING(0) uniform sampler2DArray samp0;\n"); - out.Write("SAMPLER_BINDING(1) uniform sampler2DArray samp1;\n"); - out.Write("SAMPLER_BINDING(2) uniform sampler2DArray samp2;\n"); - out.Write("SAMPLER_BINDING(3) uniform sampler2DArray samp3;\n"); - out.Write("SAMPLER_BINDING(4) uniform sampler2DArray samp4;\n"); - out.Write("SAMPLER_BINDING(5) uniform sampler2DArray samp5;\n"); - out.Write("SAMPLER_BINDING(6) uniform sampler2DArray samp6;\n"); - out.Write("SAMPLER_BINDING(7) uniform sampler2DArray samp7;\n"); - } else // D3D { // Declare samplers @@ -1191,11 +1180,6 @@ static void SampleTexture(ShaderCode& out, const char* texcoords, const char* te "[%d].xy, %s))).%s;\n", texmap, texmap, texcoords, texmap, stereo ? "layer" : "0.0", texswap); } - else if (ApiType == APIType::Vulkan) - { - out.Write("iround(255.0 * texture(samp%d, float3(%s.xy * " I_TEXDIMS "[%d].xy, %s))).%s;\n", - texmap, texcoords, texmap, stereo ? "layer" : "0.0", texswap); - } else { out.Write("iround(255.0 * texture(samp[%d], float3(%s.xy * " I_TEXDIMS "[%d].xy, %s))).%s;\n", -- cgit v1.2.3 From e17efb1d8dcff32e7db915a53dc95df0bf329692 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 27 Jul 2017 01:01:25 +1000 Subject: ShaderGen: Use consistent variable names for texture coordinates --- Source/Core/VideoCommon/PixelShaderGen.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 61e8f92531..43dba06263 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -562,7 +562,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host // Let's set up attributes for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i) { - out.Write("%s in float3 uv%d;\n", GetInterpolationQualifier(msaa, ssaa), i); + out.Write("%s in float3 tex%d;\n", GetInterpolationQualifier(msaa, ssaa), i); } out.Write("%s in float4 clipPos;\n", GetInterpolationQualifier(msaa, ssaa)); if (per_pixel_lighting) @@ -573,13 +573,6 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host } out.Write("void main()\n{\n"); - - if (host_config.backend_geometry_shaders || ApiType == APIType::Vulkan) - { - for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i) - out.Write("\tfloat3 uv%d = tex%d;\n", i, i); - } - out.Write("\tfloat4 rawpos = gl_FragCoord;\n"); } else // D3D @@ -595,7 +588,8 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host // compute window position if needed because binding semantic WPOS is not widely supported for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i) - out.Write(",\n in %s float3 uv%d : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa), i, i); + out.Write(",\n in %s float3 tex%d : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa), i, + i); out.Write(",\n in %s float4 clipPos : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa), uid_data->genMode_numtexgens); if (per_pixel_lighting) @@ -658,7 +652,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i) { out.Write("\tint2 fixpoint_uv%d = int2(", i); - out.Write("(uv%d.z == 0.0 ? uv%d.xy : uv%d.xy / uv%d.z)", i, i, i, i); + out.Write("(tex%d.z == 0.0 ? tex%d.xy : tex%d.xy / tex%d.z)", i, i, i, i); out.Write(" * " I_TEXDIMS "[%d].zw);\n", i); // TODO: S24 overflows here? } -- cgit v1.2.3 From e968c191ffc7bf2899e8f56f39f988c36b54034c Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 27 Jul 2017 20:52:20 +1000 Subject: Ubershaders: Support per-pixel lighting --- Source/Core/VideoCommon/PixelShaderGen.cpp | 40 ++++++++++++++++-------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 43dba06263..b385776f96 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -333,7 +333,8 @@ PixelShaderUid GetPixelShaderUid() return out; } -void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, bool bounding_box) +void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, u32 num_texgens, + bool per_pixel_lighting, bool bounding_box) { // dot product for integer vectors out.Write("int idot(int3 x, int3 y)\n" @@ -404,6 +405,19 @@ void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, bool boundin "#define bpmem_tevorder(i) (bpmem_pack2[(i)].x)\n" "#define bpmem_tevksel(i) (bpmem_pack2[(i)].y)\n\n"); + if (per_pixel_lighting) + { + out.Write("%s", s_lighting_struct); + + if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) + out.Write("UBO_BINDING(std140, 2) uniform VSBlock {\n"); + else + out.Write("cbuffer VSBlock : register(b1) {\n"); + + out.Write(s_shader_uniforms); + out.Write("};\n"); + } + if (bounding_box) { if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) @@ -417,6 +431,10 @@ void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, bool boundin out.Write("globallycoherent RWBuffer bbox_data : register(u2);\n"); } } + + out.Write("struct VS_OUTPUT {\n"); + GenerateVSOutputMembers(out, ApiType, num_texgens, per_pixel_lighting, ""); + out.Write("};\n"); } static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, int n, @@ -447,24 +465,8 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host uid_data->genMode_numindstages); // Stuff that is shared between ubershaders and pixelgen. - WritePixelShaderCommonHeader(out, ApiType, uid_data->bounding_box); - - if (per_pixel_lighting) - { - out.Write("%s", s_lighting_struct); - - if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) - out.Write("UBO_BINDING(std140, 2) uniform VSBlock {\n"); - else - out.Write("cbuffer VSBlock : register(b1) {\n"); - - out.Write(s_shader_uniforms); - out.Write("};\n"); - } - - out.Write("struct VS_OUTPUT {\n"); - GenerateVSOutputMembers(out, ApiType, uid_data->genMode_numtexgens, per_pixel_lighting, ""); - out.Write("};\n"); + WritePixelShaderCommonHeader(out, ApiType, uid_data->genMode_numtexgens, per_pixel_lighting, + uid_data->bounding_box); if (uid_data->forced_early_z) { -- cgit v1.2.3 From d54ca2a16aa286fbdd68d65714c08c3a7b0a1f47 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Fri, 28 Jul 2017 21:56:55 +1000 Subject: PixelShaderGen: Don't include host early z support in UID Disable it at shader generation time instead. This way the UIDs are sharable. --- Source/Core/VideoCommon/PixelShaderGen.cpp | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index b385776f96..308807e7c8 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -179,7 +179,7 @@ PixelShaderUid GetPixelShaderUid() u32 numStages = uid_data->genMode_numtevstages + 1; const bool forced_early_z = - g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.UseEarlyDepthTest() && + bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED) // We can't allow early_ztest for zfreeze because depth is overridden per-pixel. // This means it's impossible for zcomploc to be emulated on a zfrozen polygon. @@ -192,18 +192,6 @@ PixelShaderUid GetPixelShaderUid() uid_data->per_pixel_depth = per_pixel_depth; uid_data->forced_early_z = forced_early_z; - if (!uid_data->forced_early_z && bpmem.UseEarlyDepthTest() && - (!g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED)) - { - static bool warn_once = true; - if (warn_once) - WARN_LOG(VIDEO, "Early z test enabled but not possible to emulate with current " - "configuration. Make sure to enable fast depth calculations. If this message " - "still shows up your hardware isn't able to emulate the feature properly (a " - "GPU with D3D 11.0 / OGL 4.2 support is required)."); - warn_once = false; - } - if (g_ActiveConfig.bEnablePixelLighting) { // The lighting shader only needs the two color bits of the 23bit component bit array. @@ -468,7 +456,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host WritePixelShaderCommonHeader(out, ApiType, uid_data->genMode_numtexgens, per_pixel_lighting, uid_data->bounding_box); - if (uid_data->forced_early_z) + if (uid_data->forced_early_z && g_ActiveConfig.backend_info.bSupportsEarlyZ) { // Zcomploc (aka early_ztest) is a way to control whether depth test is done before // or after texturing and alpha test. PC graphics APIs used to provide no way to emulate -- cgit v1.2.3