Skip to content

Commit

Permalink
ShaderGLImpl::LinkProgram: throw an exception if linkage fails (close #…
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Sep 14, 2023
1 parent 4bc659a commit 7ad2914
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class PipelineStateGLImpl final : public PipelineStateBase<EngineGLImplTraits>
GLObjectWrappers::GLPipelineObj& GetGLProgramPipeline(GLContext::NativeGLContextType Context);

template <typename PSOCreateInfoType>
void InitInternalObjects(const PSOCreateInfoType& CreateInfo, const TShaderStages& ShaderStages);
void InitInternalObjects(const PSOCreateInfoType& CreateInfo, const TShaderStages& ShaderStages) noexcept(false);

void InitResourceLayout(PSO_CREATE_INTERNAL_FLAGS InternalFlags,
const TShaderStages& ShaderStages,
Expand Down
4 changes: 2 additions & 2 deletions Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class ShaderGLImpl final : public ShaderBase<EngineGLImplTraits>
RenderDeviceGLImpl* pDeviceGL,
const ShaderCreateInfo& ShaderCI,
const CreateInfo& GLShaderCI,
bool bIsDeviceInternal = false);
bool bIsDeviceInternal = false) noexcept(false);
~ShaderGLImpl();

virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final;
Expand All @@ -72,7 +72,7 @@ class ShaderGLImpl final : public ShaderBase<EngineGLImplTraits>
/// Implementation of IShaderGL::GetGLShaderHandle() in OpenGL backend.
virtual GLuint DILIGENT_CALL_TYPE GetGLShaderHandle() const override final { return m_GLShaderObj; }

static GLObjectWrappers::GLProgramObj LinkProgram(ShaderGLImpl* const* ppShaders, Uint32 NumShaders, bool IsSeparableProgram);
static GLObjectWrappers::GLProgramObj LinkProgram(ShaderGLImpl* const* ppShaders, Uint32 NumShaders, bool IsSeparableProgram) noexcept(false);

const std::shared_ptr<const ShaderResourcesGL>& GetShaderResources() const { return m_pShaderResources; }

Expand Down
6 changes: 3 additions & 3 deletions Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ void PipelineStateGLImpl::InitResourceLayout(PSO_CREATE_INTERNAL_FLAGS InternalF
}

template <typename PSOCreateInfoType>
void PipelineStateGLImpl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, const TShaderStages& ShaderStages)
void PipelineStateGLImpl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, const TShaderStages& ShaderStages) noexcept(false)
{
const auto& DeviceInfo = GetDevice()->GetDeviceInfo();
VERIFY(DeviceInfo.Type != RENDER_DEVICE_TYPE_UNDEFINED, "Device info is not initialized");
Expand Down Expand Up @@ -276,13 +276,13 @@ void PipelineStateGLImpl::InitInternalObjects(const PSOCreateInfoType& CreateInf
for (size_t i = 0; i < ShaderStages.size(); ++i)
{
auto* pShaderGL = ShaderStages[i];
m_GLPrograms[i] = GLProgramObj{ShaderGLImpl::LinkProgram(&ShaderStages[i], 1, true)};
m_GLPrograms[i] = GLProgramObj{ShaderGLImpl::LinkProgram(&ShaderStages[i], 1, true)}; // May throw
m_ShaderTypes[i] = pShaderGL->GetDesc().ShaderType;
}
}
else
{
m_GLPrograms[0] = ShaderGLImpl::LinkProgram(ShaderStages.data(), static_cast<Uint32>(ShaderStages.size()), false);
m_GLPrograms[0] = ShaderGLImpl::LinkProgram(ShaderStages.data(), static_cast<Uint32>(ShaderStages.size()), false); // May throw
m_ShaderTypes[0] = ActiveStages;

m_GLPrograms[0].SetName(m_Desc.Name);
Expand Down
11 changes: 5 additions & 6 deletions Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters,
RenderDeviceGLImpl* pDeviceGL,
const ShaderCreateInfo& ShaderCI,
const CreateInfo& GLShaderCI,
bool bIsDeviceInternal) :
bool bIsDeviceInternal) noexcept(false) :
// clang-format off
TShaderBase
{
Expand Down Expand Up @@ -179,7 +179,7 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters,
if (DeviceInfo.Features.SeparablePrograms /*&& (ShaderCI.CompileFlags & SHADER_COMPILE_FLAG_SKIP_REFLECTION) == 0*/)
{
ShaderGLImpl* const ThisShader[] = {this};
GLObjectWrappers::GLProgramObj Program = LinkProgram(ThisShader, 1, true);
GLObjectWrappers::GLProgramObj Program = LinkProgram(ThisShader, 1, true); // May throw

auto pImmediateCtx = m_pDevice->GetImmediateContext(0);
VERIFY_EXPR(pImmediateCtx);
Expand All @@ -206,11 +206,11 @@ ShaderGLImpl::~ShaderGLImpl()
IMPLEMENT_QUERY_INTERFACE2(ShaderGLImpl, IID_ShaderGL, IID_InternalImpl, TShaderBase)


GLObjectWrappers::GLProgramObj ShaderGLImpl::LinkProgram(ShaderGLImpl* const* ppShaders, Uint32 NumShaders, bool IsSeparableProgram)
GLObjectWrappers::GLProgramObj ShaderGLImpl::LinkProgram(ShaderGLImpl* const* ppShaders, Uint32 NumShaders, bool IsSeparableProgram) noexcept(false)
{
VERIFY(!IsSeparableProgram || NumShaders == 1, "Number of shaders must be 1 when separable program is created");

GLObjectWrappers::GLProgramObj GLProg(true);
GLObjectWrappers::GLProgramObj GLProg{true};

// GL_PROGRAM_SEPARABLE parameter must be set before linking!
if (IsSeparableProgram)
Expand Down Expand Up @@ -251,8 +251,7 @@ GLObjectWrappers::GLProgramObj ShaderGLImpl::LinkProgram(ShaderGLImpl* const* pp
// Notice that glGetProgramInfoLog is used, not glGetShaderInfoLog.
glGetProgramInfoLog(GLProg, LengthWithNull, &Length, shaderProgramInfoLog.data());
VERIFY(Length == LengthWithNull - 1, "Incorrect program info log len");
LOG_ERROR_MESSAGE("Failed to link shader program:\n", shaderProgramInfoLog.data(), '\n');
UNEXPECTED("glLinkProgram failed");
LOG_ERROR_AND_THROW("Failed to link shader program:\n", shaderProgramInfoLog.data(), '\n');
}

for (Uint32 i = 0; i < NumShaders; ++i)
Expand Down

0 comments on commit 7ad2914

Please sign in to comment.