From af4d6e76424d8c0485c8125b55d29b6afdecd3e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 30 Oct 2020 10:22:40 +0100 Subject: [PATCH] Set up the test for D3D9, start fixing stuff. --- Common/GPU/D3D9/D3D9ShaderCompiler.cpp | 89 +++++++------------- Common/GPU/D3D9/D3D9ShaderCompiler.h | 9 +- Common/GPU/OpenGL/GLQueueRunner.cpp | 2 +- GPU/Common/DepalettizeShaderCommon.cpp | 6 +- GPU/Common/PresentationCommon.cpp | 4 +- GPU/Common/ShaderCommon.cpp | 81 +++++++++--------- GPU/Common/ShaderCommon.h | 18 ++-- GPU/Common/ShaderTranslation.cpp | 10 +-- GPU/Directx9/DepalettizeShaderDX9.cpp | 8 +- GPU/Directx9/DepalettizeShaderDX9.h | 4 +- GPU/Directx9/FragmentShaderGeneratorHLSL.cpp | 35 ++------ GPU/Directx9/FramebufferManagerDX9.cpp | 6 +- GPU/Directx9/ShaderManagerDX9.cpp | 10 +-- GPU/Directx9/StencilBufferDX9.cpp | 4 +- GPU/Directx9/VertexShaderGeneratorHLSL.cpp | 4 +- GPU/GLES/FragmentShaderGeneratorGLES.cpp | 78 ++++++++++------- GPU/GLES/ShaderManagerGLES.cpp | 6 ++ GPU/GLES/VertexShaderGeneratorGLES.cpp | 25 +++--- GPU/Vulkan/ShaderManagerVulkan.cpp | 8 +- unittest/TestShaderGenerators.cpp | 69 ++++++++++----- 20 files changed, 236 insertions(+), 240 deletions(-) diff --git a/Common/GPU/D3D9/D3D9ShaderCompiler.cpp b/Common/GPU/D3D9/D3D9ShaderCompiler.cpp index b54bb215c1..8240dc7587 100644 --- a/Common/GPU/D3D9/D3D9ShaderCompiler.cpp +++ b/Common/GPU/D3D9/D3D9ShaderCompiler.cpp @@ -1,7 +1,7 @@ -#ifdef _WIN32 - #include "ppsspp_config.h" +#ifdef _WIN32 + #include "Common/CommonWindows.h" #include "Common/GPU/D3D9/D3DCompilerLoader.h" #include "Common/GPU/D3D9/D3D9ShaderCompiler.h" @@ -10,9 +10,7 @@ struct ID3DXConstantTable; -namespace DX9 { - -bool CompilePixelShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPIXELSHADER9 *pShader, ID3DXConstantTable **pShaderTable, std::string &errorMessage) { +LPD3DBLOB CompileShaderToByteCodeD3D9(const char *code, const char *target, std::string *errorMessage) { LPD3DBLOB pShaderCode = nullptr; LPD3DBLOB pErrorMsg = nullptr; @@ -23,77 +21,50 @@ bool CompilePixelShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPI nullptr, nullptr, "main", - "ps_2_0", + target, 0, 0, &pShaderCode, &pErrorMsg); if (pErrorMsg) { - errorMessage = (CHAR *)pErrorMsg->GetBufferPointer(); + *errorMessage = (CHAR *)pErrorMsg->GetBufferPointer(); pErrorMsg->Release(); } else if (FAILED(hr)) { - errorMessage = GetStringErrorMsg(hr); - } else { - errorMessage = ""; - } - - if (FAILED(hr) || !pShaderCode) { - if (pShaderCode) + *errorMessage = GetStringErrorMsg(hr); + if (pShaderCode) { pShaderCode->Release(); - return false; + pShaderCode = nullptr; + } + } else { + *errorMessage = ""; } - // Create pixel shader. - device->CreatePixelShader( (DWORD*)pShaderCode->GetBufferPointer(), - pShader ); - - pShaderCode->Release(); - - return true; + return pShaderCode; } -bool CompileVertexShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DVERTEXSHADER9 *pShader, ID3DXConstantTable **pShaderTable, std::string &errorMessage) { - LPD3DBLOB pShaderCode = nullptr; - LPD3DBLOB pErrorMsg = nullptr; - - // Compile pixel shader. - HRESULT hr = dyn_D3DCompile(code, - (UINT)strlen(code), - nullptr, - nullptr, - nullptr, - "main", - "vs_2_0", - 0, - 0, - &pShaderCode, - &pErrorMsg); - - if (pErrorMsg) { - errorMessage = (CHAR *)pErrorMsg->GetBufferPointer(); - pErrorMsg->Release(); - } else if (FAILED(hr)) { - errorMessage = GetStringErrorMsg(hr); +bool CompilePixelShaderD3D9(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPIXELSHADER9 *pShader, std::string *errorMessage) { + LPD3DBLOB pShaderCode = CompileShaderToByteCodeD3D9(code, "ps_2_0", errorMessage); + if (pShaderCode) { + // Create pixel shader. + device->CreatePixelShader((DWORD*)pShaderCode->GetBufferPointer(), pShader); + pShaderCode->Release(); + return true; } else { - errorMessage = ""; - } - - if (FAILED(hr) || !pShaderCode) { - if (pShaderCode) - pShaderCode->Release(); return false; } - - // Create pixel shader. - device->CreateVertexShader( (DWORD*)pShaderCode->GetBufferPointer(), - pShader ); - - pShaderCode->Release(); - - return true; } -} // namespace +bool CompileVertexShaderD3D9(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DVERTEXSHADER9 *pShader, std::string *errorMessage) { + LPD3DBLOB pShaderCode = CompileShaderToByteCodeD3D9(code, "vs_2_0", errorMessage); + if (pShaderCode) { + // Create vertex shader. + device->CreateVertexShader((DWORD*)pShaderCode->GetBufferPointer(), pShader); + pShaderCode->Release(); + return true; + } else { + return false; + } +} #endif diff --git a/Common/GPU/D3D9/D3D9ShaderCompiler.h b/Common/GPU/D3D9/D3D9ShaderCompiler.h index 6c4aaf75a2..1de2a158d0 100644 --- a/Common/GPU/D3D9/D3D9ShaderCompiler.h +++ b/Common/GPU/D3D9/D3D9ShaderCompiler.h @@ -1,6 +1,7 @@ #pragma once #include "Common/CommonWindows.h" +#include "Common/GPU/D3D9/D3DCompilerLoader.h" #include #include @@ -8,9 +9,7 @@ struct ID3DXConstantTable; -namespace DX9 { +LPD3DBLOB CompileShaderToByteCodeD3D9(const char *code, const char *target, std::string *errorMessage); -bool CompilePixelShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPIXELSHADER9 *pShader, ID3DXConstantTable **pShaderTable, std::string &errorMessage); -bool CompileVertexShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DVERTEXSHADER9 *pShader, ID3DXConstantTable **pShaderTable, std::string &errorMessage); - -} // namespace DX9 +bool CompilePixelShaderD3D9(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPIXELSHADER9 *pShader, std::string *errorMessage); +bool CompileVertexShaderD3D9(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DVERTEXSHADER9 *pShader, std::string *errorMessage); diff --git a/Common/GPU/OpenGL/GLQueueRunner.cpp b/Common/GPU/OpenGL/GLQueueRunner.cpp index 1d5c024379..c01eb0ed70 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.cpp +++ b/Common/GPU/OpenGL/GLQueueRunner.cpp @@ -279,7 +279,7 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps, bool ski glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if (!success) { std::string infoLog = GetInfoLog(shader, glGetShaderiv, glGetShaderInfoLog); -#ifdef __ANDROID__ +#if PPSSPP_PLATFORM(ANDROID) ERROR_LOG(G3D, "Error in shader compilation! %s\n", infoLog.c_str()); ERROR_LOG(G3D, "Shader source:\n%s\n", (const char *)code); #endif diff --git a/GPU/Common/DepalettizeShaderCommon.cpp b/GPU/Common/DepalettizeShaderCommon.cpp index 5a0c7c6e4a..516c3b9fde 100644 --- a/GPU/Common/DepalettizeShaderCommon.cpp +++ b/GPU/Common/DepalettizeShaderCommon.cpp @@ -164,7 +164,7 @@ void GenerateDepalShader300(char *buffer, GEBufferFormat pixelFormat, ShaderLang void GenerateDepalShaderFloat(char *buffer, GEBufferFormat pixelFormat, ShaderLanguage lang) { char *p = buffer; - const char *modFunc = lang == HLSL_DX9 ? "fmod" : "mod"; + const char *modFunc = lang == HLSL_D3D9 ? "fmod" : "mod"; char lookupMethod[128] = "index.r"; char offset[128] = ""; @@ -305,7 +305,7 @@ void GenerateDepalShaderFloat(char *buffer, GEBufferFormat pixelFormat, ShaderLa WRITE(p, " float coord = (%s * %f)%s;\n", lookupMethod, index_multiplier, offset); WRITE(p, " gl_FragColor = texture2D(pal, vec2(coord, 0.0));\n"); WRITE(p, "}\n"); - } else if (lang == HLSL_DX9) { + } else if (lang == HLSL_D3D9) { WRITE(p, "sampler tex: register(s0);\n"); WRITE(p, "sampler pal: register(s1);\n"); WRITE(p, "float4 main(float2 v_texcoord0 : TEXCOORD0) : COLOR0 {\n"); @@ -326,7 +326,7 @@ void GenerateDepalShader(char *buffer, GEBufferFormat pixelFormat, ShaderLanguag case HLSL_D3D11: GenerateDepalShader300(buffer, pixelFormat, language); break; - case HLSL_DX9: + case HLSL_D3D9: GenerateDepalShaderFloat(buffer, pixelFormat, language); break; default: diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index e969e390e4..2d4da991c6 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -372,7 +372,7 @@ Draw::Pipeline *PresentationCommon::CreatePipeline(std::vectorGetNativeObject(Draw::NativeObject::DEVICE); std::string errorMessage; - if (!DX9::CompileVertexShader(device_, depalVShaderHLSL, &vertexShader_, nullptr, errorMessage)) { + if (!CompileVertexShaderD3D9(device_, depalVShaderHLSL, &vertexShader_, &errorMessage)) { ERROR_LOG(G3D, "error compling depal vshader: %s", errorMessage.c_str()); } } @@ -152,11 +152,11 @@ LPDIRECT3DPIXELSHADER9 DepalShaderCacheDX9::GetDepalettizePixelShader(uint32_t c char *buffer = new char[2048]; - GenerateDepalShader(buffer, pixelFormat, HLSL_DX9); + GenerateDepalShader(buffer, pixelFormat, HLSL_D3D9); LPDIRECT3DPIXELSHADER9 pshader; std::string errorMessage; - if (!CompilePixelShader(device_, buffer, &pshader, NULL, errorMessage)) { + if (!CompilePixelShaderD3D9(device_, buffer, &pshader, &errorMessage)) { ERROR_LOG(G3D, "Failed to compile depal pixel shader: %s\n\n%s", buffer, errorMessage.c_str()); delete[] buffer; return nullptr; diff --git a/GPU/Directx9/DepalettizeShaderDX9.h b/GPU/Directx9/DepalettizeShaderDX9.h index b6c77aa6f2..1f9ad4a6b7 100644 --- a/GPU/Directx9/DepalettizeShaderDX9.h +++ b/GPU/Directx9/DepalettizeShaderDX9.h @@ -54,9 +54,9 @@ public: private: LPDIRECT3DDEVICE9 device_; - LPDIRECT3DVERTEXSHADER9 vertexShader_; + LPDIRECT3DVERTEXSHADER9 vertexShader_ = nullptr; std::map cache_; std::map texCache_; }; -} // namespace \ No newline at end of file +} // namespace diff --git a/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp b/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp index bca9438265..b109988234 100644 --- a/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp +++ b/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp @@ -29,24 +29,9 @@ // #define DEBUG_SHADER -const char *hlsl_preamble = -"#define vec2 float2\n" -"#define vec3 float3\n" -"#define vec4 float4\n" -"#define uvec3 uint3\n" -"#define ivec3 int3\n" -"#define splat3(x) float3(x, x, x)\n" -"#define mix lerp\n" -"#define mod(x, y) fmod(x, y)\n"; - -const char *hlsl_d3d11_preamble = -"#define DISCARD discard\n" -"#define DISCARD_BELOW(x) clip(x);\n"; -const char *hlsl_d3d9_preamble = -"#define DISCARD clip(-1)\n" -"#define DISCARD_BELOW(x) clip(x)\n"; - -const char *hlsl_late_preamble = ""; +extern const char *hlsl_preamble_fs; +extern const char *hlsl_d3d9_preamble_fs; +extern const char *hlsl_d3d11_preamble_fs; // Missing: Z depth range // Also, logic ops etc, of course, as they are not supported in DX9. @@ -86,19 +71,19 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag StencilValueType replaceAlphaWithStencilType = (StencilValueType)id.Bits(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE, 4); - WRITE(p, "%s", hlsl_preamble); + WRITE(p, "%s", hlsl_preamble_fs); // Output some compatibility defines switch (lang) { - case ShaderLanguage::HLSL_DX9: - WRITE(p, hlsl_d3d9_preamble); + case ShaderLanguage::HLSL_D3D9: + WRITE(p, hlsl_d3d9_preamble_fs); break; case ShaderLanguage::HLSL_D3D11: - WRITE(p, hlsl_d3d11_preamble); + WRITE(p, hlsl_d3d11_preamble_fs); break; } - if (lang == HLSL_DX9) { + if (lang == HLSL_D3D9) { if (doTexture) WRITE(p, "sampler tex : register(s0);\n"); if (!isModeClear && replaceBlend > REPLACE_BLEND_STANDARD) { @@ -178,8 +163,7 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag } WRITE(p, "};\n"); - if (lang == HLSL_DX9) { - WRITE(p, "%s", hlsl_late_preamble); + if (lang == HLSL_D3D9) { WRITE(p, "vec4 main( PS_IN In ) : COLOR {\n"); } else { WRITE(p, "struct PS_OUT {\n"); @@ -194,7 +178,6 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag WRITE(p, " float depth : SV_DEPTH;\n"); } WRITE(p, "};\n"); - WRITE(p, "%s", hlsl_late_preamble); WRITE(p, "PS_OUT main( PS_IN In ) {\n"); WRITE(p, " PS_OUT outfragment;\n"); } diff --git a/GPU/Directx9/FramebufferManagerDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp index 0c9c2d5720..3bbecb90b3 100644 --- a/GPU/Directx9/FramebufferManagerDX9.cpp +++ b/GPU/Directx9/FramebufferManagerDX9.cpp @@ -88,11 +88,11 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE); deviceEx_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE_EX); std::string errorMsg; - if (!CompileVertexShader(device_, vscode, &pFramebufferVertexShader, nullptr, errorMsg)) { + if (!CompileVertexShaderD3D9(device_, vscode, &pFramebufferVertexShader, &errorMsg)) { OutputDebugStringA(errorMsg.c_str()); } - if (!CompilePixelShader(device_, pscode, &pFramebufferPixelShader, nullptr, errorMsg)) { + if (!CompilePixelShaderD3D9(device_, pscode, &pFramebufferPixelShader, &errorMsg)) { OutputDebugStringA(errorMsg.c_str()); if (pFramebufferVertexShader) { pFramebufferVertexShader->Release(); @@ -116,7 +116,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { ShaderTranslationInit(); - presentation_->SetLanguage(HLSL_DX9); + presentation_->SetLanguage(HLSL_D3D9); preferredPixelsFormat_ = Draw::DataFormat::B8G8R8A8_UNORM; } diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index bce4de6770..ee6f75a600 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -57,7 +57,7 @@ PSShader::PSShader(LPDIRECT3DDEVICE9 device, FShaderID id, const char *code) : i bool success; std::string errorMessage; - success = CompilePixelShader(device, code, &shader, NULL, errorMessage); + success = CompilePixelShaderD3D9(device, code, &shader, &errorMessage); if (!errorMessage.empty()) { if (success) { @@ -107,7 +107,7 @@ VSShader::VSShader(LPDIRECT3DDEVICE9 device, VShaderID id, const char *code, boo bool success; std::string errorMessage; - success = CompileVertexShader(device, code, &shader, NULL, errorMessage); + success = CompileVertexShaderD3D9(device, code, &shader, &errorMessage); if (!errorMessage.empty()) { if (success) { ERROR_LOG(G3D, "Warnings in shader compilation!"); @@ -588,7 +588,7 @@ VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellat if (vsIter == vsCache_.end()) { // Vertex shader not in cache. Let's compile it. std::string genErrorString; - if (GenerateVertexShaderHLSL(VSID, codeBuffer_, HLSL_DX9, &genErrorString)) { + if (GenerateVertexShaderHLSL(VSID, codeBuffer_, HLSL_D3D9, &genErrorString)) { vs = new VSShader(device_, VSID, codeBuffer_, useHWTransform); } if (!vs || vs->Failed()) { @@ -611,7 +611,7 @@ VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellat // next time and we'll do this over and over... // Can still work with software transform. - bool success = GenerateVertexShaderHLSL(VSID, codeBuffer_, HLSL_DX9, &genErrorString); + bool success = GenerateVertexShaderHLSL(VSID, codeBuffer_, HLSL_D3D9, &genErrorString); _assert_(success); vs = new VSShader(device_, VSID, codeBuffer_, false); } @@ -627,7 +627,7 @@ VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellat if (fsIter == fsCache_.end()) { // Fragment shader not in cache. Let's compile it. std::string errorString; - bool success = GenerateFragmentShaderHLSL(FSID, codeBuffer_, HLSL_DX9, &errorString); + bool success = GenerateFragmentShaderHLSL(FSID, codeBuffer_, HLSL_D3D9, &errorString); // We're supposed to handle all possible cases. _assert_(success); fs = new PSShader(device_, FSID, codeBuffer_); diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index be617417f0..d8e740836b 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -132,7 +132,7 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, StencilUploa // TODO: Helper with logging? if (!stencilUploadPS_) { std::string errorMessage; - bool success = CompilePixelShader(device_, stencil_ps, &stencilUploadPS_, NULL, errorMessage); + bool success = CompilePixelShaderD3D9(device_, stencil_ps, &stencilUploadPS_, &errorMessage); if (!errorMessage.empty()) { if (success) { ERROR_LOG(G3D, "Warnings in shader compilation!"); @@ -154,7 +154,7 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, StencilUploa } if (!stencilUploadVS_) { std::string errorMessage; - bool success = CompileVertexShader(device_, stencil_vs, &stencilUploadVS_, NULL, errorMessage); + bool success = CompileVertexShaderD3D9(device_, stencil_vs, &stencilUploadVS_, &errorMessage); if (!errorMessage.empty()) { if (success) { ERROR_LOG(G3D, "Warnings in shader compilation!"); diff --git a/GPU/Directx9/VertexShaderGeneratorHLSL.cpp b/GPU/Directx9/VertexShaderGeneratorHLSL.cpp index 05bc0b41c7..1a71e1ce03 100644 --- a/GPU/Directx9/VertexShaderGeneratorHLSL.cpp +++ b/GPU/Directx9/VertexShaderGeneratorHLSL.cpp @@ -108,7 +108,7 @@ bool GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage WRITE(p, "#define mat3x4 float4x3\n"); // note how the conventions are backwards WRITE(p, "#define splat3(x) vec3(x, x, x)\n"); - if (lang == HLSL_DX9) { + if (lang == HLSL_D3D9) { WRITE(p, "#pragma warning( disable : 3571 )\n"); if (isModeThrough) { WRITE(p, "float4x4 u_proj_through : register(c%i);\n", CONST_VS_PROJ_THROUGH); @@ -245,7 +245,7 @@ bool GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage if (enableFog) { WRITE(p, " float v_fogdepth: TEXCOORD1;\n"); } - if (lang == HLSL_DX9) { + if (lang == HLSL_D3D9) { WRITE(p, " vec4 gl_Position : POSITION;\n"); } else { WRITE(p, " vec4 gl_Position : SV_Position;\n"); diff --git a/GPU/GLES/FragmentShaderGeneratorGLES.cpp b/GPU/GLES/FragmentShaderGeneratorGLES.cpp index 4d97c3b855..e190bb70a5 100644 --- a/GPU/GLES/FragmentShaderGeneratorGLES.cpp +++ b/GPU/GLES/FragmentShaderGeneratorGLES.cpp @@ -34,7 +34,7 @@ #define WRITE p+=sprintf -static const char *vulkan_glsl_preamble = +const char *vulkan_glsl_preamble_fs = "#version 450\n" "#extension GL_ARB_separate_shader_objects : enable\n" "#extension GL_ARB_shading_language_420pack : enable\n" @@ -46,17 +46,31 @@ static const char *vulkan_glsl_preamble = "#define highp\n" "#define DISCARD discard\n" "\n"; -extern const char *hlsl_preamble; -extern const char *hlsl_d3d9_preamble; -extern const char *hlsl_d3d11_preamble; -extern const char *hlsl_late_preamble; + +const char *hlsl_preamble_fs = +"#define vec2 float2\n" +"#define vec3 float3\n" +"#define vec4 float4\n" +"#define uvec3 uint3\n" +"#define ivec3 int3\n" +"#define splat3(x) float3(x, x, x)\n" +"#define mix lerp\n" +"#define mod(x, y) fmod(x, y)\n"; + +const char *hlsl_d3d11_preamble_fs = +"#define DISCARD discard\n" +"#define DISCARD_BELOW(x) clip(x);\n"; +const char *hlsl_d3d9_preamble_fs = +"#define DISCARD clip(-1)\n" +"#define DISCARD_BELOW(x) clip(x)\n"; + bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLShaderCompat &compat, uint64_t *uniformMask, std::string *errorString) { *uniformMask = 0; bool highpFog = false; bool highpTexcoord = false; - bool enableFragmentTestCache = g_Config.bFragmentTestCache && !compat.vulkan && !compat.d3d11; + bool enableFragmentTestCache = g_Config.bFragmentTestCache && ShaderLanguageIsOpenGL(compat.shaderLanguage); if (compat.gles) { // PowerVR needs highp to do the fog in MHU correctly. @@ -69,15 +83,20 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha char *p = buffer; - if (compat.vulkan) { - WRITE(p, "%s", vulkan_glsl_preamble); - } else if (compat.d3d11) { - WRITE(p, "%s", hlsl_preamble); - WRITE(p, "%s", hlsl_d3d11_preamble); - } else if (compat.d3d9) { - WRITE(p, "%s", hlsl_preamble); - WRITE(p, "%s", hlsl_d3d9_preamble); - } else { + switch (compat.shaderLanguage) { + case ShaderLanguage::GLSL_VULKAN: + WRITE(p, "%s", vulkan_glsl_preamble_fs); + break; + case ShaderLanguage::HLSL_D3D11: + WRITE(p, "%s", hlsl_preamble_fs); + WRITE(p, "%s", hlsl_d3d11_preamble_fs); + break; + case ShaderLanguage::HLSL_D3D9: + WRITE(p, "%s", hlsl_preamble_fs); + WRITE(p, "%s", hlsl_d3d9_preamble_fs); + break; + default: + // OpenGL WRITE(p, "#version %d%s\n", compat.glslVersionNumber, compat.gles ? " es" : ""); WRITE(p, "#define DISCARD discard\n"); @@ -134,13 +153,13 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha bool isModeClear = id.Bit(FS_BIT_CLEARMODE); const char *shading = ""; - if (compat.glslES30 || compat.vulkan) + if (compat.glslES30 || compat.shaderLanguage == ShaderLanguage::GLSL_VULKAN) shading = doFlatShading ? "flat" : ""; bool earlyFragmentTests = ((!enableAlphaTest && !enableColorTest) || testForceToZero) && !gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT); bool useAdrenoBugWorkaround = id.Bit(FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL); - if (compat.vulkan) { + if (compat.shaderLanguage == ShaderLanguage::GLSL_VULKAN) { if (earlyFragmentTests) { WRITE(p, "layout (early_fragment_tests) in;\n"); } else if (useAdrenoBugWorkaround && !gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT)) { @@ -183,7 +202,7 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha if (stencilToAlpha == REPLACE_ALPHA_DUALSOURCE) { WRITE(p, "layout (location = 0, index = 1) out vec4 fragColor1;\n"); } - } else if (compat.d3d11) { + } else if (compat.shaderLanguage == ShaderLanguage::HLSL_D3D11) { WRITE(p, "SamplerState samp : register(s0);\n"); WRITE(p, "Texture2D tex : register(t0);\n"); if (!isModeClear && replaceBlend > REPLACE_BLEND_STANDARD) { @@ -229,7 +248,7 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha WRITE(p, " float depth : SV_DEPTH;\n"); } WRITE(p, "};\n"); - } else { + } else if (ShaderLanguageIsOpenGL(compat.shaderLanguage)) { if (shaderDepal && gl_extensions.IsGLES) { WRITE(p, "precision highp int;\n"); } @@ -343,8 +362,7 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha WRITE(p, "float mymod(float a, float b) { return a - b * floor(a / b); }\n"); } - if (compat.d3d11) { - WRITE(p, "%s", hlsl_late_preamble); + if (compat.shaderLanguage == HLSL_D3D11 || compat.shaderLanguage == HLSL_D3D9) { WRITE(p, "PS_OUT main( PS_IN In ) {\n"); WRITE(p, " PS_OUT outfragment;\n"); } else { @@ -364,7 +382,7 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha } if (doTexture) { - std::string texcoord = std::string(compat.inPrefix) + "v_texcoord"; + std::string texcoord = StringFromFormat("%sv_texcoord", compat.inPrefix); // TODO: Not sure the right way to do this for projection. // This path destroys resolution on older PowerVR no matter what I do if projection is needed, // so we disable it on SGX 540 and lesser, and live with the consequences. @@ -378,8 +396,8 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha // We may be clamping inside a larger surface (tex = 64x64, buffer=480x272). // We may also be wrapping in such a surface, or either one in a too-small surface. // Obviously, clamping to a smaller surface won't work. But better to clamp to something. - std::string ucoord = std::string(compat.inPrefix) + "v_texcoord.x"; - std::string vcoord = std::string(compat.inPrefix) + "v_texcoord.y"; + std::string ucoord = StringFromFormat("%sv_texcoord.x", compat.inPrefix); + std::string vcoord = StringFromFormat("%sv_texcoord.y", compat.inPrefix); if (doTextureProjection) { ucoord = StringFromFormat("(%sv_texcoord.x / %sv_texcoord.z)", compat.inPrefix, compat.inPrefix); vcoord = StringFromFormat("(%sv_texcoord.y / %sv_texcoord.z)", compat.inPrefix, compat.inPrefix); @@ -409,7 +427,7 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha } if (!shaderDepal) { - if (compat.d3d11) { + if (compat.shaderLanguage == HLSL_D3D11) { if (doTextureProjection) { WRITE(p, " vec4 t = tex.Sample(samp, %sv_texcoord.xy / %sv_texcoord.z)%s;\n", compat.inPrefix, compat.inPrefix, bgraTexture ? ".bgra" : ""); } else { @@ -668,7 +686,7 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha const char *colorTestFuncs[] = { "#", "#", " != ", " == " }; if (colorTestFuncs[colorTestFunc][0] != '#') { // TODO: Unify these paths better. - if (compat.d3d11) { + if (compat.shaderLanguage == HLSL_D3D11) { const char *test = colorTestFuncs[colorTestFunc]; WRITE(p, " uvec3 v_scaled = roundAndScaleTo255iv(v.rgb);\n"); WRITE(p, " uvec3 v_masked = v_scaled & u_alphacolormask.rgb;\n"); @@ -678,7 +696,7 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha } else if (compat.bitwiseOps) { // Apparently GLES3 does not support vector bitwise ops. WRITE(p, " ivec3 v_scaled = roundAndScaleTo255iv(v.rgb);\n"); - if (compat.vulkan) { + if (compat.shaderLanguage == GLSL_VULKAN) { // TODO: Use this for GL as well? WRITE(p, " if ((v_scaled & u_alphacolormask.rgb) %s (u_alphacolorref.rgb & u_alphacolormask.rgb)) %s\n", colorTestFuncs[colorTestFunc], discardStatement); } else { @@ -728,10 +746,10 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha WRITE(p, " v.rgb = v.rgb * %s;\n", srcFactor); } - if (replaceBlend == REPLACE_BLEND_COPY_FBO) { + if (replaceBlend == REPLACE_BLEND_COPY_FBO && compat.shaderLanguage != HLSL_D3D9) { // If we have NV_shader_framebuffer_fetch / EXT_shader_framebuffer_fetch, we skip the blit. // We can just read the prev value more directly. - if (compat.d3d11) { + if (compat.shaderLanguage == HLSL_D3D11) { WRITE(p, " vec4 destColor = fboTex.Load(int3((int)In.pixelPos.x, (int)In.pixelPos.y, 0));\n"); } else if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)) { WRITE(p, " lowp vec4 destColor = %s;\n", compat.lastFragData); @@ -904,7 +922,7 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha WRITE(p, " %s = v;\n", compat.fragColor0); } - if (compat.d3d11) { + if (compat.shaderLanguage == HLSL_D3D11 || compat.shaderLanguage == HLSL_D3D9) { WRITE(p, " return outfragment;\n"); } diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 5d5af4f4a8..887eade3ec 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -585,6 +585,7 @@ ShaderManagerGLES::~ShaderManagerGLES() { void ShaderManagerGLES::DetectShaderLanguage() { GLSLShaderCompat &compat = compat_; + compat.shaderLanguage = ShaderLanguage::GLSL_140; compat.attribute = "attribute"; compat.varying_vs = "varying"; compat.varying_fs = "varying"; @@ -599,6 +600,7 @@ void ShaderManagerGLES::DetectShaderLanguage() { if (compat.gles) { if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300)) { + compat.shaderLanguage = ShaderLanguage::GLSL_300; compat.glslVersionNumber = 300; // GLSL ES 3.0 compat.fragColor0 = "fragColor0"; compat.texture = "texture"; @@ -606,6 +608,7 @@ void ShaderManagerGLES::DetectShaderLanguage() { compat.bitwiseOps = true; compat.texelFetch = "texelFetch"; } else { + compat.shaderLanguage = ShaderLanguage::GLSL_140; compat.glslVersionNumber = 100; // GLSL ES 1.0 if (gl_extensions.EXT_gpu_shader4) { compat.bitwiseOps = true; @@ -619,6 +622,7 @@ void ShaderManagerGLES::DetectShaderLanguage() { } else { if (!gl_extensions.ForceGL2 || gl_extensions.IsCoreContext) { if (gl_extensions.VersionGEThan(3, 3, 0)) { + compat.shaderLanguage = ShaderLanguage::GLSL_300; compat.glslVersionNumber = 330; compat.fragColor0 = "fragColor0"; compat.texture = "texture"; @@ -626,11 +630,13 @@ void ShaderManagerGLES::DetectShaderLanguage() { compat.bitwiseOps = true; compat.texelFetch = "texelFetch"; } else if (gl_extensions.VersionGEThan(3, 0, 0)) { + compat.shaderLanguage = ShaderLanguage::GLSL_140; compat.glslVersionNumber = 130; compat.fragColor0 = "fragColor0"; compat.bitwiseOps = true; compat.texelFetch = "texelFetch"; } else { + compat.shaderLanguage = ShaderLanguage::GLSL_140; compat.glslVersionNumber = 110; if (gl_extensions.EXT_gpu_shader4) { compat.bitwiseOps = true; diff --git a/GPU/GLES/VertexShaderGeneratorGLES.cpp b/GPU/GLES/VertexShaderGeneratorGLES.cpp index c5d0bf8623..76faa4af05 100644 --- a/GPU/GLES/VertexShaderGeneratorGLES.cpp +++ b/GPU/GLES/VertexShaderGeneratorGLES.cpp @@ -113,7 +113,7 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const GLSLShade bool highpTexcoord = false; char *p = buffer; - if (compat.vulkan) { + if (compat.shaderLanguage == GLSL_VULKAN) { WRITE(p, "%s", vulkan_glsl_preamble); } else { if (compat.gles) { @@ -126,13 +126,13 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const GLSLShade WRITE(p, "#define splat3(x) vec3(x)\n"); } - if (!compat.vulkan && gl_extensions.EXT_gpu_shader4) { + 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.vulkan) { + } else if (!compat.shaderLanguage == GLSL_VULKAN) { WRITE(p, "#define lowp\n"); WRITE(p, "#define mediump\n"); WRITE(p, "#define highp\n"); @@ -175,7 +175,7 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const GLSLShade bool hasNormalTess = id.Bit(VS_BIT_HAS_NORMAL_TESS); bool flipNormalTess = id.Bit(VS_BIT_NORM_REVERSE_TESS); - if (compat.vulkan) { + 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) @@ -185,7 +185,7 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const GLSLShade } const char *shading = ""; - if (compat.glslES30 || compat.vulkan) + if (compat.glslES30 || compat.shaderLanguage == GLSL_VULKAN) shading = doFlatShading ? "flat " : ""; DoLightComputation doLight[4] = { LIGHT_OFF, LIGHT_OFF, LIGHT_OFF, LIGHT_OFF }; @@ -204,7 +204,7 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const GLSLShade int boneWeightScale = id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2); bool texcoordInVec3 = false; - if (compat.vulkan) { + if (compat.shaderLanguage == GLSL_VULKAN) { if (enableBones) { numBoneWeights = 1 + id.Bits(VS_BIT_BONES, 3); WRITE(p, "%s", boneWeightDecl[numBoneWeights]); @@ -307,15 +307,10 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const GLSLShade *uniformMask |= DIRTY_TEXMATRIX; } if (enableBones) { -#ifdef USE_BONE_ARRAY - WRITE(p, "uniform mediump mat4 u_bone[%i];\n", numBoneWeights); - *uniformMask |= DIRTY_BONE_UNIFORMS; -#else for (int i = 0; i < numBoneWeights; i++) { WRITE(p, "uniform mat4 u_bone%i;\n", i); *uniformMask |= DIRTY_BONEMATRIX0 << i; } -#endif } if (doTexture) { WRITE(p, "uniform vec4 u_uvscaleoffset;\n"); @@ -415,7 +410,7 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const GLSLShade if (doBezier || doSpline) { *uniformMask |= DIRTY_BEZIERSPLINE; - if (compat.vulkan) { + if (compat.shaderLanguage == GLSL_VULKAN) { WRITE(p, "struct TessData {\n"); WRITE(p, " vec4 pos;\n"); WRITE(p, " vec4 uv;\n"); @@ -615,14 +610,14 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const GLSLShade // Uncomment this to screw up bone shaders to check the vertex shader software fallback // WRITE(p, "THIS SHOULD ERROR! #error"); - if (numBoneWeights == 1 && !compat.vulkan) + if (numBoneWeights == 1 && compat.shaderLanguage != GLSL_VULKAN) WRITE(p, " %s skinMatrix = w1 * u_bone0", boneMatrix); else WRITE(p, " %s skinMatrix = w1.x * u_bone0", boneMatrix); for (int i = 1; i < numBoneWeights; i++) { const char *weightAttr = boneWeightAttr[i]; // workaround for "cant do .x of scalar" issue - if (!compat.vulkan) { + if (compat.shaderLanguage != GLSL_VULKAN) { if (numBoneWeights == 1 && i == 0) weightAttr = "w1"; if (numBoneWeights == 5 && i == 4) weightAttr = "w2"; } @@ -895,7 +890,7 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const GLSLShade WRITE(p, " }\n"); } WRITE(p, " gl_Position = outPos;\n"); - if (compat.vulkan) { + if (compat.shaderLanguage == GLSL_VULKAN) { WRITE(p, " gl_PointSize = 1.0;\n"); } diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index 84909a4d8a..6503aa3b1f 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -169,7 +169,7 @@ ShaderManagerVulkan::ShaderManagerVulkan(Draw::DrawContext *draw, VulkanContext static_assert(sizeof(ub_lights) <= 512, "ub_lights grew too big"); static_assert(sizeof(ub_bones) <= 384, "ub_bones grew too big"); - compat_.SetupForVulkan(); + compat_.SetupForShaderLanguage(ShaderLanguage::GLSL_VULKAN); } ShaderManagerVulkan::~ShaderManagerVulkan() { @@ -390,8 +390,6 @@ bool ShaderManagerVulkan::LoadCache(FILE *f) { if (header.featureFlags != gstate_c.featureFlags) return false; - GLSLShaderCompat compat{}; - compat.SetupForVulkan(); for (int i = 0; i < header.numVertexShaders; i++) { VShaderID id; if (fread(&id, sizeof(id), 1, f) != 1) { @@ -402,7 +400,7 @@ bool ShaderManagerVulkan::LoadCache(FILE *f) { std::string genErrorString; uint32_t attributeMask = 0; uint64_t uniformMask = 0; - if (!GenerateVertexShaderGLSL(id, codeBuffer_, compat, &attributeMask, &uniformMask, &genErrorString)) { + if (!GenerateVertexShaderGLSL(id, codeBuffer_, compat_, &attributeMask, &uniformMask, &genErrorString)) { return false; } VulkanVertexShader *vs = new VulkanVertexShader(vulkan_, id, codeBuffer_, useHWTransform); @@ -418,7 +416,7 @@ bool ShaderManagerVulkan::LoadCache(FILE *f) { } std::string genErrorString; uint64_t uniformMask = 0; - if (!GenerateFragmentShaderGLSL(id, codeBuffer_, compat, &uniformMask, &genErrorString)) { + if (!GenerateFragmentShaderGLSL(id, codeBuffer_, compat_, &uniformMask, &genErrorString)) { return false; } VulkanFragmentShader *fs = new VulkanFragmentShader(vulkan_, id, codeBuffer_); diff --git a/unittest/TestShaderGenerators.cpp b/unittest/TestShaderGenerators.cpp index c4eb0cae2f..4008d75606 100644 --- a/unittest/TestShaderGenerators.cpp +++ b/unittest/TestShaderGenerators.cpp @@ -20,19 +20,16 @@ #include "GPU/D3D9/D3DCompilerLoader.h" #include "GPU/D3D9/D3D9ShaderCompiler.h" - bool GenerateFShader(FShaderID id, char *buffer, ShaderLanguage lang, std::string *errorString) { switch (lang) { case ShaderLanguage::HLSL_D3D11: return GenerateFragmentShaderHLSL(id, buffer, ShaderLanguage::HLSL_D3D11, errorString); - case ShaderLanguage::HLSL_DX9: - GenerateFragmentShaderHLSL(id, buffer, ShaderLanguage::HLSL_DX9, errorString); - // TODO: Need a device :( Returning false here so it doesn't get tried. - return false; + case ShaderLanguage::HLSL_D3D9: + return GenerateFragmentShaderHLSL(id, buffer, ShaderLanguage::HLSL_D3D9, errorString); case ShaderLanguage::GLSL_VULKAN: { GLSLShaderCompat compat{}; - compat.SetupForVulkan(); + compat.SetupForShaderLanguage(ShaderLanguage::GLSL_VULKAN); uint64_t uniformMask; return GenerateFragmentShaderGLSL(id, buffer, compat, &uniformMask, errorString); } @@ -40,10 +37,17 @@ bool GenerateFShader(FShaderID id, char *buffer, ShaderLanguage lang, std::strin case ShaderLanguage::GLSL_300: // TODO: Need a device - except that maybe glslang could be used to verify these .... return false; + case ShaderLanguage::HLSL_D3D9_TEST: + { + GLSLShaderCompat compat{}; + compat.SetupForShaderLanguage(ShaderLanguage::HLSL_D3D9); + uint64_t uniformMask; + return GenerateFragmentShaderGLSL(id, buffer, compat, &uniformMask, errorString); + } case ShaderLanguage::HLSL_D3D11_TEST: { GLSLShaderCompat compat{}; - compat.SetupForD3D11(); + compat.SetupForShaderLanguage(ShaderLanguage::HLSL_D3D11); uint64_t uniformMask; return GenerateFragmentShaderGLSL(id, buffer, compat, &uniformMask, errorString); } @@ -56,15 +60,21 @@ bool GenerateVShader(VShaderID id, char *buffer, ShaderLanguage lang, std::strin switch (lang) { case ShaderLanguage::HLSL_D3D11: return GenerateVertexShaderHLSL(id, buffer, ShaderLanguage::HLSL_D3D11, errorString); - case ShaderLanguage::HLSL_DX9: - GenerateVertexShaderHLSL(id, buffer, ShaderLanguage::HLSL_DX9, errorString); - // TODO: Need a device :( Returning false here so it doesn't get tried. - return false; - // return DX9::GenerateFragmentShaderHLSL(id, buffer, ShaderLanguage::HLSL_DX9); + case ShaderLanguage::HLSL_D3D9: + return GenerateVertexShaderHLSL(id, buffer, ShaderLanguage::HLSL_D3D9, errorString); + // return DX9::GenerateFragmentShaderHLSL(id, buffer, ShaderLanguage::HLSL_D3D9); case ShaderLanguage::GLSL_VULKAN: { GLSLShaderCompat compat{}; - compat.SetupForVulkan(); + compat.SetupForShaderLanguage(ShaderLanguage::GLSL_VULKAN); + uint32_t attrMask; + uint64_t uniformMask; + return GenerateVertexShaderGLSL(id, buffer, compat, &attrMask, &uniformMask, errorString); + } + case ShaderLanguage::HLSL_D3D9_TEST: + { + GLSLShaderCompat compat{}; + compat.SetupForShaderLanguage(ShaderLanguage::HLSL_D3D9); uint32_t attrMask; uint64_t uniformMask; return GenerateVertexShaderGLSL(id, buffer, compat, &attrMask, &uniformMask, errorString); @@ -72,7 +82,7 @@ bool GenerateVShader(VShaderID id, char *buffer, ShaderLanguage lang, std::strin case ShaderLanguage::HLSL_D3D11_TEST: { GLSLShaderCompat compat{}; - compat.SetupForD3D11(); + compat.SetupForShaderLanguage(ShaderLanguage::HLSL_D3D11); uint32_t attrMask; uint64_t uniformMask; return GenerateVertexShaderGLSL(id, buffer, compat, &attrMask, &uniformMask, errorString); @@ -82,7 +92,7 @@ bool GenerateVShader(VShaderID id, char *buffer, ShaderLanguage lang, std::strin } } -bool TestCompileShader(const char *buffer, ShaderLanguage lang, bool vertex) { +bool TestCompileShader(const char *buffer, ShaderLanguage lang, bool vertex, std::string *errorMessage) { switch (lang) { case ShaderLanguage::HLSL_D3D11: case ShaderLanguage::HLSL_D3D11_TEST: @@ -90,8 +100,18 @@ bool TestCompileShader(const char *buffer, ShaderLanguage lang, bool vertex) { auto output = CompileShaderToBytecodeD3D11(buffer, strlen(buffer), vertex ? "vs_4_0" : "ps_4_0", 0); return !output.empty(); } - case ShaderLanguage::HLSL_DX9: - return false; + case ShaderLanguage::HLSL_D3D9: + case ShaderLanguage::HLSL_D3D9_TEST: + { + LPD3DBLOB blob = CompileShaderToByteCodeD3D9(buffer, vertex ? "vs_2_0" : "ps_2_0", errorMessage); + if (blob) { + blob->Release(); + return true; + } else { + return false; + } + } + case ShaderLanguage::GLSL_VULKAN: { std::vector spirv; @@ -144,12 +164,13 @@ bool TestShaderGenerators() { LoadD3DCompilerDynamic(); ShaderLanguage languages[] = { - ShaderLanguage::HLSL_D3D11_TEST, + ShaderLanguage::HLSL_D3D9_TEST, + ShaderLanguage::HLSL_D3D9, ShaderLanguage::HLSL_D3D11, + ShaderLanguage::HLSL_D3D9, ShaderLanguage::GLSL_VULKAN, ShaderLanguage::GLSL_140, ShaderLanguage::GLSL_300, - ShaderLanguage::HLSL_DX9, }; const int numLanguages = ARRAY_SIZE(languages); @@ -203,8 +224,9 @@ bool TestShaderGenerators() { // let's try to compile them. for (int j = 0; j < numLanguages; j++) { if (generateSuccess[j]) { - if (!TestCompileShader(buffer[j], languages[j], false)) { - printf("Error compiling fragment shader:\n\n%s\n\n", LineNumberString(buffer[j]).c_str()); + std::string errorMessage; + if (!TestCompileShader(buffer[j], languages[j], false, &errorMessage)) { + printf("Error compiling fragment shader:\n\n%s\n\n%s\n", LineNumberString(buffer[j]).c_str(), errorMessage.c_str()); return false; } successes++; @@ -254,8 +276,9 @@ bool TestShaderGenerators() { // let's try to compile them. for (int j = 0; j < numLanguages; j++) { if (generateSuccess[j]) { - if (!TestCompileShader(buffer[j], languages[j], true)) { - printf("Error compiling vertex shader:\n\n%s\n\n", LineNumberString(buffer[j]).c_str()); + 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++;