D3D11: Improve compilation error reporting

This commit is contained in:
Henrik Rydgård
2026-05-25 21:27:32 +02:00
parent 7309c477d1
commit 886d9c255b
3 changed files with 43 additions and 14 deletions

View File

@@ -22,7 +22,7 @@
using namespace Microsoft::WRL;
std::vector<uint8_t> CompileShaderToBytecodeD3D11(const char *code, size_t codeSize, const char *target, UINT flags) {
std::vector<uint8_t> CompileShaderToBytecodeD3D11(const char *code, size_t codeSize, const char *target, UINT flags, std::string *errorMessage) {
ComPtr<ID3DBlob> compiledCode;
ComPtr<ID3DBlob> errorMsgs;
HRESULT result = ptr_D3DCompile(code, codeSize, nullptr, nullptr, nullptr, "main", target, flags, 0, &compiledCode, &errorMsgs);
@@ -45,6 +45,9 @@ std::vector<uint8_t> CompileShaderToBytecodeD3D11(const char *code, size_t codeS
}
} else {
ERROR_LOG(Log::G3D, "%s: %s\n\n%s", "errors", errors.c_str(), numberedCode.c_str());
if (errorMessage) {
*errorMessage = errors;
}
OutputDebugStringA(errors.c_str());
OutputDebugStringA(numberedCode.c_str());
}
@@ -63,9 +66,14 @@ HRESULT CreateVertexShaderD3D11(ID3D11Device *device, const char *code, size_t c
if (ppVertexShader)
*ppVertexShader = nullptr;
const char *profile = featureLevel <= D3D_FEATURE_LEVEL_9_3 ? "vs_4_0_level_9_1" : "vs_4_0";
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, profile, flags);
if (byteCode.empty())
std::string errorMessage;
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, profile, flags, &errorMessage);
if (byteCode.empty()) {
if (!errorMessage.empty()) {
ERROR_LOG(Log::G3D, "%s", errorMessage.c_str());
}
return S_FALSE;
}
auto hr = device->CreateVertexShader(byteCode.data(), byteCode.size(), nullptr, ppVertexShader);
if (byteCodeOut)
@@ -77,9 +85,14 @@ HRESULT CreatePixelShaderD3D11(ID3D11Device *device, const char *code, size_t co
if (ppPixelShader)
*ppPixelShader = nullptr;
const char *profile = featureLevel <= D3D_FEATURE_LEVEL_9_3 ? "ps_4_0_level_9_1" : "ps_4_0";
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, profile, flags);
if (byteCode.empty())
std::string errorMessage;
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, profile, flags, &errorMessage);
if (byteCode.empty()) {
if (!errorMessage.empty()) {
ERROR_LOG(Log::G3D, "%s", errorMessage.c_str());
}
return S_FALSE;
}
return device->CreatePixelShader(byteCode.data(), byteCode.size(), nullptr, ppPixelShader);
}
@@ -89,9 +102,14 @@ HRESULT CreateComputeShaderD3D11(ID3D11Device *device, const char *code, size_t
*ppComputeShader = nullptr;
if (featureLevel <= D3D_FEATURE_LEVEL_9_3)
return S_FALSE;
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, "cs_4_0", flags);
if (byteCode.empty())
std::string errorMessage;
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, "cs_4_0", flags, &errorMessage);
if (byteCode.empty()) {
if (!errorMessage.empty()) {
ERROR_LOG(Log::G3D, "%s", errorMessage.c_str());
}
return S_FALSE;
}
return device->CreateComputeShader(byteCode.data(), byteCode.size(), nullptr, ppComputeShader);
}
@@ -101,9 +119,14 @@ HRESULT CreateGeometryShaderD3D11(ID3D11Device *device, const char *code, size_t
*ppGeometryShader = nullptr;
if (featureLevel <= D3D_FEATURE_LEVEL_9_3)
return S_FALSE;
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, "gs_5_0", flags);
if (byteCode.empty())
std::string errorMessage;
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, "gs_5_0", flags, &errorMessage);
if (byteCode.empty()) {
if (!errorMessage.empty()) {
ERROR_LOG(Log::G3D, "%s", errorMessage.c_str());
}
return S_FALSE;
}
return device->CreateGeometryShader(byteCode.data(), byteCode.size(), nullptr, ppGeometryShader);
}

View File

@@ -73,7 +73,7 @@ private:
bool nextMapDiscard_ = false;
};
std::vector<uint8_t> CompileShaderToBytecodeD3D11(const char *code, size_t codeSize, const char *target, UINT flags);
std::vector<uint8_t> CompileShaderToBytecodeD3D11(const char *code, size_t codeSize, const char *target, UINT flags, std::string *errorMessage = nullptr);
HRESULT CreateVertexShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, std::vector<uint8_t> *byteCodeOut, D3D_FEATURE_LEVEL featureLevel, UINT flags, ID3D11VertexShader **);
HRESULT CreatePixelShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags, ID3D11PixelShader **);

View File

@@ -139,9 +139,14 @@ bool TestCompileShader(const char *buffer, ShaderLanguage lang, ShaderStage stag
case ShaderStage::Vertex: programType = "vs_4_0"; break;
case ShaderStage::Fragment: programType = "ps_4_0"; break;
case ShaderStage::Geometry: programType = "gs_4_0"; break;
default: return false;
default:
*errorMessage = "Unknown shader stage";
return false;
}
auto output = CompileShaderToBytecodeD3D11(buffer, strlen(buffer), programType, 0, errorMessage);
if (output.empty() && errorMessage->empty()) {
*errorMessage = "Error compiling HLSL shader: bytecode empty";
}
auto output = CompileShaderToBytecodeD3D11(buffer, strlen(buffer), programType, 0);
return !output.empty();
}
#endif
@@ -153,6 +158,7 @@ bool TestCompileShader(const char *buffer, ShaderLanguage lang, ShaderStage stag
case ShaderLanguage::GLSL_3xx:
return GLSLtoSPV(StageToVulkan(stage), buffer, GLSLVariant::GLES300, spirv, errorMessage);
default:
*errorMessage = "Unknown shader language";
return false;
}
}
@@ -422,7 +428,7 @@ bool TestVertexShaders() {
if (generateSuccess[j]) {
std::string errorMessage;
if (!TestCompileShader(buffer[j], languages[j], ShaderStage::Vertex, &errorMessage)) {
printf("Error compiling vertex shader %d:\n\n%s\n\n%s\n", (int)j, LineNumberString(buffer[j]).c_str(), errorMessage.c_str());
printf("Error compiling vertex shader %d:\n\n%s\n\nERROR: %s\n\n(end of error)\n\n", (int)j, LineNumberString(buffer[j]).c_str(), errorMessage.c_str());
for (int i = 0; i < numLanguages; i++) {
delete[] buffer[i];
}
@@ -496,7 +502,7 @@ bool TestFragmentShaders() {
if (generateSuccess[j]) {
std::string errorMessage;
if (!TestCompileShader(buffer[j], languages[j], ShaderStage::Fragment, &errorMessage)) {
printf("Error compiling fragment shader:\n\n%s\n\n%s\n", LineNumberString(buffer[j]).c_str(), errorMessage.c_str());
printf("Error compiling fragment shader %d:\n\n%s\n\nERROR: %s\n\n(end of error)\n\n", (int)j, LineNumberString(buffer[j]).c_str(), errorMessage.c_str());
for (int i = 0; i < numLanguages; i++) {
delete[] buffer[i];
}