Set up the test for D3D9, start fixing stuff.

This commit is contained in:
Henrik Rydgård 2020-10-30 10:22:40 +01:00
parent b070ed45e9
commit af4d6e7642
20 changed files with 236 additions and 240 deletions

View File

@ -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

View File

@ -1,6 +1,7 @@
#pragma once
#include "Common/CommonWindows.h"
#include "Common/GPU/D3D9/D3DCompilerLoader.h"
#include <initguid.h>
#include <string>
@ -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);

View File

@ -279,7 +279,7 @@ void GLQueueRunner::RunInitSteps(const std::vector<GLRInitStep> &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

View File

@ -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:

View File

@ -372,7 +372,7 @@ Draw::Pipeline *PresentationCommon::CreatePipeline(std::vector<Draw::ShaderModul
Semantic pos = SEM_POSITION;
Semantic tc = SEM_TEXCOORD0;
// Shader translation marks these both as "TEXCOORDs" on HLSL...
if (postShader && (lang_ == HLSL_D3D11 || lang_ == HLSL_DX9)) {
if (postShader && (lang_ == HLSL_D3D11 || lang_ == HLSL_D3D9)) {
pos = SEM_TEXCOORD0;
tc = SEM_TEXCOORD1;
}
@ -488,7 +488,7 @@ Draw::ShaderModule *PresentationCommon::CompileShaderModule(Draw::ShaderStage st
case GLSL_VULKAN:
mappedLang = Draw::ShaderLanguage::GLSL_VULKAN;
break;
case HLSL_DX9:
case HLSL_D3D9:
mappedLang = Draw::ShaderLanguage::HLSL_D3D9;
break;
case HLSL_D3D11:

View File

@ -102,45 +102,46 @@ void init_resources(TBuiltInResource &Resources) {
Resources.limits.generalConstantMatrixVectorIndexing = 1;
}
void GLSLShaderCompat::SetupForVulkan() {
fragColor0 = "fragColor0";
fragColor1 = "fragColor1";
varying_fs = "in";
varying_vs = "out";
attribute = "in";
bitwiseOps = true;
framebufferFetchExtension = nullptr;
gles = false;
glslES30 = true;
glslVersionNumber = 450;
lastFragData = nullptr;
texture = "texture";
texelFetch = "texelFetch";
d3d11 = false;
vulkan = true;
forceMatrix4x4 = false;
coefsFromBuffers = true;
inPrefix = "";
void GLSLShaderCompat::SetupForShaderLanguage(ShaderLanguage lang) {
shaderLanguage = lang;
switch (lang) {
case GLSL_VULKAN:
fragColor0 = "fragColor0";
fragColor1 = "fragColor1";
varying_fs = "in";
varying_vs = "out";
attribute = "in";
bitwiseOps = true;
framebufferFetchExtension = nullptr;
gles = false;
glslES30 = true;
glslVersionNumber = 450;
lastFragData = nullptr;
texture = "texture";
texelFetch = "texelFetch";
forceMatrix4x4 = false;
coefsFromBuffers = true;
inPrefix = "";
break;
case HLSL_D3D9:
case HLSL_D3D11:
fragColor0 = "outfragment.target";
fragColor1 = "outfragment.target1";
varying_fs = "in";
varying_vs = "out";
attribute = "in";
bitwiseOps = true;
framebufferFetchExtension = nullptr;
gles = false;
glslES30 = true;
glslVersionNumber = 0;
lastFragData = nullptr;
texture = "texture";
texelFetch = "texelFetch";
forceMatrix4x4 = false;
coefsFromBuffers = true;
inPrefix = "In.";
break;
}
}
void GLSLShaderCompat::SetupForD3D11() {
fragColor0 = "outfragment.target";
fragColor1 = "outfragment.target1";
varying_fs = "in";
varying_vs = "out";
attribute = "in";
bitwiseOps = true;
framebufferFetchExtension = nullptr;
gles = false;
glslES30 = true;
glslVersionNumber = 450;
lastFragData = nullptr;
texture = "texture";
texelFetch = "texelFetch";
vulkan = false;
d3d11 = true;
forceMatrix4x4 = false;
coefsFromBuffers = true;
inPrefix = "In.";
}

View File

@ -25,15 +25,20 @@ namespace Draw {
}
enum ShaderLanguage {
GLSL_140,
GLSL_140, // really covers a lot more. This set of languages is not good.
GLSL_300,
GLSL_VULKAN,
HLSL_DX9,
HLSL_D3D9,
HLSL_D3D11,
HLSL_D3D11_TEST, // temporary
HLSL_D3D9_TEST, // temporary
};
inline bool ShaderLanguageIsOpenGL(ShaderLanguage lang) {
return lang == GLSL_140 || lang == GLSL_300;
}
enum DebugShaderType {
SHADER_TYPE_VERTEX = 0,
SHADER_TYPE_FRAGMENT = 1,
@ -142,10 +147,8 @@ enum DoLightComputation {
struct GLSLShaderCompat {
int glslVersionNumber;
ShaderLanguage shaderLanguage;
bool gles;
bool vulkan;
bool d3d11;
bool d3d9;
const char *varying_fs;
const char *varying_vs;
const char *attribute;
@ -155,14 +158,13 @@ struct GLSLShaderCompat {
const char *texelFetch;
const char *lastFragData;
const char *framebufferFetchExtension;
const char *inPrefix;
const char *inPrefix = "";
bool glslES30;
bool bitwiseOps;
bool forceMatrix4x4;
bool coefsFromBuffers;
void SetupForVulkan();
void SetupForD3D11();
void SetupForShaderLanguage(ShaderLanguage lang);
};
// PSP vertex format.

View File

@ -126,7 +126,7 @@ float u_video : register(c5);
// Should probably do it in the source shader instead and then back translate to old style GLSL, but
// SPIRV-Cross currently won't compile with the Android NDK so I can't be bothered.
std::string Postprocess(std::string code, ShaderLanguage lang, Draw::ShaderStage stage) {
if (lang != HLSL_D3D11 && lang != HLSL_DX9)
if (lang != HLSL_D3D11 && lang != HLSL_D3D9)
return code;
std::stringstream out;
@ -134,18 +134,18 @@ std::string Postprocess(std::string code, ShaderLanguage lang, Draw::ShaderStage
// Output the uniform buffer.
if (lang == HLSL_D3D11)
out << cbufferDecl;
else if (lang == HLSL_DX9)
else if (lang == HLSL_D3D9)
out << d3d9RegisterDecl;
// Alright, now let's go through it line by line and zap the single uniforms.
std::string line;
std::stringstream instream(code);
while (std::getline(instream, line)) {
if (line == "uniform sampler2D sampler0;" && lang == HLSL_DX9) {
if (line == "uniform sampler2D sampler0;" && lang == HLSL_D3D9) {
out << "sampler2D sampler0 : register(s0);\n";
continue;
}
if (line == "uniform sampler2D sampler1;" && lang == HLSL_DX9) {
if (line == "uniform sampler2D sampler1;" && lang == HLSL_D3D9) {
out << "sampler2D sampler1 : register(s1);\n";
continue;
}
@ -291,7 +291,7 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShade
switch (destLang) {
#ifdef _WIN32
case HLSL_DX9:
case HLSL_D3D9:
{
spirv_cross::CompilerHLSL hlsl(spirv);
spirv_cross::CompilerHLSL::Options options{};

View File

@ -52,10 +52,10 @@ VS_OUT main(VS_IN input) {
}
)";
DepalShaderCacheDX9::DepalShaderCacheDX9(Draw::DrawContext *draw) : vertexShader_(nullptr) {
DepalShaderCacheDX9::DepalShaderCacheDX9(Draw::DrawContext *draw) {
device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(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;

View File

@ -54,9 +54,9 @@ public:
private:
LPDIRECT3DDEVICE9 device_;
LPDIRECT3DVERTEXSHADER9 vertexShader_;
LPDIRECT3DVERTEXSHADER9 vertexShader_ = nullptr;
std::map<u32, DepalShaderDX9 *> cache_;
std::map<u32, DepalTextureDX9 *> texCache_;
};
} // namespace
} // namespace

View File

@ -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");
}

View File

@ -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;
}

View File

@ -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_);

View File

@ -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!");

View File

@ -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");

View File

@ -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<vec4> 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");
}

View File

@ -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;

View File

@ -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");
}

View File

@ -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_);

View File

@ -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<uint32_t> 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++;