diff options
Diffstat (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/PixelShaderGen.cpp | 87 |
1 files changed, 59 insertions, 28 deletions
diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 13d6bdd13e..e4227e8280 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,15 +404,11 @@ 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" : ""); - } + if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) + 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" @@ -420,24 +427,20 @@ 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" : ""); - } + 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 (ApiType == APIType::OpenGL) + if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) { - out.Write("layout(std140, binding = 3) buffer BBox {\n" + out.Write("SSBO_BINDING(0) buffer BBox {\n" "\tint4 bbox_data;\n" "};\n"); } @@ -488,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"); @@ -510,18 +513,33 @@ ShaderCode GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, APIType ApiType, warn_once = false; } - if (ApiType == APIType::OpenGL) + if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) { - out.Write("out vec4 ocol0;\n"); if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) - out.Write("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 + { + 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) + // 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("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)); @@ -557,7 +575,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); @@ -728,7 +746,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"); @@ -742,7 +760,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"); @@ -763,7 +781,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"); @@ -793,7 +811,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" @@ -1140,12 +1159,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[] = { @@ -1197,7 +1225,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) |
