summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-03-28 01:46:47 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-03-28 01:46:47 +0000
commitcf7ef96b20bf3f91a9ee623f94800d617bc6ff3c (patch)
tree314fc2e3e66b8c6b3d8f41cabd0d0bab78edd751 /Graphics
parentAdded comments (diff)
downloadDiligentCore-cf7ef96b20bf3f91a9ee623f94800d617bc6ff3c.tar.gz
DiligentCore-cf7ef96b20bf3f91a9ee623f94800d617bc6ff3c.zip
Added shader compiler log output
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngine/interface/Shader.h7
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions.fxh1
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh1
-rw-r--r--Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp79
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp47
5 files changed, 85 insertions, 50 deletions
diff --git a/Graphics/GraphicsEngine/interface/Shader.h b/Graphics/GraphicsEngine/interface/Shader.h
index 15df194d..4cac8e82 100644
--- a/Graphics/GraphicsEngine/interface/Shader.h
+++ b/Graphics/GraphicsEngine/interface/Shader.h
@@ -258,6 +258,13 @@ struct ShaderCreationAttribs
/// Shader source language. See Diligent::SHADER_SOURCE_LANGUAGE.
SHADER_SOURCE_LANGUAGE SourceLanguage = SHADER_SOURCE_LANGUAGE_DEFAULT;
+
+ /// Memory address where pointer to the compiler messages data blob will be written
+
+ /// The buffer contains two null-terminated strings. The first one is the compiler
+ /// output message. The second one is the full shader source code including definitions added
+ /// by the engine. Data blob object must be released by the client.
+ IDataBlob **ppCompilerOutput = nullptr;
};
diff --git a/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions.fxh b/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions.fxh
index df6edfa0..44ed3641 100644
--- a/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions.fxh
+++ b/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions.fxh
@@ -74,3 +74,4 @@ float2x2 MatrixFromRows(float2 row0, float2 row1)
}
#endif // _HLSL_DEFINITIONS_
+
diff --git a/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh b/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh
index 3eb36067..72bfc1f8 100644
--- a/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh
+++ b/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh
@@ -74,3 +74,4 @@
"}\n"
"\n"
"#endif // _HLSL_DEFINITIONS_\n"
+"\n"
diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp
index 31332e3e..5820245b 100644
--- a/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp
+++ b/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp
@@ -57,7 +57,7 @@ public:
return E_FAIL;
}
- RefCntAutoPtr<Diligent::IDataBlob> pFileData( MakeNewRCObj<Diligent::DataBlobImpl>()(0) );
+ RefCntAutoPtr<IDataBlob> pFileData( MakeNewRCObj<DataBlobImpl>()(0) );
pSourceStream->Read( pFileData );
*ppData = pFileData->GetDataPtr();
*pBytes = static_cast<UINT>( pFileData->GetSize() );
@@ -75,7 +75,7 @@ public:
private:
IShaderSourceInputStreamFactory *m_pStreamFactory;
- std::unordered_map< LPCVOID, RefCntAutoPtr<Diligent::IDataBlob> > m_DataBlobs;
+ std::unordered_map< LPCVOID, RefCntAutoPtr<IDataBlob> > m_DataBlobs;
};
HRESULT CompileShader( const char* Source,
@@ -83,7 +83,8 @@ HRESULT CompileShader( const char* Source,
const D3D_SHADER_MACRO* pDefines,
IShaderSourceInputStreamFactory *pIncludeStreamFactory,
LPCSTR profile,
- ID3DBlob **ppBlobOut )
+ ID3DBlob **ppBlobOut,
+ ID3DBlob **ppCompilerOutput)
{
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
@@ -98,37 +99,25 @@ HRESULT CompileShader( const char* Source,
// dwShaderFlags |= D3D10_SHADER_OPTIMIZATION_LEVEL3;
#endif
HRESULT hr;
- do
- {
- CComPtr<ID3DBlob> errors;
+// do
+// {
auto SourceLen = strlen(Source);
D3DIncludeImpl IncludeImpl(pIncludeStreamFactory);
- hr = D3DCompile( Source, SourceLen, NULL, pDefines, &IncludeImpl, strFunctionName, profile, dwShaderFlags, 0, ppBlobOut, &errors );
+ hr = D3DCompile( Source, SourceLen, NULL, pDefines, &IncludeImpl, strFunctionName, profile, dwShaderFlags, 0, ppBlobOut, ppCompilerOutput);
- if( FAILED(hr) || errors )
- {
- std::wstringstream errorss;
- ComErrorDesc ErrDesc(hr);
- if( FAILED(hr) )
- Diligent::FormatMsg( errorss, "Failed to compile shader\n" );
- else
- Diligent::FormatMsg( errorss, "Shader compiler output:\n" );
- Diligent::FormatMsg( errorss, ErrDesc.Get(), "\n" );
- if( errors )
- Diligent::FormatMsg( errorss, (char*)errors->GetBufferPointer() );
- auto ErrorDesc = errorss.str();
- OutputDebugStringW( ErrorDesc.c_str() );
- if( FAILED(hr)
-#if PLATFORM_WIN32
- && IDRETRY != MessageBoxW( NULL, ErrorDesc.c_str() , L"FX Error", MB_ICONERROR | (Source == nullptr ? MB_ABORTRETRYIGNORE : 0) )
-#endif
- )
- {
- break;
- }
- }
- } while( FAILED(hr) );
+// if( FAILED(hr) || errors )
+// {
+// if( FAILED(hr)
+//#if PLATFORM_WIN32
+// && IDRETRY != MessageBoxW( NULL, L"Failed to compile shader", L"FX Error", MB_ICONERROR | (Source == nullptr ? MB_ABORTRETRYIGNORE : 0) )
+//#endif
+// )
+// {
+// break;
+// }
+// }
+// } while( FAILED(hr) );
return hr;
}
@@ -178,7 +167,7 @@ ShaderD3DBase::ShaderD3DBase(const ShaderCreationAttribs &CreationAttribs)
VERIFY(CreationAttribs.pShaderSourceStreamFactory, "Input stream factory is null");
RefCntAutoPtr<IFileStream> pSourceStream;
CreationAttribs.pShaderSourceStreamFactory->CreateInputStream(CreationAttribs.FilePath, &pSourceStream);
- RefCntAutoPtr<Diligent::IDataBlob> pFileData(MakeNewRCObj<Diligent::DataBlobImpl>()(0));
+ RefCntAutoPtr<IDataBlob> pFileData(MakeNewRCObj<DataBlobImpl>()(0));
if (pSourceStream == nullptr)
LOG_ERROR_AND_THROW("Failed to open shader source file");
pSourceStream->Read(pFileData);
@@ -201,8 +190,32 @@ ShaderD3DBase::ShaderD3DBase(const ShaderCreationAttribs &CreationAttribs)
}
VERIFY(CreationAttribs.EntryPoint != nullptr, "Entry point must not be null");
- CHECK_D3D_RESULT_THROW(CompileShader(ShaderSource.c_str(), CreationAttribs.EntryPoint, pDefines, CreationAttribs.pShaderSourceStreamFactory, strShaderProfile.c_str(), &m_pShaderByteCode),
- "Failed to compile the shader");
+ CComPtr<ID3DBlob> errors;
+ auto hr = CompileShader(ShaderSource.c_str(), CreationAttribs.EntryPoint, pDefines, CreationAttribs.pShaderSourceStreamFactory, strShaderProfile.c_str(), &m_pShaderByteCode, &errors);
+
+ const char *CompilerMsg = errors ? reinterpret_cast<const char*>(errors->GetBufferPointer()) : nullptr;
+ if(CompilerMsg != nullptr && CreationAttribs.ppCompilerOutput != nullptr)
+ {
+ auto ErrorMsgLen = strlen(CompilerMsg);
+ auto *pOutputDataBlob = MakeNewRCObj<DataBlobImpl>()(ErrorMsgLen + 1 + ShaderSource.length() + 1);
+ char* DataPtr = reinterpret_cast<char*>(pOutputDataBlob->GetDataPtr());
+ memcpy(DataPtr, CompilerMsg, ErrorMsgLen+1);
+ memcpy(DataPtr + ErrorMsgLen + 1, ShaderSource.data(), ShaderSource.length() + 1);
+ pOutputDataBlob->QueryInterface(IID_DataBlob, reinterpret_cast<IObject**>(CreationAttribs.ppCompilerOutput));
+ }
+
+ if(FAILED(hr))
+ {
+ ComErrorDesc ErrDesc(hr);
+ if(CreationAttribs.ppCompilerOutput != nullptr)
+ {
+ LOG_ERROR_AND_THROW("Failed to compile D3D shader (", ErrDesc.Get(), ").");
+ }
+ else
+ {
+ LOG_ERROR_AND_THROW("Failed to compile D3D shader (", ErrDesc.Get(), "):\n", CompilerMsg != nullptr ? CompilerMsg : "<no compiler log available>");
+ }
+ }
}
else if (CreationAttribs.ByteCode)
{
diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp
index 58106b5e..dad50a0c 100644
--- a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp
@@ -33,8 +33,8 @@ using namespace Diligent;
namespace Diligent
{
-ShaderGLImpl::ShaderGLImpl(IReferenceCounters *pRefCounters, RenderDeviceGLImpl *pDeviceGL, const ShaderCreationAttribs &ShaderCreationAttribs, bool bIsDeviceInternal) :
- TShaderBase( pRefCounters, pDeviceGL, ShaderCreationAttribs.Desc, bIsDeviceInternal ),
+ShaderGLImpl::ShaderGLImpl(IReferenceCounters *pRefCounters, RenderDeviceGLImpl *pDeviceGL, const ShaderCreationAttribs &CreationAttribs, bool bIsDeviceInternal) :
+ TShaderBase( pRefCounters, pDeviceGL, CreationAttribs.Desc, bIsDeviceInternal ),
m_GlProgObj(false),
m_GLShaderObj( false, GLObjectWrappers::GLShaderObjCreateReleaseHelper( GetGLShaderType( m_Desc.ShaderType ) ) )
{
@@ -196,9 +196,9 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters *pRefCounters, RenderDeviceGLImpl
Lenghts.push_back( static_cast<GLint>( strlen(ShaderTypeDefine) ) );
String UserDefines;
- if( ShaderCreationAttribs.Macros != nullptr)
+ if( CreationAttribs.Macros != nullptr)
{
- auto *pMacro = ShaderCreationAttribs.Macros;
+ auto *pMacro = CreationAttribs.Macros;
while( pMacro->Name != nullptr && pMacro->Definition != nullptr )
{
UserDefines += "#define ";
@@ -213,7 +213,7 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters *pRefCounters, RenderDeviceGLImpl
}
RefCntAutoPtr<IDataBlob> pFileData(MakeNewRCObj<DataBlobImpl>()(0));
- auto ShaderSource = ShaderCreationAttribs.Source;
+ auto ShaderSource = CreationAttribs.Source;
GLuint SourceLen = 0;
if( ShaderSource )
{
@@ -221,9 +221,9 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters *pRefCounters, RenderDeviceGLImpl
}
else
{
- VERIFY(ShaderCreationAttribs.pShaderSourceStreamFactory, "Input stream factory is null");
+ VERIFY(CreationAttribs.pShaderSourceStreamFactory, "Input stream factory is null");
RefCntAutoPtr<IFileStream> pSourceStream;
- ShaderCreationAttribs.pShaderSourceStreamFactory->CreateInputStream( ShaderCreationAttribs.FilePath, &pSourceStream );
+ CreationAttribs.pShaderSourceStreamFactory->CreateInputStream( CreationAttribs.FilePath, &pSourceStream );
if (pSourceStream == nullptr)
LOG_ERROR_AND_THROW("Failed to open shader source file");
@@ -233,19 +233,19 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters *pRefCounters, RenderDeviceGLImpl
}
String ConvertedSource;
- if( ShaderCreationAttribs.SourceLanguage == SHADER_SOURCE_LANGUAGE_HLSL )
+ if( CreationAttribs.SourceLanguage == SHADER_SOURCE_LANGUAGE_HLSL )
{
// Convert HLSL to GLSL
const auto &Converter = HLSL2GLSLConverterImpl::GetInstance();
HLSL2GLSLConverterImpl::ConversionAttribs Attribs;
- Attribs.pSourceStreamFactory = ShaderCreationAttribs.pShaderSourceStreamFactory;
- Attribs.ppConversionStream = ShaderCreationAttribs.ppConversionStream;
+ Attribs.pSourceStreamFactory = CreationAttribs.pShaderSourceStreamFactory;
+ Attribs.ppConversionStream = CreationAttribs.ppConversionStream;
Attribs.HLSLSource = ShaderSource;
Attribs.NumSymbols = SourceLen;
- Attribs.EntryPoint = ShaderCreationAttribs.EntryPoint;
- Attribs.ShaderType = ShaderCreationAttribs.Desc.ShaderType;
+ Attribs.EntryPoint = CreationAttribs.EntryPoint;
+ Attribs.ShaderType = CreationAttribs.Desc.ShaderType;
Attribs.IncludeDefinitions = true;
- Attribs.InputFileName = ShaderCreationAttribs.FilePath;
+ Attribs.InputFileName = CreationAttribs.FilePath;
ConvertedSource = Converter.Convert(Attribs);
ShaderSource = ConvertedSource.c_str();
@@ -284,17 +284,15 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters *pRefCounters, RenderDeviceGLImpl
for(const auto *str : ShaderStrings)
FullSource.append(str);
- LOG_INFO_MESSAGE("Failed shader full source: \n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n", FullSource, "\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
-
std::stringstream ErrorMsgSS;
- ErrorMsgSS << "Failed to compile shader file \""<< (ShaderCreationAttribs.FilePath != nullptr ? ShaderCreationAttribs.FilePath : "") << '\"' << std::endl;
+ ErrorMsgSS << "Failed to compile shader file \""<< (CreationAttribs.FilePath != nullptr ? CreationAttribs.FilePath : "") << '\"' << std::endl;
int infoLogLen = 0;
// The function glGetShaderiv() tells how many bytes to allocate; the length includes the NULL terminator.
glGetShaderiv(ShaderObj, GL_INFO_LOG_LENGTH, &infoLogLen);
+ std::vector<GLchar> infoLog(infoLogLen);
if (infoLogLen > 0)
{
- std::vector<GLchar> infoLog(infoLogLen);
int charsWritten = 0;
// Get the log. infoLogLen is the size of infoLog. This tells OpenGL how many bytes at maximum it will write
// charsWritten is a return value, specifying how many bytes it actually wrote. One may pass NULL if he
@@ -303,6 +301,21 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters *pRefCounters, RenderDeviceGLImpl
VERIFY(charsWritten == infoLogLen-1, "Unexpected info log length");
ErrorMsgSS << "InfoLog:" << std::endl << infoLog.data() << std::endl;
}
+
+ if (CreationAttribs.ppCompilerOutput != nullptr)
+ {
+ auto *pOutputDataBlob = MakeNewRCObj<DataBlobImpl>()(infoLogLen + FullSource.length() + 1);
+ char* DataPtr = reinterpret_cast<char*>(pOutputDataBlob->GetDataPtr());
+ memcpy(DataPtr, !infoLog.empty() ? infoLog.data() : nullptr, infoLogLen);
+ memcpy(DataPtr + infoLogLen, FullSource.data(), FullSource.length() + 1);
+ pOutputDataBlob->QueryInterface(IID_DataBlob, reinterpret_cast<IObject**>(CreationAttribs.ppCompilerOutput));
+ }
+ else
+ {
+ // Dump full source code to debug output
+ LOG_INFO_MESSAGE("Failed shader full source: \n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n", FullSource, "\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
+ }
+
LOG_ERROR_AND_THROW(ErrorMsgSS.str().c_str());
}