diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-03-28 01:46:47 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-03-28 01:46:47 +0000 |
| commit | cf7ef96b20bf3f91a9ee623f94800d617bc6ff3c (patch) | |
| tree | 314fc2e3e66b8c6b3d8f41cabd0d0bab78edd751 /Graphics | |
| parent | Added comments (diff) | |
| download | DiligentCore-cf7ef96b20bf3f91a9ee623f94800d617bc6ff3c.tar.gz DiligentCore-cf7ef96b20bf3f91a9ee623f94800d617bc6ff3c.zip | |
Added shader compiler log output
Diffstat (limited to 'Graphics')
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()); } |
