diff --git a/GPU/Common/ShaderCommon.h b/GPU/Common/ShaderCommon.h index c2e77563ad..456ff0f392 100644 --- a/GPU/Common/ShaderCommon.h +++ b/GPU/Common/ShaderCommon.h @@ -30,6 +30,9 @@ enum ShaderLanguage { GLSL_VULKAN, HLSL_D3D9, HLSL_D3D11, + + HLSL_D3D9_TEST, + HLSL_D3D11_TEST, }; inline bool ShaderLanguageIsOpenGL(ShaderLanguage lang) { diff --git a/GPU/Directx9/VertexShaderGeneratorHLSL.cpp b/GPU/Directx9/VertexShaderGeneratorHLSL.cpp index e0a4b57887..5e301cb1fa 100644 --- a/GPU/Directx9/VertexShaderGeneratorHLSL.cpp +++ b/GPU/Directx9/VertexShaderGeneratorHLSL.cpp @@ -43,6 +43,8 @@ static const char * const boneWeightAttrDecl[9] = { "vec4 a_w1:TEXCOORD1;\n vec4 a_w2:TEXCOORD2;\n", }; +extern const char *hlsl_preamble_vs; + bool GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage lang, std::string *errorString) { char *p = buffer; @@ -101,12 +103,7 @@ bool GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage } // Output some compatibility defines - WRITE(p, "#define vec2 float2\n"); - WRITE(p, "#define vec3 float3\n"); - WRITE(p, "#define vec4 float4\n"); - WRITE(p, "#define mat4 float4x4\n"); - WRITE(p, "#define mat3x4 float4x3\n"); // note how the conventions are backwards - WRITE(p, "#define splat3(x) vec3(x, x, x)\n"); + WRITE(p, "%s", hlsl_preamble_vs); if (lang == HLSL_D3D9) { WRITE(p, "#pragma warning( disable : 3571 )\n"); @@ -399,9 +396,9 @@ bool GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage WRITE(p, " Tess tess;\n"); WRITE(p, " tessellate(In, tess);\n"); - WRITE(p, " vec3 worldpos = mul(vec4(tess.pos.xyz, 1.0), u_world);\n"); + WRITE(p, " vec3 worldpos = mul(vec4(tess.pos.xyz, 1.0), u_world).xyz;\n"); if (hasNormalTess) - WRITE(p, " vec3 worldnormal = normalize(mul(vec4(%stess.nrm, 0.0), u_world));\n", flipNormalTess ? "-" : ""); + WRITE(p, " vec3 worldnormal = normalize(mul(vec4(%stess.nrm, 0.0), u_world)).xyz;\n", flipNormalTess ? "-" : ""); else WRITE(p, " vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n"); } else { diff --git a/GPU/Directx9/VertexShaderGeneratorHLSL.h b/GPU/Directx9/VertexShaderGeneratorHLSL.h index 08adab846c..90900328d5 100644 --- a/GPU/Directx9/VertexShaderGeneratorHLSL.h +++ b/GPU/Directx9/VertexShaderGeneratorHLSL.h @@ -18,40 +18,8 @@ #pragma once #include + #include "GPU/Common/ShaderID.h" +#include "GPU/GLES/VertexShaderGeneratorGLES.h" bool GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage lang, std::string *errorString); - -enum { - CONST_VS_PROJ = 0, - CONST_VS_PROJ_THROUGH = 4, - CONST_VS_VIEW = 8, - CONST_VS_WORLD = 11, - CONST_VS_TEXMTX = 14, - CONST_VS_UVSCALEOFFSET = 17, - CONST_VS_FOGCOEF = 18, - CONST_VS_AMBIENT = 19, - CONST_VS_MATAMBIENTALPHA = 20, - CONST_VS_MATDIFFUSE = 21, - CONST_VS_MATSPECULAR = 22, - CONST_VS_MATEMISSIVE = 23, - CONST_VS_LIGHTPOS = 24, - CONST_VS_LIGHTDIR = 28, - CONST_VS_LIGHTATT = 32, - CONST_VS_LIGHTANGLE_SPOTCOEF = 36, - CONST_VS_LIGHTDIFFUSE = 40, - CONST_VS_LIGHTSPECULAR = 44, - CONST_VS_LIGHTAMBIENT = 48, - CONST_VS_DEPTHRANGE = 52, - CONST_VS_BONE0 = 53, - CONST_VS_BONE1 = 56, - CONST_VS_BONE2 = 59, - CONST_VS_BONE3 = 62, - CONST_VS_BONE4 = 65, - CONST_VS_BONE5 = 68, - CONST_VS_BONE6 = 71, - CONST_VS_BONE7 = 74, - CONST_VS_BONE8 = 77, - CONST_VS_CULLRANGEMIN = 80, - CONST_VS_CULLRANGEMAX = 81, -}; diff --git a/GPU/GLES/VertexShaderGeneratorGLES.cpp b/GPU/GLES/VertexShaderGeneratorGLES.cpp index e412f50232..065a1e5647 100644 --- a/GPU/GLES/VertexShaderGeneratorGLES.cpp +++ b/GPU/GLES/VertexShaderGeneratorGLES.cpp @@ -103,7 +103,19 @@ const char *vulkan_glsl_preamble_vs = "#version 450\n" "#extension GL_ARB_separate_shader_objects : enable\n" "#extension GL_ARB_shading_language_420pack : enable\n" -"#define splat3(x) vec3(x)\n\n"; +"#define mul(x, y) x * y\n" +"#define splat3(x) vec3(x)\n" +"#define lowp\n" +"#define mediump\n" +"#define highp\n\n"; + +const char *hlsl_preamble_vs = +"#define vec2 float2\n" +"#define vec3 float3\n" +"#define vec4 float4\n" +"#define mat4 float4x4\n" +"#define mat3x4 float4x3\n" // note how the conventions are backwards +"#define splat3(x) vec3(x, x, x)\n"; bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const ShaderLanguageDesc &compat, uint32_t *attrMask, uint64_t *uniformMask, std::string *errorString) { *attrMask = 0; @@ -115,7 +127,9 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const ShaderLan char *p = buffer; if (compat.shaderLanguage == GLSL_VULKAN) { WRITE(p, "%s", vulkan_glsl_preamble_vs); - } else { + } else if (compat.shaderLanguage == HLSL_D3D11 || compat.shaderLanguage == HLSL_D3D9) { + WRITE(p, "%s", hlsl_preamble_vs); + } else if (ShaderLanguageIsOpenGL(compat.shaderLanguage)) { if (compat.gles) { // PowerVR needs highp to do the fog in MHU correctly. // Others don't, and some can't handle highp in the fragment shader. @@ -123,19 +137,18 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const ShaderLan highpTexcoord = highpFog; } WRITE(p, "#version %d%s\n", compat.glslVersionNumber, compat.gles && compat.glslES30 ? " es" : ""); + if (gl_extensions.EXT_gpu_shader4) { + WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n"); + } + if (compat.gles) { + WRITE(p, "precision highp float;\n"); + } else { + WRITE(p, "#define lowp\n"); + WRITE(p, "#define mediump\n"); + WRITE(p, "#define highp\n"); + } WRITE(p, "#define splat3(x) vec3(x)\n"); - } - - if (ShaderLanguageIsOpenGL(compat.shaderLanguage) && gl_extensions.EXT_gpu_shader4) { - WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n"); - } - - if (compat.gles) { - WRITE(p, "precision highp float;\n"); - } else if (compat.shaderLanguage != GLSL_VULKAN) { - WRITE(p, "#define lowp\n"); - WRITE(p, "#define mediump\n"); - WRITE(p, "#define highp\n"); + WRITE(p, "#define mul(x, y) x * y\n"); } bool isModeThrough = id.Bit(VS_BIT_IS_THROUGH); @@ -175,15 +188,6 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const ShaderLan bool hasNormalTess = id.Bit(VS_BIT_HAS_NORMAL_TESS); bool flipNormalTess = id.Bit(VS_BIT_NORM_REVERSE_TESS); - if (compat.shaderLanguage == GLSL_VULKAN) { - WRITE(p, "\n"); - WRITE(p, "layout (std140, set = 0, binding = 3) uniform baseVars {\n%s};\n", ub_baseStr); - if (enableLighting || doShadeMapping) - WRITE(p, "layout (std140, set = 0, binding = 4) uniform lightVars {\n%s};\n", ub_vs_lightsStr); - if (enableBones) - WRITE(p, "layout (std140, set = 0, binding = 5) uniform boneVars {\n%s};\n", ub_vs_bonesStr); - } - const char *shading = ""; if (compat.glslES30 || compat.shaderLanguage == GLSL_VULKAN) shading = doFlatShading ? "flat " : ""; @@ -205,6 +209,13 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const ShaderLan bool texcoordInVec3 = false; if (compat.shaderLanguage == GLSL_VULKAN) { + WRITE(p, "\n"); + WRITE(p, "layout (std140, set = 0, binding = 3) uniform baseVars {\n%s};\n", ub_baseStr); + if (enableLighting || doShadeMapping) + WRITE(p, "layout (std140, set = 0, binding = 4) uniform lightVars {\n%s};\n", ub_vs_lightsStr); + if (enableBones) + WRITE(p, "layout (std140, set = 0, binding = 5) uniform boneVars {\n%s};\n", ub_vs_bonesStr); + if (enableBones) { numBoneWeights = 1 + id.Bits(VS_BIT_BONES, 3); WRITE(p, "%s", boneWeightDecl[numBoneWeights]); @@ -245,6 +256,146 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const ShaderLan // See the fragment shader generator WRITE(p, "layout (location = 3) out float v_fogdepth;\n"); } + } else if (compat.shaderLanguage == HLSL_D3D11 || compat.shaderLanguage == HLSL_D3D9) { + // Note: These two share some code after this hellishly large if/else. + if (compat.shaderLanguage == HLSL_D3D11) { + WRITE(p, "cbuffer base : register(b0) {\n%s};\n", cb_baseStr); + WRITE(p, "cbuffer lights: register(b1) {\n%s};\n", cb_vs_lightsStr); + WRITE(p, "cbuffer bones : register(b2) {\n%s};\n", cb_vs_bonesStr); + } else { + WRITE(p, "#pragma warning( disable : 3571 )\n"); + if (isModeThrough) { + WRITE(p, "float4x4 u_proj_through : register(c%i);\n", CONST_VS_PROJ_THROUGH); + } else { + WRITE(p, "float4x4 u_proj : register(c%i);\n", CONST_VS_PROJ); + // Add all the uniforms we'll need to transform properly. + } + + if (enableFog) { + WRITE(p, "vec2 u_fogcoef : register(c%i);\n", CONST_VS_FOGCOEF); + } + if (useHWTransform || !hasColor) + WRITE(p, "vec4 u_matambientalpha : register(c%i);\n", CONST_VS_MATAMBIENTALPHA); // matambient + matalpha + + if (useHWTransform) { + // When transforming by hardware, we need a great deal more uniforms... + WRITE(p, "mat3x4 u_world : register(c%i);\n", CONST_VS_WORLD); + WRITE(p, "mat3x4 u_view : register(c%i);\n", CONST_VS_VIEW); + if (doTextureTransform) + WRITE(p, "mat3x4 u_texmtx : register(c%i);\n", CONST_VS_TEXMTX); + if (enableBones) { +#ifdef USE_BONE_ARRAY + WRITE(p, "mat3x4 u_bone[%i] : register(c%i);\n", numBones, CONST_VS_BONE0); +#else + for (int i = 0; i < numBoneWeights; i++) { + WRITE(p, "mat3x4 u_bone%i : register(c%i);\n", i, CONST_VS_BONE0 + i * 3); + } +#endif + } + if (doTexture) { + WRITE(p, "vec4 u_uvscaleoffset : register(c%i);\n", CONST_VS_UVSCALEOFFSET); + } + for (int i = 0; i < 4; i++) { + if (doLight[i] != LIGHT_OFF) { + // This is needed for shade mapping + WRITE(p, "vec3 u_lightpos%i : register(c%i);\n", i, CONST_VS_LIGHTPOS + i); + } + if (doLight[i] == LIGHT_FULL) { + GELightType type = static_cast(id.Bits(VS_BIT_LIGHT0_TYPE + 4 * i, 2)); + GELightComputation comp = static_cast(id.Bits(VS_BIT_LIGHT0_COMP + 4 * i, 2)); + + if (type != GE_LIGHTTYPE_DIRECTIONAL) + WRITE(p, "vec3 u_lightatt%i : register(c%i);\n", i, CONST_VS_LIGHTATT + i); + + if (type == GE_LIGHTTYPE_SPOT || type == GE_LIGHTTYPE_UNKNOWN) { + WRITE(p, "vec3 u_lightdir%i : register(c%i);\n", i, CONST_VS_LIGHTDIR + i); + WRITE(p, "vec4 u_lightangle_spotCoef%i : register(c%i);\n", i, CONST_VS_LIGHTANGLE_SPOTCOEF + i); + } + WRITE(p, "vec3 u_lightambient%i : register(c%i);\n", i, CONST_VS_LIGHTAMBIENT + i); + WRITE(p, "vec3 u_lightdiffuse%i : register(c%i);\n", i, CONST_VS_LIGHTDIFFUSE + i); + + if (comp == GE_LIGHTCOMP_BOTH) { + WRITE(p, "vec3 u_lightspecular%i : register(c%i);\n", i, CONST_VS_LIGHTSPECULAR + i); + } + } + } + if (enableLighting) { + WRITE(p, "vec4 u_ambient : register(c%i);\n", CONST_VS_AMBIENT); + if ((matUpdate & 2) == 0 || !hasColor) + WRITE(p, "vec3 u_matdiffuse : register(c%i);\n", CONST_VS_MATDIFFUSE); + // if ((matUpdate & 4) == 0) + WRITE(p, "vec4 u_matspecular : register(c%i);\n", CONST_VS_MATSPECULAR); // Specular coef is contained in alpha + WRITE(p, "vec3 u_matemissive : register(c%i);\n", CONST_VS_MATEMISSIVE); + } + } + + if (!isModeThrough && gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) { + WRITE(p, "vec4 u_depthRange : register(c%i);\n", CONST_VS_DEPTHRANGE); + } + if (!isModeThrough) { + WRITE(p, "vec4 u_cullRangeMin : register(c%i);\n", CONST_VS_CULLRANGEMIN); + WRITE(p, "vec4 u_cullRangeMax : register(c%i);\n", CONST_VS_CULLRANGEMAX); + } + } + + // And the "varyings". + if (useHWTransform) { + WRITE(p, "struct VS_IN { \n"); + if ((doSpline || doBezier) && compat.shaderLanguage == HLSL_D3D11) { + WRITE(p, " uint instanceId : SV_InstanceID;\n"); + } + if (enableBones) { + WRITE(p, " %s", boneWeightAttrDecl[numBoneWeights]); + } + if (doTexture && hasTexcoord) { + WRITE(p, " vec2 texcoord : TEXCOORD0;\n"); + } + if (hasColor) { + WRITE(p, " vec4 color0 : COLOR0;\n"); + } + if (hasNormal) { + WRITE(p, " vec3 normal : NORMAL;\n"); + } + WRITE(p, " vec3 position : POSITION;\n"); + WRITE(p, "};\n"); + } else { + WRITE(p, "struct VS_IN {\n"); + WRITE(p, " vec4 position : POSITION;\n"); + if (doTexture && hasTexcoord) { + if (doTextureTransform && !isModeThrough) { + texcoordInVec3 = true; + WRITE(p, " vec3 texcoord : TEXCOORD0;\n"); + } else + WRITE(p, " vec2 texcoord : TEXCOORD0;\n"); + } + if (hasColor) { + WRITE(p, " vec4 color0 : COLOR0;\n"); + } + // only software transform supplies color1 as vertex data + if (lmode) { + WRITE(p, " vec4 color1 : COLOR1;\n"); + } + WRITE(p, "};\n"); + } + + WRITE(p, "struct VS_OUT {\n"); + if (doTexture) { + WRITE(p, " vec3 v_texcoord : TEXCOORD0;\n"); + } + const char *colorInterpolation = doFlatShading && compat.shaderLanguage == HLSL_D3D11 ? "nointerpolation " : ""; + WRITE(p, " %svec4 v_color0 : COLOR0;\n", colorInterpolation); + if (lmode) + WRITE(p, " vec3 v_color1 : COLOR1;\n"); + + if (enableFog) { + WRITE(p, " float v_fogdepth: TEXCOORD1;\n"); + } + if (compat.shaderLanguage == HLSL_D3D9) { + WRITE(p, " vec4 gl_Position : POSITION;\n"); + } else { + WRITE(p, " vec4 gl_Position : SV_Position;\n"); + } + WRITE(p, "};\n"); } else { if (enableBones) { numBoneWeights = 1 + id.Bits(VS_BIT_BONES, 3); @@ -542,7 +693,12 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const ShaderLan WRITE(p, "}\n"); } - WRITE(p, "void main() {\n"); + if (ShaderLanguageIsOpenGL(compat.shaderLanguage) || compat.shaderLanguage == GLSL_VULKAN) { + WRITE(p, "void main() {\n"); + } else if (compat.shaderLanguage == HLSL_D3D9 || compat.shaderLanguage == HLSL_D3D11) { + WRITE(p, "VS_OUT main(VS_IN In) {\n"); + WRITE(p, " VS_OUT Out;\n"); + } if (!useHWTransform) { // Simple pass-through of vertex data to fragment shader @@ -583,17 +739,17 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const ShaderLan WRITE(p, " Tess tess;\n"); WRITE(p, " tessellate(tess);\n"); - WRITE(p, " vec3 worldpos = (vec4(tess.pos.xyz, 1.0) * u_world).xyz;\n"); + WRITE(p, " vec3 worldpos = mul(vec4(tess.pos.xyz, 1.0), u_world).xyz;\n"); if (hasNormalTess) { - WRITE(p, " mediump vec3 worldnormal = normalize((vec4(%stess.nrm, 0.0) * u_world).xyz);\n", flipNormalTess ? "-" : ""); + WRITE(p, " mediump vec3 worldnormal = normalize(mul(vec4(%stess.nrm, 0.0), u_world).xyz);\n", flipNormalTess ? "-" : ""); } else { WRITE(p, " mediump vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n"); } } else { // No skinning, just standard T&L. - WRITE(p, " vec3 worldpos = (vec4(position.xyz, 1.0) * u_world).xyz;\n"); + WRITE(p, " vec3 worldpos = mul(vec4(position.xyz, 1.0), u_world).xyz;\n"); if (hasNormal) - WRITE(p, " mediump vec3 worldnormal = normalize((vec4(%snormal, 0.0) * u_world).xyz);\n", flipNormal ? "-" : ""); + WRITE(p, " mediump vec3 worldnormal = normalize(mul(vec4(%snormal, 0.0), u_world).xyz);\n", flipNormal ? "-" : ""); else WRITE(p, " mediump vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n"); } diff --git a/GPU/GLES/VertexShaderGeneratorGLES.h b/GPU/GLES/VertexShaderGeneratorGLES.h index df42bd4d11..743cea026a 100644 --- a/GPU/GLES/VertexShaderGeneratorGLES.h +++ b/GPU/GLES/VertexShaderGeneratorGLES.h @@ -22,3 +22,38 @@ struct VShaderID; bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const ShaderLanguageDesc &compat, uint32_t *attrMask, uint64_t *uniformMask, std::string *errorString); + +// D3D9 constants. +enum { + CONST_VS_PROJ = 0, + CONST_VS_PROJ_THROUGH = 4, + CONST_VS_VIEW = 8, + CONST_VS_WORLD = 11, + CONST_VS_TEXMTX = 14, + CONST_VS_UVSCALEOFFSET = 17, + CONST_VS_FOGCOEF = 18, + CONST_VS_AMBIENT = 19, + CONST_VS_MATAMBIENTALPHA = 20, + CONST_VS_MATDIFFUSE = 21, + CONST_VS_MATSPECULAR = 22, + CONST_VS_MATEMISSIVE = 23, + CONST_VS_LIGHTPOS = 24, + CONST_VS_LIGHTDIR = 28, + CONST_VS_LIGHTATT = 32, + CONST_VS_LIGHTANGLE_SPOTCOEF = 36, + CONST_VS_LIGHTDIFFUSE = 40, + CONST_VS_LIGHTSPECULAR = 44, + CONST_VS_LIGHTAMBIENT = 48, + CONST_VS_DEPTHRANGE = 52, + CONST_VS_BONE0 = 53, + CONST_VS_BONE1 = 56, + CONST_VS_BONE2 = 59, + CONST_VS_BONE3 = 62, + CONST_VS_BONE4 = 65, + CONST_VS_BONE5 = 68, + CONST_VS_BONE6 = 71, + CONST_VS_BONE7 = 74, + CONST_VS_BONE8 = 77, + CONST_VS_CULLRANGEMIN = 80, + CONST_VS_CULLRANGEMAX = 81, +}; diff --git a/unittest/TestShaderGenerators.cpp b/unittest/TestShaderGenerators.cpp index bd91558ca1..eed6e9b9d0 100644 --- a/unittest/TestShaderGenerators.cpp +++ b/unittest/TestShaderGenerators.cpp @@ -39,11 +39,13 @@ bool GenerateFShader(FShaderID id, char *buffer, ShaderLanguage lang, std::strin return GenerateFragmentShader(id, buffer, compat, &uniformMask, errorString); } case ShaderLanguage::HLSL_D3D9: + case ShaderLanguage::HLSL_D3D9_TEST: { ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D9); return GenerateFragmentShader(id, buffer, compat, &uniformMask, errorString); } case ShaderLanguage::HLSL_D3D11: + case ShaderLanguage::HLSL_D3D11_TEST: { ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D11); return GenerateFragmentShader(id, buffer, compat, &uniformMask, errorString); @@ -72,6 +74,16 @@ bool GenerateVShader(VShaderID id, char *buffer, ShaderLanguage lang, std::strin ShaderLanguageDesc compat(ShaderLanguage::GLSL_140); return GenerateVertexShaderGLSL(id, buffer, compat, &attrMask, &uniformMask, errorString); } + case ShaderLanguage::HLSL_D3D9_TEST: + { + ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D9); + return GenerateVertexShaderGLSL(id, buffer, compat, &attrMask, &uniformMask, errorString); + } + case ShaderLanguage::HLSL_D3D11_TEST: + { + ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D11); + return GenerateVertexShaderGLSL(id, buffer, compat, &attrMask, &uniformMask, errorString); + } case ShaderLanguage::HLSL_D3D9: { //ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D9); @@ -91,10 +103,12 @@ bool TestCompileShader(const char *buffer, ShaderLanguage lang, bool vertex, std std::vector spirv; switch (lang) { case ShaderLanguage::HLSL_D3D11: + case ShaderLanguage::HLSL_D3D11_TEST: { auto output = CompileShaderToBytecodeD3D11(buffer, strlen(buffer), vertex ? "vs_4_0" : "ps_4_0", 0); return !output.empty(); } + case ShaderLanguage::HLSL_D3D9_TEST: case ShaderLanguage::HLSL_D3D9: { LPD3DBLOB blob = CompileShaderToByteCodeD3D9(buffer, vertex ? "vs_2_0" : "ps_2_0", errorMessage); @@ -150,8 +164,9 @@ bool TestShaderGenerators() { LoadD3DCompilerDynamic(); ShaderLanguage languages[] = { - ShaderLanguage::HLSL_D3D9, + ShaderLanguage::HLSL_D3D11_TEST, ShaderLanguage::HLSL_D3D11, + ShaderLanguage::HLSL_D3D9, ShaderLanguage::GLSL_VULKAN, ShaderLanguage::GLSL_140, ShaderLanguage::GLSL_300, @@ -167,6 +182,57 @@ bool TestShaderGenerators() { int successes = 0; int count = 700; + // Generate a bunch of random vertex shader IDs, try to generate shader source. + // Then compile it and check that it's ok. + for (int i = 0; i < count; i++) { + uint32_t bottom = rng.R32(); + uint32_t top = rng.R32(); + VShaderID id; + id.d[0] = bottom; + id.d[1] = top; + + bool generateSuccess[numLanguages]{}; + std::string genErrorString[numLanguages]; + + for (int j = 0; j < numLanguages; j++) { + generateSuccess[j] = GenerateVShader(id, buffer[j], languages[j], &genErrorString[j]); + if (!genErrorString[j].empty()) { + printf("%s\n", genErrorString[j].c_str()); + } + } + + // KEEPING FOR REUSE LATER: Defunct temporary test: Compare GLSL-in-Vulkan-mode vs Vulkan + if (generateSuccess[0] != generateSuccess[1]) { + printf("mismatching success! '%s' '%s'\n", genErrorString[0].c_str(), genErrorString[1].c_str()); + printf("%s\n", buffer[0]); + printf("%s\n", buffer[1]); + return false; + } + if (generateSuccess[0] && strcmp(buffer[0], buffer[1])) { + printf("mismatching shaders!\n"); + PrintDiff(buffer[0], buffer[1]); + return false; + } + + // Now that we have the strings ready for easy comparison (buffer,4 in the watch window), + // let's try to compile them. + for (int j = 0; j < numLanguages; j++) { + if (generateSuccess[j]) { + std::string errorMessage; + if (!TestCompileShader(buffer[j], languages[j], true, &errorMessage)) { + printf("Error compiling vertex shader:\n\n%s\n\n%s\n", LineNumberString(buffer[j]).c_str(), errorMessage.c_str()); + return false; + } + successes++; + } + } + } + + printf("%d/%d vertex shaders generated (it's normal that it's not all, there are invalid bit combos)\n", successes, count * numLanguages); + + successes = 0; + count = 200; + // Generate a bunch of random fragment shader IDs, try to generate shader source. // Then compile it and check that it's ok. for (int i = 0; i < count; i++) { @@ -232,58 +298,6 @@ bool TestShaderGenerators() { successes = 0; count = 200; - /* - // Generate a bunch of random vertex shader IDs, try to generate shader source. - // Then compile it and check that it's ok. - for (int i = 0; i < count; i++) { - uint32_t bottom = rng.R32(); - uint32_t top = rng.R32(); - VShaderID id; - id.d[0] = bottom; - id.d[1] = top; - - bool generateSuccess[numLanguages]{}; - std::string genErrorString[numLanguages]; - - for (int j = 0; j < numLanguages; j++) { - generateSuccess[j] = GenerateVShader(id, buffer[j], languages[j], &genErrorString[j]); - if (!genErrorString[j].empty()) { - printf("%s\n", genErrorString[j].c_str()); - } - } - - // KEEPING FOR REUSE LATER: Defunct temporary test: Compare GLSL-in-Vulkan-mode vs Vulkan - if (generateSuccess[0] != generateSuccess[1]) { - printf("mismatching success! '%s' '%s'\n", genErrorString[0].c_str(), genErrorString[1].c_str()); - printf("%s\n", buffer[0]); - printf("%s\n", buffer[1]); - return false; - } - if (generateSuccess[0] && strcmp(buffer[0], buffer[1])) { - printf("mismatching shaders!\n"); - PrintDiff(buffer[0], buffer[1]); - return false; - } - - // Now that we have the strings ready for easy comparison (buffer,4 in the watch window), - // let's try to compile them. - for (int j = 0; j < numLanguages; j++) { - if (generateSuccess[j]) { - std::string errorMessage; - if (!TestCompileShader(buffer[j], languages[j], true, &errorMessage)) { - printf("Error compiling vertex shader:\n\n%s\n\n%s\n", LineNumberString(buffer[j]).c_str(), errorMessage.c_str()); - return false; - } - successes++; - } - } - } - - printf("%d/%d vertex shaders generated (it's normal that it's not all, there are invalid bit combos)\n", successes, count * numLanguages); - - successes = 0; - count = 200; - */ _CrtCheckMemory();