Commit 97049c6a by Tibor den Ouden Committed by Geoff Lang

Enhance shader debug output

glGetTranslatedShaderSourceANGLE() returns the glsl code, the initial translated hlsl code, the final translated hlsl code and the disassembly of the generated binary with the compiler configuration. This enhancement is only available if the define ANGLE_GENERATE_SHADER_DEBUG_INFO exists. This define is set in the debug configurations for the Windows platform. BUG=angle:751 Change-Id: I8b15e8b25fbb0c0575a73cc876bf8f1fa7ed142a Reviewed-on: https://chromium-review.googlesource.com/221059Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 5e0c80ad
......@@ -221,7 +221,10 @@ if (is_win) {
]
if (is_debug) {
defines += [ "ANGLE_ENABLE_PERF" ]
defines += [
"ANGLE_ENABLE_PERF",
"ANGLE_GENERATE_SHADER_DEBUG_INFO"
]
}
include_dirs = [ "src/libGLESv2" ]
......
......@@ -63,7 +63,7 @@
<MinimalRebuild>false</MinimalRebuild>
<Optimization>Disabled</Optimization>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;_DEBUG;ANGLE_ENABLE_PERF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;_DEBUG;ANGLE_ENABLE_PERF;ANGLE_GENERATE_SHADER_DEBUG_INFO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<TreatWarningAsError>true</TreatWarningAsError>
......@@ -90,7 +90,7 @@
<ResourceCompile>
<AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Culture>0x0409</Culture>
<PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;_DEBUG;ANGLE_ENABLE_PERF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;_DEBUG;ANGLE_ENABLE_PERF;ANGLE_GENERATE_SHADER_DEBUG_INFO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
......@@ -107,7 +107,7 @@
<MinimalRebuild>false</MinimalRebuild>
<Optimization>Disabled</Optimization>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;ANGLE_GENERATE_SHADER_DEBUG_INFO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<TreatWarningAsError>true</TreatWarningAsError>
......
......@@ -424,6 +424,7 @@
'defines':
[
'ANGLE_ENABLE_PERF',
'ANGLE_GENERATE_SHADER_DEBUG_INFO'
],
'msvs_settings':
{
......
......@@ -117,6 +117,12 @@ void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer);
}
void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const
{
std::string debugInfo(mShader->getDebugInfo());
getSourceImpl(debugInfo, bufSize, length, buffer);
}
void Shader::compile()
{
mCompiled = mShader->compile(mSource);
......
......@@ -73,6 +73,7 @@ class Shader
void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
int getTranslatedSourceLength() const;
void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
void getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const;
void compile();
bool isCompiled() const { return mCompiled; }
......
......@@ -2935,7 +2935,8 @@ void GL_APIENTRY glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize
return;
}
shaderObject->getTranslatedSource(bufsize, length, source);
// Only returns extra info if ANGLE_GENERATE_SHADER_DEBUG_INFO is defined
shaderObject->getTranslatedSourceWithDebugInfo(bufsize, length, source);
}
}
......
......@@ -40,10 +40,21 @@ class ShaderExecutable
return mFunctionBuffer.size();
}
const std::string &getDebugInfo() const
{
return mDebugInfo;
}
void appendDebugInfo(const std::string &info)
{
mDebugInfo += info;
}
private:
DISALLOW_COPY_AND_ASSIGN(ShaderExecutable);
std::vector<uint8_t> mFunctionBuffer;
std::string mDebugInfo;
};
class UniformStorage
......@@ -64,4 +75,4 @@ class UniformStorage
}
#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_
#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE_H_
......@@ -26,6 +26,7 @@ class ShaderImpl
virtual bool compile(const std::string &source) = 0;
virtual const std::string &getInfoLog() const = 0;
virtual const std::string &getTranslatedSource() const = 0;
virtual std::string getDebugInfo() const = 0;
const std::vector<gl::PackedVarying> &getVaryings() const { return mVaryings; }
const std::vector<sh::Uniform> &getUniforms() const { return mUniforms; }
......
......@@ -29,7 +29,8 @@ CompileConfig::CompileConfig(UINT flags, const std::string &name)
HLSLCompiler::HLSLCompiler()
: mD3DCompilerModule(NULL),
mD3DCompileFunc(NULL)
mD3DCompileFunc(NULL),
mD3DDisassembleFunc(NULL)
{
}
......@@ -69,6 +70,9 @@ bool HLSLCompiler::initialize()
mD3DCompileFunc = reinterpret_cast<pD3DCompile>(GetProcAddress(mD3DCompilerModule, "D3DCompile"));
ASSERT(mD3DCompileFunc);
mD3DDisassembleFunc = reinterpret_cast<pD3DDisassemble>(GetProcAddress(mD3DCompilerModule, "D3DDisassemble"));
ASSERT(mD3DDisassembleFunc);
return mD3DCompileFunc != NULL;
}
......@@ -79,12 +83,13 @@ void HLSLCompiler::release()
FreeLibrary(mD3DCompilerModule);
mD3DCompilerModule = NULL;
mD3DCompileFunc = NULL;
mD3DDisassembleFunc = NULL;
}
}
gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile,
const std::vector<CompileConfig> &configs, const D3D_SHADER_MACRO *overrideMacros,
ID3DBlob **outCompiledBlob) const
ID3DBlob **outCompiledBlob, std::string *outDebugInfo) const
{
ASSERT(mD3DCompilerModule && mD3DCompileFunc);
......@@ -107,12 +112,12 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string
if (errorMessage)
{
std::string message = (const char*)errorMessage->GetBufferPointer();
std::string message = reinterpret_cast<const char*>(errorMessage->GetBufferPointer());
SafeRelease(errorMessage);
infoLog.appendSanitized(message.c_str());
TRACE("\n%s", hlsl);
TRACE("\n%s", message);
TRACE("\n%s", hlsl.c_str());
TRACE("\n%s", message.c_str());
if (message.find("error X3531:") != std::string::npos) // "can't unroll loops marked with loop attribute"
{
......@@ -127,6 +132,14 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string
if (SUCCEEDED(result))
{
*outCompiledBlob = binary;
#ifdef ANGLE_GENERATE_SHADER_DEBUG_INFO
(*outDebugInfo) += "// COMPILER INPUT HLSL BEGIN\n\n" + hlsl + "\n// COMPILER INPUT HLSL END\n";
(*outDebugInfo) += "\n\n// ASSEMBLY BEGIN\n\n";
(*outDebugInfo) += "// Compiler configuration: " + configs[i].name + "\n// Flags:\n";
(*outDebugInfo) += "\n" + disassembleBinary(binary) + "\n// ASSEMBLY END\n";
#endif
return gl::Error(GL_NO_ERROR);
}
else
......@@ -151,4 +164,25 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string
return gl::Error(GL_NO_ERROR);
}
std::string HLSLCompiler::disassembleBinary(ID3DBlob *shaderBinary) const
{
// Retrieve disassembly
UINT flags = D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS | D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING;
ID3DBlob *disassembly = NULL;
pD3DDisassemble disassembleFunc = reinterpret_cast<pD3DDisassemble>(mD3DDisassembleFunc);
LPCVOID buffer = shaderBinary->GetBufferPointer();
SIZE_T bufSize = shaderBinary->GetBufferSize();
HRESULT result = disassembleFunc(buffer, bufSize, flags, "", &disassembly);
std::string asmSrc;
if (SUCCEEDED(result))
{
asmSrc = reinterpret_cast<const char*>(disassembly->GetBufferPointer());
}
SafeRelease(disassembly);
return asmSrc;
}
}
......@@ -39,13 +39,16 @@ class HLSLCompiler
// even if no GL errors are returned.
gl::Error compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile,
const std::vector<CompileConfig> &configs, const D3D_SHADER_MACRO *overrideMacros,
ID3DBlob **outCompiledBlob) const;
ID3DBlob **outCompiledBlob, std::string *outDebugInfo) const;
std::string disassembleBinary(ID3DBlob* shaderBinary) const;
private:
DISALLOW_COPY_AND_ASSIGN(HLSLCompiler);
HMODULE mD3DCompilerModule;
pD3DCompile mD3DCompileFunc;
pD3DDisassemble mD3DDisassembleFunc;
};
}
......
......@@ -534,6 +534,27 @@ gl::LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::S
}
}
#ifdef ANGLE_GENERATE_SHADER_DEBUG_INFO
if (usesGeometryShader() && mGeometryExecutable)
{
// Geometry shaders are currently only used internally, so there is no corresponding shader object at the interface level
// For now the geometry shader debug info is pre-pended to the vertex shader, this is a bit of a clutch
vertexShaderD3D->appendDebugInfo("// GEOMETRY SHADER BEGIN\n\n");
vertexShaderD3D->appendDebugInfo(mGeometryExecutable->getDebugInfo());
vertexShaderD3D->appendDebugInfo("\nGEOMETRY SHADER END\n\n\n");
}
if (defaultVertexExecutable)
{
vertexShaderD3D->appendDebugInfo(defaultVertexExecutable->getDebugInfo());
}
if (defaultPixelExecutable)
{
fragmentShaderD3D->appendDebugInfo(defaultPixelExecutable->getDebugInfo());
}
#endif
bool linkSuccess = (defaultVertexExecutable && defaultPixelExecutable && (!usesGeometryShader() || mGeometryExecutable));
return gl::LinkResult(linkSuccess, gl::Error(GL_NO_ERROR));
}
......
......@@ -13,6 +13,28 @@
#include "common/utilities.h"
// Definitions local to the translation unit
namespace
{
const char *GetShaderTypeString(GLenum type)
{
switch (type)
{
case GL_VERTEX_SHADER:
return "VERTEX";
case GL_FRAGMENT_SHADER:
return "FRAGMENT";
default:
UNREACHABLE();
return "";
}
}
}
namespace rx
{
......@@ -69,6 +91,11 @@ const ShaderD3D *ShaderD3D::makeShaderD3D(const ShaderImpl *impl)
return static_cast<const ShaderD3D*>(impl);
}
std::string ShaderD3D::getDebugInfo() const
{
return mDebugInfo + std::string("\n// ") + GetShaderTypeString(mType) + " SHADER END\n";
}
// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
void ShaderD3D::initializeCompiler()
{
......@@ -183,6 +210,7 @@ void ShaderD3D::uncompile()
mInterfaceBlocks.clear();
mActiveAttributes.clear();
mActiveOutputVariables.clear();
mDebugInfo.clear();
}
void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
......@@ -239,6 +267,8 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
ShGetObjectCode(compiler, outputHLSL.data());
#ifdef _DEBUG
// Prefix hlsl shader with commented out glsl shader
// Useful in diagnostics tools like pix which capture the hlsl shaders
std::ostringstream hlslStream;
hlslStream << "// GLSL\n";
hlslStream << "//\n";
......@@ -418,6 +448,15 @@ bool ShaderD3D::compile(const std::string &source)
}
}
#ifdef ANGLE_GENERATE_SHADER_DEBUG_INFO
mDebugInfo += std::string("// ") + GetShaderTypeString(mType) + " SHADER BEGIN\n";
mDebugInfo += "\n// GLSL BEGIN\n\n" + source + "\n\n// GLSL END\n\n\n";
mDebugInfo += "// INITIAL HLSL BEGIN\n\n" + getTranslatedSource() + "\n// INITIAL HLSL END\n\n\n";
// Successive steps will append more info
#else
mDebugInfo += getTranslatedSource();
#endif
return !getTranslatedSource().empty();
}
......
......@@ -32,8 +32,9 @@ class ShaderD3D : public ShaderImpl
static const ShaderD3D *makeShaderD3D(const ShaderImpl *impl);
// ShaderImpl implementation
const std::string &getInfoLog() const { return mInfoLog; }
const std::string &getTranslatedSource() const { return mHlsl; }
virtual const std::string &getInfoLog() const { return mInfoLog; }
virtual const std::string &getTranslatedSource() const { return mHlsl; }
virtual std::string getDebugInfo() const;
// D3D-specific methods
virtual void uncompile();
......@@ -41,6 +42,7 @@ class ShaderD3D : public ShaderImpl
unsigned int getUniformRegister(const std::string &uniformName) const;
unsigned int getInterfaceBlockRegister(const std::string &blockName) const;
int getSemanticIndex(const std::string &attributeName) const;
void appendDebugInfo(const std::string &info) { mDebugInfo += info; }
rx::D3DWorkaroundType getD3DWorkarounds() const;
int getShaderVersion() const { return mShaderVersion; }
......@@ -86,6 +88,7 @@ class ShaderD3D : public ShaderImpl
std::string mHlsl;
std::string mInfoLog;
std::string mDebugInfo;
std::map<std::string, unsigned int> mUniformRegisterMap;
std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
};
......
......@@ -2425,7 +2425,8 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin
D3D_SHADER_MACRO loopMacros[] = { {"ANGLE_ENABLE_LOOP_FLATTEN", "1"}, {0, 0} };
ID3DBlob *binary = NULL;
gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, loopMacros, &binary);
std::string debugInfo;
gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, loopMacros, &binary, &debugInfo);
if (error.isError())
{
return error;
......@@ -2441,12 +2442,18 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin
error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type,
transformFeedbackVaryings, separatedOutputBuffers, outExectuable);
SafeRelease(binary);
if (error.isError())
{
return error;
}
if (!debugInfo.empty())
{
(*outExectuable)->appendDebugInfo(debugInfo);
}
return gl::Error(GL_NO_ERROR);
}
......
......@@ -2927,7 +2927,8 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string
configs.push_back(CompileConfig(flags | D3DCOMPILE_PREFER_FLOW_CONTROL, "prefer flow control"));
ID3DBlob *binary = NULL;
gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, NULL, &binary);
std::string debugInfo;
gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, NULL, &binary, &debugInfo);
if (error.isError())
{
return error;
......@@ -2943,12 +2944,18 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string
error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type,
transformFeedbackVaryings, separatedOutputBuffers, outExectuable);
SafeRelease(binary);
if (error.isError())
{
return error;
}
if (!debugInfo.empty())
{
(*outExectuable)->appendDebugInfo(debugInfo);
}
return gl::Error(GL_NO_ERROR);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment