Skip to content

Commit

Permalink
OpenGL: added support for caching shaders
Browse files Browse the repository at this point in the history
  • Loading branch information
Xottab-DUTY committed Aug 25, 2019
1 parent bdb5d02 commit dd07c10
Show file tree
Hide file tree
Showing 4 changed files with 280 additions and 102 deletions.
4 changes: 4 additions & 0 deletions src/Layers/xrRender/HW.h
Expand Up @@ -68,6 +68,10 @@ class CHW
SDL_Window* m_hWnd;
HDC m_hDC;
SDL_GLContext m_hRC;
pcstr AdapterName;
pcstr OpenGLVersion;
pcstr ShadingVersion;
bool ShaderBinarySupported;
#else // General DirectX
ID3DDevice* pDevice = nullptr; // render device
ID3DRenderTargetView* pBaseRT = nullptr; // base render target
Expand Down
140 changes: 118 additions & 22 deletions src/Layers/xrRender/ShaderResourceTraits.h
Expand Up @@ -4,19 +4,61 @@

#ifdef USE_OGL
template<GLenum type>
inline std::pair<GLuint, GLuint> GLCreateShader(pcstr* buffer, size_t size, pcstr name)
inline std::pair<GLuint, GLuint> GLCompileShader(pcstr* buffer, size_t size, pcstr name)
{
GLint status{};

GLuint shader = glCreateShader(type);
R_ASSERT(shader);
CHK_GL(glShaderSource(shader, size, buffer, nullptr));
CHK_GL(glCompileShader(shader));
glShaderSource(shader, size, buffer, nullptr);
glCompileShader(shader);

glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (GLboolean(status) == GL_FALSE)
return { shader, -1 };

GLuint program = glCreateProgram();
R_ASSERT(program);
CHK_GL(glObjectLabel(GL_PROGRAM, program, -1, name));
CHK_GL(glProgramParameteri(program, GL_PROGRAM_SEPARABLE, (GLint)GL_TRUE));
CHK_GL(glProgramParameteri(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, (GLint)GL_TRUE));

glAttachShader(program, shader);
glBindFragDataLocation(program, 0, "SV_Target");
glBindFragDataLocation(program, 0, "SV_Target0");
glBindFragDataLocation(program, 1, "SV_Target1");
glBindFragDataLocation(program, 2, "SV_Target2");
glLinkProgram(program);
glDetachShader(program, shader);
glDeleteShader(shader);

glGetProgramiv(program, GL_LINK_STATUS, &status);
if (GLboolean(status) == GL_FALSE)
return { -1, program };

return { 0, program };
}

inline std::pair<GLuint, GLuint> GLUseBinary(pcstr* buffer, size_t size, const GLenum* format, pcstr name)
{
GLint status{};

GLuint program = glCreateProgram();
R_ASSERT(program);
CHK_GL(glObjectLabel(GL_PROGRAM, program, -1, name));
CHK_GL(glProgramParameteri(program, GL_PROGRAM_SEPARABLE, (GLint)GL_TRUE));

return { shader, program };
glBindFragDataLocation(program, 0, "SV_Target");
glBindFragDataLocation(program, 0, "SV_Target0");
glBindFragDataLocation(program, 1, "SV_Target1");
glBindFragDataLocation(program, 2, "SV_Target2");

glProgramBinary(program, *format, buffer, size);
glGetProgramiv(program, GL_LINK_STATUS, &status);
if ((GLboolean)status == GL_FALSE)
return { -1, program };

return { 0, program };
}
#endif

Expand All @@ -29,10 +71,16 @@ struct ShaderTypeTraits<SVS>
using MapType = CResourceManager::map_VS;

#ifdef USE_OGL
using LinkageType = const GLenum*;
using HWShaderType = GLuint;
using BufferType = pcstr*;
using ResultType = std::pair<GLuint, GLuint>;
#else
#ifdef USE_DX11
using LinkageType = ID3D11ClassLinkage*;
#else
using LinkageType = void*;
#endif
using HWShaderType = ID3DVertexShader*;
using BufferType = DWORD const*;
using ResultType = HRESULT;
Expand Down Expand Up @@ -97,14 +145,17 @@ struct ShaderTypeTraits<SVS>
}

static inline ResultType CreateHWShader(BufferType buffer, size_t size, HWShaderType& sh,
pcstr name = nullptr)
LinkageType linkage = nullptr, pcstr name = nullptr)
{
ResultType res{};

#ifdef USE_OGL
res = GLCreateShader<GL_VERTEX_SHADER>(buffer, size, name);
if (linkage)
res = GLUseBinary(buffer, size, linkage, name);
else
res = GLCompileShader<GL_VERTEX_SHADER>(buffer, size, name);
#elif defined(USE_DX11)
res = HW.pDevice->CreateVertexShader(buffer, size, 0, &sh);
res = HW.pDevice->CreateVertexShader(buffer, size, linkage, &sh);
#elif defined(USE_DX10)
res = HW.pDevice->CreateVertexShader(buffer, size, &sh);
#else
Expand All @@ -123,10 +174,16 @@ struct ShaderTypeTraits<SPS>
using MapType = CResourceManager::map_PS;

#ifdef USE_OGL
using LinkageType = const GLenum*;
using HWShaderType = GLuint;
using BufferType = pcstr*;
using ResultType = std::pair<GLuint, GLuint>;
#else
#ifdef USE_DX11
using LinkageType = ID3D11ClassLinkage*;
#else
using LinkageType = void*;
#endif
using HWShaderType = ID3DPixelShader*;
using BufferType = DWORD const*;
using ResultType = HRESULT;
Expand Down Expand Up @@ -203,14 +260,17 @@ struct ShaderTypeTraits<SPS>
}

static inline ResultType CreateHWShader(BufferType buffer, size_t size, HWShaderType& sh,
pcstr name = nullptr)
LinkageType linkage = nullptr, pcstr name = nullptr)
{
ResultType res{};

#ifdef USE_OGL
res = GLCreateShader<GL_FRAGMENT_SHADER>(buffer, size, name);
if (linkage)
res = GLUseBinary(buffer, size, linkage, name);
else
res = GLCompileShader<GL_FRAGMENT_SHADER>(buffer, size, name);
#elif defined(USE_DX11)
res = HW.pDevice->CreatePixelShader(buffer, size, 0, &sh);
res = HW.pDevice->CreatePixelShader(buffer, size, linkage, &sh);
#elif defined(USE_DX10)
res = HW.pDevice->CreatePixelShader(buffer, size, &sh);
#else
Expand All @@ -230,10 +290,16 @@ struct ShaderTypeTraits<SGS>
using MapType = CResourceManager::map_GS;

#ifdef USE_OGL
using LinkageType = const GLenum*;
using HWShaderType = GLuint;
using BufferType = pcstr*;
using ResultType = std::pair<GLuint, GLuint>;
#else
#ifdef USE_DX11
using LinkageType = ID3D11ClassLinkage*;
#else
using LinkageType = void*;
#endif
using HWShaderType = ID3DGeometryShader*;
using BufferType = DWORD const*;
using ResultType = HRESULT;
Expand Down Expand Up @@ -277,14 +343,17 @@ struct ShaderTypeTraits<SGS>
}

static inline ResultType CreateHWShader(BufferType buffer, size_t size, HWShaderType& sh,
pcstr name = nullptr)
LinkageType linkage = nullptr, pcstr name = nullptr)
{
ResultType res{};

#ifdef USE_OGL
res = GLCreateShader<GL_GEOMETRY_SHADER>(buffer, size, name);
if (linkage)
res = GLUseBinary(buffer, size, linkage, name);
else
res = GLCompileShader<GL_GEOMETRY_SHADER>(buffer, size, name);
#elif defined(USE_DX11)
res = HW.pDevice->CreateGeometryShader(buffer, size, 0, &sh);
res = HW.pDevice->CreateGeometryShader(buffer, size, linkage, &sh);
#else
res = HW.pDevice->CreateGeometryShader(buffer, size, &sh);
#endif
Expand All @@ -303,10 +372,16 @@ struct ShaderTypeTraits<SHS>
using MapType = CResourceManager::map_HS;

#ifdef USE_OGL
using LinkageType = const GLenum*;
using HWShaderType = GLuint;
using BufferType = pcstr*;
using ResultType = std::pair<GLuint, GLuint>;
#else
#ifdef USE_DX11
using LinkageType = ID3D11ClassLinkage*;
#else
using LinkageType = void*;
#endif
using HWShaderType = ID3D11HullShader*;
using BufferType = DWORD const*;
using ResultType = HRESULT;
Expand Down Expand Up @@ -340,14 +415,17 @@ struct ShaderTypeTraits<SHS>
}

static inline ResultType CreateHWShader(BufferType buffer, size_t size, HWShaderType& sh,
pcstr name = nullptr)
LinkageType linkage = nullptr, pcstr name = nullptr)
{
ResultType res{};

#ifdef USE_OGL
res = GLCreateShader<GL_TESS_CONTROL_SHADER>(buffer, size, name);
if (linkage)
res = GLUseBinary(buffer, size, linkage, name);
else
res = GLCompileShader<GL_TESS_CONTROL_SHADER>(buffer, size, name);
#else
res = HW.pDevice->CreateHullShader(buffer, size, NULL, &sh);
res = HW.pDevice->CreateHullShader(buffer, size, linkage, &sh);
#endif

return res;
Expand All @@ -362,10 +440,16 @@ struct ShaderTypeTraits<SDS>
using MapType = CResourceManager::map_DS;

#ifdef USE_OGL
using LinkageType = const GLenum*;
using HWShaderType = GLuint;
using BufferType = pcstr*;
using ResultType = std::pair<GLuint, GLuint>;
#else
#ifdef USE_DX11
using LinkageType = ID3D11ClassLinkage*;
#else
using LinkageType = void*;
#endif
using HWShaderType = ID3D11DomainShader*;
using BufferType = DWORD const*;
using ResultType = HRESULT;
Expand Down Expand Up @@ -399,14 +483,17 @@ struct ShaderTypeTraits<SDS>
}

static inline ResultType CreateHWShader(BufferType buffer, size_t size, HWShaderType& sh,
pcstr name = nullptr)
LinkageType linkage = nullptr, pcstr name = nullptr)
{
ResultType res{};

#ifdef USE_OGL
res = GLCreateShader<GL_TESS_EVALUATION_SHADER>(buffer, size, name);
if (linkage)
res = GLUseBinary(buffer, size, linkage, name);
else
res = GLCompileShader<GL_TESS_EVALUATION_SHADER>(buffer, size, name);
#else
res = HW.pDevice->CreateDomainShader(buffer, size, NULL, &sh);
res = HW.pDevice->CreateDomainShader(buffer, size, linkage, &sh);
#endif

return res;
Expand All @@ -421,10 +508,16 @@ struct ShaderTypeTraits<SCS>
using MapType = CResourceManager::map_CS;

#ifdef USE_OGL
using LinkageType = const GLenum*;
using HWShaderType = GLuint;
using BufferType = pcstr*;
using ResultType = std::pair<GLuint, GLuint>;
#else
#ifdef USE_DX11
using LinkageType = ID3D11ClassLinkage*;
#else
using LinkageType = void*;
#endif
using HWShaderType = ID3D11ComputeShader*;
using BufferType = DWORD const*;
using ResultType = HRESULT;
Expand Down Expand Up @@ -462,14 +555,17 @@ struct ShaderTypeTraits<SCS>
}

static inline ResultType CreateHWShader(BufferType buffer, size_t size, HWShaderType& sh,
pcstr name = nullptr)
LinkageType linkage = nullptr, pcstr name = nullptr)
{
ResultType res{};

#ifdef USE_OGL
res = GLCreateShader<GL_COMPUTE_SHADER>(buffer, size, name);
if (linkage)
res = GLUseBinary(buffer, size, linkage, name);
else
res = GLCompileShader<GL_COMPUTE_SHADER>(buffer, size, name);
#else
res = HW.pDevice->CreateComputeShader(buffer, size, NULL, &sh);
res = HW.pDevice->CreateComputeShader(buffer, size, linkage, &sh);
#endif

return res;
Expand Down
12 changes: 9 additions & 3 deletions src/Layers/xrRenderGL/glHW.cpp
Expand Up @@ -77,11 +77,17 @@ void CHW::CreateDevice(SDL_Window* hWnd)
glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &iMaxVTFUnits);
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &iMaxCTIUnits);

Msg("* GPU vendor: [%s] device: [%s]", glGetString(GL_VENDOR), glGetString(GL_RENDERER));
Msg("* GPU OpenGL version: %s", glGetString(GL_VERSION));
Msg("* GPU OpenGL shading language version: %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
AdapterName = reinterpret_cast<pcstr>(glGetString(GL_RENDERER));
OpenGLVersion = reinterpret_cast<pcstr>(glGetString(GL_VERSION));
ShadingVersion = reinterpret_cast<pcstr>(glGetString(GL_SHADING_LANGUAGE_VERSION));

Msg("* GPU vendor: [%s] device: [%s]", glGetString(GL_VENDOR), AdapterName);
Msg("* GPU OpenGL version: %s", OpenGLVersion);
Msg("* GPU OpenGL shading language version: %s", ShadingVersion);
Msg("* GPU OpenGL VTF units: [%d] CTI units: [%d]", iMaxVTFUnits, iMaxCTIUnits);

ShaderBinarySupported = GLEW_ARB_get_program_binary;

// Create render target and depth-stencil views here
UpdateViews();
}
Expand Down

0 comments on commit dd07c10

Please sign in to comment.