From d9c034e8ccaad6db870df765e01d5963af84c9c5 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 13 Aug 2016 00:40:18 +1000 Subject: ShaderGen: Specify attribute/output locations/bindings explicitly This also shifts the SSBO index from index 3 to index 0. --- Source/Core/VideoCommon/PixelShaderGen.cpp | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 13d6bdd13e..65722fb7d4 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -394,14 +394,10 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, out.Write("\n"); if (ApiType == APIType::OpenGL) - { - out.Write("layout(std140%s) uniform PSBlock {\n", - g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 1" : ""); - } + out.Write("UBO_BINDING(std140, 1) uniform PSBlock {\n"); else - { out.Write("cbuffer PSBlock : register(b0) {\n"); - } + out.Write("\tint4 " I_COLORS "[4];\n" "\tint4 " I_KCOLORS "[4];\n" "\tint4 " I_ALPHA ";\n" @@ -421,14 +417,10 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, out.Write("%s", s_lighting_struct); if (ApiType == APIType::OpenGL) - { - out.Write("layout(std140%s) uniform VSBlock {\n", - g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 2" : ""); - } + 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"); } @@ -437,7 +429,7 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, { if (ApiType == APIType::OpenGL) { - out.Write("layout(std140, binding = 3) buffer BBox {\n" + out.Write("SSBO_BINDING(0) buffer BBox {\n" "\tint4 bbox_data;\n" "};\n"); } @@ -512,16 +504,22 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, if (ApiType == APIType::OpenGL) { - out.Write("out vec4 ocol0;\n"); if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) - out.Write("out vec4 ocol1;\n"); + { + out.Write("FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 0) out vec4 ocol0;\n"); + out.Write("FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 1) out vec4 ocol1;\n"); + } + else + { + out.Write("FRAGMENT_OUTPUT_LOCATION(0) out vec4 ocol0;\n"); + } if (uid_data->per_pixel_depth) out.Write("#define depth gl_FragDepth\n"); if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) { - out.Write("in VertexData {\n"); + out.Write("VARYING_LOCATION(0) in VertexData {\n"); GenerateVSOutputMembers( out, ApiType, uid_data->genMode_numtexgens, uid_data->per_pixel_lighting, GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa, true, true)); -- cgit v1.2.3 From a71381e80a1e60b48b815f3e6a1a6290a918b596 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 13 Aug 2016 00:55:00 +1000 Subject: VideoCommon: Add APIType entry for Vulkan --- Source/Core/VideoCommon/PixelShaderGen.cpp | 49 ++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 12 deletions(-) (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 65722fb7d4..4038d9329c 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -384,6 +384,17 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, { 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 @@ -393,7 +404,7 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, } out.Write("\n"); - if (ApiType == APIType::OpenGL) + if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) out.Write("UBO_BINDING(std140, 1) uniform PSBlock {\n"); else out.Write("cbuffer PSBlock : register(b0) {\n"); @@ -416,7 +427,7 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, { out.Write("%s", s_lighting_struct); - if (ApiType == APIType::OpenGL) + if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) out.Write("UBO_BINDING(std140, 2) uniform VSBlock {\n"); else out.Write("cbuffer VSBlock : register(b1) {\n"); @@ -427,7 +438,7 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, if (uid_data->bounding_box) { - if (ApiType == APIType::OpenGL) + if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) { out.Write("SSBO_BINDING(0) buffer BBox {\n" "\tint4 bbox_data;\n" @@ -480,7 +491,7 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, // ARB_image_load_store extension yet. // D3D11 also has a way to force the driver to enable early-z, so we're fine here. - if (ApiType == APIType::OpenGL) + if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) { // This is a #define which signals whatever early-z method the driver supports. out.Write("FORCE_EARLY_Z; \n"); @@ -502,7 +513,7 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, warn_once = false; } - if (ApiType == APIType::OpenGL) + if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) { if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) { @@ -517,7 +528,8 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, if (uid_data->per_pixel_depth) out.Write("#define depth gl_FragDepth\n"); - if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) + // We need to always use output blocks for Vulkan, but geometry shaders are also optional. + if (g_ActiveConfig.backend_info.bSupportsGeometryShaders || ApiType == APIType::Vulkan) { out.Write("VARYING_LOCATION(0) in VertexData {\n"); GenerateVSOutputMembers( @@ -555,7 +567,7 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, out.Write("void main()\n{\n"); - if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) + if (g_ActiveConfig.backend_info.bSupportsGeometryShaders || ApiType == APIType::Vulkan) { for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i) out.Write("\tfloat3 uv%d = tex%d;\n", i, i); @@ -726,7 +738,7 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, } else { - if (ApiType == APIType::D3D) + if (ApiType == APIType::D3D || ApiType == APIType::Vulkan) out.Write("\tint zCoord = int((1.0 - rawpos.z) * 16777216.0);\n"); else out.Write("\tint zCoord = int(rawpos.z * 16777216.0);\n"); @@ -740,7 +752,7 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, // Note: z-textures are not written to depth buffer if early depth test is used if (uid_data->per_pixel_depth && uid_data->early_ztest) { - if (ApiType == APIType::D3D) + if (ApiType == APIType::D3D || ApiType == APIType::Vulkan) out.Write("\tdepth = 1.0 - float(zCoord) / 16777216.0;\n"); else out.Write("\tdepth = float(zCoord) / 16777216.0;\n"); @@ -761,7 +773,7 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, if (uid_data->per_pixel_depth && uid_data->late_ztest) { - if (ApiType == APIType::D3D) + if (ApiType == APIType::D3D || ApiType == APIType::Vulkan) out.Write("\tdepth = 1.0 - float(zCoord) / 16777216.0;\n"); else out.Write("\tdepth = float(zCoord) / 16777216.0;\n"); @@ -791,7 +803,8 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, if (uid_data->bounding_box) { - const char* atomic_op = ApiType == APIType::OpenGL ? "atomic" : "Interlocked"; + const char* atomic_op = + (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) ? "atomic" : "Interlocked"; out.Write("\tif(bbox_data[0] > int(rawpos.x)) %sMin(bbox_data[0], int(rawpos.x));\n" "\tif(bbox_data[1] < int(rawpos.x)) %sMax(bbox_data[1], int(rawpos.x));\n" "\tif(bbox_data[2] > int(rawpos.y)) %sMin(bbox_data[2], int(rawpos.y));\n" @@ -1138,12 +1151,21 @@ static void SampleTexture(ShaderCode& out, const char* texcoords, const char* te out.SetConstantsUsed(C_TEXDIMS + texmap, C_TEXDIMS + texmap); if (ApiType == APIType::D3D) + { out.Write("iround(255.0 * Tex[%d].Sample(samp[%d], float3(%s.xy * " I_TEXDIMS "[%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", texmap, texcoords, texmap, stereo ? "layer" : "0.0", texswap); + } } static const char* tevAlphaFuncsTable[] = { @@ -1195,7 +1217,10 @@ static void WriteAlphaTest(ShaderCode& out, const pixel_shader_uid_data* uid_dat if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) out.Write("\t\tocol1 = float4(0.0, 0.0, 0.0, 0.0);\n"); if (per_pixel_depth) - out.Write("\t\tdepth = %s;\n", (ApiType == APIType::D3D) ? "0.0" : "1.0"); + { + out.Write("\t\tdepth = %s;\n", + (ApiType == APIType::D3D || ApiType == APIType::Vulkan) ? "0.0" : "1.0"); + } // ZCOMPLOC HACK: if (!uid_data->alpha_test_use_zcomploc_hack) -- cgit v1.2.3 From bac8c2d44147395e31c4d5a2247be1b449139272 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 24 Sep 2016 23:13:17 +1000 Subject: Vulkan: Work around indexed fragment output bug on AMD drivers --- Source/Core/VideoCommon/PixelShaderGen.cpp | 12 ++++++++++-- 1 file changed, 10 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 4038d9329c..e4227e8280 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -517,8 +517,16 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, { if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) { - out.Write("FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 0) out vec4 ocol0;\n"); - out.Write("FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 1) out vec4 ocol1;\n"); + if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_FRAGMENT_SHADER_INDEX_DECORATION)) + { + out.Write("FRAGMENT_OUTPUT_LOCATION(0) out vec4 ocol0;\n"); + out.Write("FRAGMENT_OUTPUT_LOCATION(1) out vec4 ocol1;\n"); + } + else + { + out.Write("FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 0) out vec4 ocol0;\n"); + out.Write("FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 1) out vec4 ocol1;\n"); + } } else { -- cgit v1.2.3