Slightly saner way to choose shaders depending on language. More work needed.

This commit is contained in:
Henrik Rydgård 2016-12-27 17:38:26 +01:00
parent c79712d9f9
commit 1c337f72bb
6 changed files with 190 additions and 161 deletions

View file

@ -27,154 +27,179 @@ bool RefCountedObject::Release() {
// The Vulkan ones can be re-used with modern GL later if desired, as they're just GLSL. // The Vulkan ones can be re-used with modern GL later if desired, as they're just GLSL.
static const char * const glsl_fsTexCol = struct ShaderSource {
"#ifdef GL_ES\n" ShaderLanguage lang;
"precision lowp float;\n" const char *src;
"#endif\n" };
"varying vec4 oColor0;\n"
"varying vec2 oTexCoord0;\n"
"uniform sampler2D Sampler0;\n"
"void main() { gl_FragColor = texture2D(Sampler0, oTexCoord0) * oColor0; }\n";
static const char * const hlslFsTexCol =
"struct PS_INPUT { float4 color : COLOR0; float2 uv : TEXCOORD0; };\n"
"sampler2D Sampler0 : register(s0);\n"
"float4 main(PS_INPUT input) : COLOR0 {\n"
" return input.color * tex2D(Sampler0, input.uv);\n"
"}\n";
static const char * const vulkan_fsTexCol =
"#version 140\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
"#extension GL_ARB_shading_language_420pack : enable\n"
"layout(location = 0) in vec4 oColor0;\n"
"layout(location = 1) in vec2 oTexCoord0;\n"
"layout(location = 0) out vec4 fragColor0\n;"
"layout(set = 0, binding = 1) uniform sampler2D Sampler0;\n"
"void main() { fragColor0 = texture(Sampler0, oTexCoord0) * oColor0; }\n";
static const char * const glsl_fsCol =
"#ifdef GL_ES\n"
"precision lowp float;\n"
"#endif\n"
"varying vec4 oColor0;\n"
"void main() { gl_FragColor = oColor0; }\n";
static const char * const hlslFsCol =
"struct PS_INPUT { float4 color : COLOR0; };\n"
"float4 main(PS_INPUT input) : COLOR0 {\n"
" return input.color;\n"
"}\n";
static const char * const vulkan_fsCol =
"#version 140\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
"#extension GL_ARB_shading_language_420pack : enable\n"
"layout(location = 0) in vec4 oColor0;\n"
"layout(location = 0) out vec4 fragColor0\n;"
"void main() { fragColor0 = oColor0; }\n";
static const std::vector<ShaderSource> fsTexCol = {
{ShaderLanguage::GLSL_ES_200,
"#ifdef GL_ES\n"
"precision lowp float;\n"
"#endif\n"
"varying vec4 oColor0;\n"
"varying vec2 oTexCoord0;\n"
"uniform sampler2D Sampler0;\n"
"void main() { gl_FragColor = texture2D(Sampler0, oTexCoord0) * oColor0; }\n"
},
{ShaderLanguage::HLSL_D3D9,
"struct PS_INPUT { float4 color : COLOR0; float2 uv : TEXCOORD0; };\n"
"sampler2D Sampler0 : register(s0);\n"
"float4 main(PS_INPUT input) : COLOR0 {\n"
" return input.color * tex2D(Sampler0, input.uv);\n"
"}\n"
},
{ShaderLanguage::GLSL_VULKAN,
"#version 140\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
"#extension GL_ARB_shading_language_420pack : enable\n"
"layout(location = 0) in vec4 oColor0;\n"
"layout(location = 1) in vec2 oTexCoord0;\n"
"layout(location = 0) out vec4 fragColor0\n;"
"layout(set = 0, binding = 1) uniform sampler2D Sampler0;\n"
"void main() { fragColor0 = texture(Sampler0, oTexCoord0) * oColor0; }\n"
}
};
static const std::vector<ShaderSource> fsCol = {
{ ShaderLanguage::GLSL_ES_200,
"#ifdef GL_ES\n"
"precision lowp float;\n"
"#endif\n"
"varying vec4 oColor0;\n"
"void main() { gl_FragColor = oColor0; }\n"
},
{ ShaderLanguage::HLSL_D3D9,
"struct PS_INPUT { float4 color : COLOR0; };\n"
"float4 main(PS_INPUT input) : COLOR0 {\n"
" return input.color;\n"
"}\n"
},
{ ShaderLanguage::GLSL_VULKAN,
"#version 140\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
"#extension GL_ARB_shading_language_420pack : enable\n"
"layout(location = 0) in vec4 oColor0;\n"
"layout(location = 0) out vec4 fragColor0\n;"
"void main() { fragColor0 = oColor0; }\n"
}
};
// ================================== VERTEX SHADERS // ================================== VERTEX SHADERS
static const char * const glsl_vsCol = static const std::vector<ShaderSource> vsCol = {
"attribute vec3 Position;\n" { ShaderLanguage::GLSL_ES_200,
"attribute vec4 Color0;\n" "attribute vec3 Position;\n"
"varying vec4 oColor0;\n" "attribute vec4 Color0;\n"
"uniform mat4 WorldViewProj;\n" "varying vec4 oColor0;\n"
"void main() {\n" "uniform mat4 WorldViewProj;\n"
" gl_Position = WorldViewProj * vec4(Position, 1.0);\n" "void main() {\n"
" oColor0 = Color0;\n" " gl_Position = WorldViewProj * vec4(Position, 1.0);\n"
"}"; " oColor0 = Color0;\n"
"}"
},
{ ShaderLanguage::HLSL_D3D9,
"struct VS_INPUT { float3 Position : POSITION; float4 Color0 : COLOR0; };\n"
"struct VS_OUTPUT { float4 Position : POSITION; float4 Color0 : COLOR0; };\n"
"float4x4 WorldViewProj : register(c0);\n"
"VS_OUTPUT main(VS_INPUT input) {\n"
" VS_OUTPUT output;\n"
" output.Position = mul(float4(input.Position, 1.0), WorldViewProj);\n"
" output.Color0 = input.Color0;\n"
" return output;\n"
"}\n"
},
{ ShaderLanguage::GLSL_VULKAN,
"#version 400\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
"#extension GL_ARB_shading_language_420pack : enable\n"
"layout (std140, set = 0, binding = 0) uniform bufferVals {\n"
" mat4 WorldViewProj;\n"
"} myBufferVals;\n"
"layout (location = 0) in vec4 pos;\n"
"layout (location = 1) in vec4 inColor;\n"
"layout (location = 0) out vec4 outColor;\n"
"out gl_PerVertex { vec4 gl_Position; };\n"
"void main() {\n"
" outColor = inColor;\n"
" gl_Position = myBufferVals.WorldViewProj * pos;\n"
"}\n"
}
};
static const char * const hlslVsCol = static const UniformBufferDesc vsColBuf { { { 0, UniformType::MATRIX4X4, 0 } } };
"struct VS_INPUT { float3 Position : POSITION; float4 Color0 : COLOR0; };\n"
"struct VS_OUTPUT { float4 Position : POSITION; float4 Color0 : COLOR0; };\n"
"float4x4 WorldViewProj : register(c0);\n"
"VS_OUTPUT main(VS_INPUT input) {\n"
" VS_OUTPUT output;\n"
" output.Position = mul(float4(input.Position, 1.0), WorldViewProj);\n"
" output.Color0 = input.Color0;\n"
" return output;\n"
"}\n";
static const char * const vulkan_vsCol =
"#version 400\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
"#extension GL_ARB_shading_language_420pack : enable\n"
"layout (std140, set = 0, binding = 0) uniform bufferVals {\n"
" mat4 WorldViewProj;\n"
"} myBufferVals;\n"
"layout (location = 0) in vec4 pos;\n"
"layout (location = 1) in vec4 inColor;\n"
"layout (location = 0) out vec4 outColor;\n"
"out gl_PerVertex { vec4 gl_Position; };\n"
"void main() {\n"
" outColor = inColor;\n"
" gl_Position = myBufferVals.WorldViewProj * pos;\n"
"}\n";
static const UniformBufferDesc vsColDesc{ { { 0, UniformType::MATRIX4X4, 0 } } };
struct VsColUB { struct VsColUB {
float WorldViewProj[16]; float WorldViewProj[16];
}; };
static const char * const glsl_vsTexCol = static const std::vector<ShaderSource> vsTexCol = {
"attribute vec3 Position;\n" { ShaderLanguage::GLSL_ES_200,
"attribute vec4 Color0;\n" "attribute vec3 Position;\n"
"attribute vec2 TexCoord0;\n" "attribute vec4 Color0;\n"
"varying vec4 oColor0;\n" "attribute vec2 TexCoord0;\n"
"varying vec2 oTexCoord0;\n" "varying vec4 oColor0;\n"
"uniform mat4 WorldViewProj;\n" "varying vec2 oTexCoord0;\n"
"void main() {\n" "uniform mat4 WorldViewProj;\n"
" gl_Position = WorldViewProj * vec4(Position, 1.0);\n" "void main() {\n"
" oColor0 = Color0;\n" " gl_Position = WorldViewProj * vec4(Position, 1.0);\n"
" oTexCoord0 = TexCoord0;\n" " oColor0 = Color0;\n"
"}\n"; " oTexCoord0 = TexCoord0;\n"
"}\n"
static const char * const hlslVsTexCol = },
"struct VS_INPUT { float3 Position : POSITION; float2 Texcoord0 : TEXCOORD0; float4 Color0 : COLOR0; };\n" { ShaderLanguage::HLSL_D3D9,
"struct VS_OUTPUT { float4 Position : POSITION; float2 Texcoord0 : TEXCOORD0; float4 Color0 : COLOR0; };\n" "struct VS_INPUT { float3 Position : POSITION; float2 Texcoord0 : TEXCOORD0; float4 Color0 : COLOR0; };\n"
"float4x4 WorldViewProj : register(c0);\n" "struct VS_OUTPUT { float4 Position : POSITION; float2 Texcoord0 : TEXCOORD0; float4 Color0 : COLOR0; };\n"
"VS_OUTPUT main(VS_INPUT input) {\n" "float4x4 WorldViewProj : register(c0);\n"
" VS_OUTPUT output;\n" "VS_OUTPUT main(VS_INPUT input) {\n"
" output.Position = mul(float4(input.Position, 1.0), WorldViewProj);\n" " VS_OUTPUT output;\n"
" output.Texcoord0 = input.Texcoord0;\n" " output.Position = mul(float4(input.Position, 1.0), WorldViewProj);\n"
" output.Color0 = input.Color0;\n" " output.Texcoord0 = input.Texcoord0;\n"
" return output;\n" " output.Color0 = input.Color0;\n"
"}\n"; " return output;\n"
"}\n"
static const char * const vulkan_vsTexCol = },
"#version 400\n" { ShaderLanguage::GLSL_VULKAN,
"#extension GL_ARB_separate_shader_objects : enable\n" "#version 400\n"
"#extension GL_ARB_shading_language_420pack : enable\n" "#extension GL_ARB_separate_shader_objects : enable\n"
"layout (std140, set = 0, binding = 0) uniform bufferVals {\n" "#extension GL_ARB_shading_language_420pack : enable\n"
" mat4 WorldViewProj;\n" "layout (std140, set = 0, binding = 0) uniform bufferVals {\n"
"} myBufferVals;\n" " mat4 WorldViewProj;\n"
"layout (location = 0) in vec4 pos;\n" "} myBufferVals;\n"
"layout (location = 1) in vec4 inColor;\n" "layout (location = 0) in vec4 pos;\n"
"layout (location = 2) in vec2 inTexCoord;\n" "layout (location = 1) in vec4 inColor;\n"
"layout (location = 0) out vec4 outColor;\n" "layout (location = 2) in vec2 inTexCoord;\n"
"layout (location = 1) out vec2 outTexCoord;\n" "layout (location = 0) out vec4 outColor;\n"
"out gl_PerVertex { vec4 gl_Position; };\n" "layout (location = 1) out vec2 outTexCoord;\n"
"void main() {\n" "out gl_PerVertex { vec4 gl_Position; };\n"
" outColor = inColor;\n" "void main() {\n"
" outTexCoord = inTexCoord;\n" " outColor = inColor;\n"
" gl_Position = myBufferVals.WorldViewProj * pos;\n" " outTexCoord = inTexCoord;\n"
"}\n"; " gl_Position = myBufferVals.WorldViewProj * pos;\n"
"}\n"
}
};
static const UniformBufferDesc vsTexColDesc{ { { 0, UniformType::MATRIX4X4, 0 } } }; static const UniformBufferDesc vsTexColDesc{ { { 0, UniformType::MATRIX4X4, 0 } } };
struct VsTexColUB { struct VsTexColUB {
float WorldViewProj[16]; float WorldViewProj[16];
}; };
void DrawContext::CreatePresets() { inline ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector<ShaderSource> &sources) {
vsPresets_[VS_TEXTURE_COLOR_2D] = CreateShaderModule(ShaderStage::VERTEX, glsl_vsTexCol, hlslVsTexCol, vulkan_vsTexCol); uint32_t supported = draw->GetSupportedShaderLanguages();
vsPresets_[VS_COLOR_2D] = CreateShaderModule(ShaderStage::VERTEX, glsl_vsCol, hlslVsCol, vulkan_vsCol); for (auto iter : sources) {
if ((uint32_t)iter.lang & supported) {
return draw->CreateShaderModule(stage, iter.lang, (const uint8_t *)iter.src, strlen(iter.src));
}
}
return nullptr;
}
fsPresets_[FS_TEXTURE_COLOR_2D] = CreateShaderModule(ShaderStage::FRAGMENT, glsl_fsTexCol, hlslFsTexCol, vulkan_fsTexCol); void DrawContext::CreatePresets() {
fsPresets_[FS_COLOR_2D] = CreateShaderModule(ShaderStage::FRAGMENT, glsl_fsCol, hlslFsCol, vulkan_fsCol); vsPresets_[VS_TEXTURE_COLOR_2D] = CreateShader(this, ShaderStage::VERTEX, vsTexCol);
vsPresets_[VS_COLOR_2D] = CreateShader(this, ShaderStage::VERTEX, vsCol);
fsPresets_[FS_TEXTURE_COLOR_2D] = CreateShader(this, ShaderStage::FRAGMENT, fsTexCol);
fsPresets_[FS_COLOR_2D] = CreateShader(this, ShaderStage::FRAGMENT, fsCol);
} }
DrawContext::~DrawContext() { DrawContext::~DrawContext() {

View file

@ -494,7 +494,6 @@ public:
virtual BlendState *CreateBlendState(const BlendStateDesc &desc) = 0; virtual BlendState *CreateBlendState(const BlendStateDesc &desc) = 0;
virtual SamplerState *CreateSamplerState(const SamplerStateDesc &desc) = 0; virtual SamplerState *CreateSamplerState(const SamplerStateDesc &desc) = 0;
virtual RasterState *CreateRasterState(const RasterStateDesc &desc) = 0; virtual RasterState *CreateRasterState(const RasterStateDesc &desc) = 0;
virtual Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) = 0;
// virtual ComputePipeline CreateComputePipeline(const ComputePipelineDesc &desc) = 0 // virtual ComputePipeline CreateComputePipeline(const ComputePipelineDesc &desc) = 0
virtual InputLayout *CreateInputLayout(const InputLayoutDesc &desc) = 0; virtual InputLayout *CreateInputLayout(const InputLayoutDesc &desc) = 0;
@ -510,9 +509,8 @@ public:
virtual Buffer *CreateBuffer(size_t size, uint32_t usageFlags) = 0; virtual Buffer *CreateBuffer(size_t size, uint32_t usageFlags) = 0;
virtual Texture *CreateTexture() = 0; // To be later filled in by ->LoadFromFile or similar. virtual Texture *CreateTexture() = 0; // To be later filled in by ->LoadFromFile or similar.
virtual Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) = 0; virtual Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) = 0;
virtual ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) = 0;
// The implementation makes the choice of which shader code to use. virtual Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) = 0;
virtual ShaderModule *CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) = 0;
// Dynamic state // Dynamic state
virtual void SetScissorRect(int left, int top, int width, int height) = 0; virtual void SetScissorRect(int left, int top, int width, int height) = 0;

View file

@ -20,7 +20,6 @@ public:
return (uint32_t)ShaderLanguage::HLSL_D3D11 | (uint32_t)ShaderLanguage::HLSL_D3D11_BYTECODE; return (uint32_t)ShaderLanguage::HLSL_D3D11 | (uint32_t)ShaderLanguage::HLSL_D3D11_BYTECODE;
} }
ShaderModule *CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) override;
InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override; InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override;
DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override; DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override;
BlendState *CreateBlendState(const BlendStateDesc &desc) override; BlendState *CreateBlendState(const BlendStateDesc &desc) override;
@ -30,6 +29,7 @@ public:
Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override; Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override;
Texture *CreateTexture() override; Texture *CreateTexture() override;
Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override; Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override;
ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) override;
void BindTextures(int start, int count, Texture **textures) override; void BindTextures(int start, int count, Texture **textures) override;
void BindSamplerStates(int start, int count, SamplerState **states) override; void BindSamplerStates(int start, int count, SamplerState **states) override;

View file

@ -300,7 +300,7 @@ public:
if (constantTable_) if (constantTable_)
constantTable_->Release(); constantTable_->Release();
} }
bool Compile(LPDIRECT3DDEVICE9 device, const char *source); bool Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, size_t size);
void Apply(LPDIRECT3DDEVICE9 device) { void Apply(LPDIRECT3DDEVICE9 device) {
if (stage_ == ShaderStage::FRAGMENT) { if (stage_ == ShaderStage::FRAGMENT) {
device->SetPixelShader(pshader_); device->SetPixelShader(pshader_);
@ -518,7 +518,7 @@ public:
return (uint32_t)ShaderLanguage::HLSL_D3D9 | (uint32_t)ShaderLanguage::HLSL_D3D9_BYTECODE; return (uint32_t)ShaderLanguage::HLSL_D3D9 | (uint32_t)ShaderLanguage::HLSL_D3D9_BYTECODE;
} }
ShaderModule *CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) override; ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) override;
DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override; DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override;
BlendState *CreateBlendState(const BlendStateDesc &desc) override; BlendState *CreateBlendState(const BlendStateDesc &desc) override;
SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override; SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override;
@ -592,9 +592,9 @@ D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, ID
D3D9Context::~D3D9Context() { D3D9Context::~D3D9Context() {
} }
ShaderModule *D3D9Context::CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) { ShaderModule *D3D9Context::CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t size) {
D3D9ShaderModule *shader = new D3D9ShaderModule(stage); D3D9ShaderModule *shader = new D3D9ShaderModule(stage);
if (shader->Compile(device_, hlsl_source)) { if (shader->Compile(device_, data, size)) {
return shader; return shader;
} else { } else {
delete shader; delete shader;
@ -854,12 +854,13 @@ void D3D9Context::SetBlendFactor(float color[4]) {
device_->SetRenderState(D3DRS_BLENDFACTOR, r | (g << 8) | (b << 16) | (a << 24)); device_->SetRenderState(D3DRS_BLENDFACTOR, r | (g << 8) | (b << 16) | (a << 24));
} }
bool D3D9ShaderModule::Compile(LPDIRECT3DDEVICE9 device, const char *source) { bool D3D9ShaderModule::Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, size_t size) {
LPD3DXMACRO defines = NULL; LPD3DXMACRO defines = NULL;
LPD3DXINCLUDE includes = NULL; LPD3DXINCLUDE includes = NULL;
DWORD flags = 0; DWORD flags = 0;
LPD3DXBUFFER codeBuffer; LPD3DXBUFFER codeBuffer;
LPD3DXBUFFER errorBuffer; LPD3DXBUFFER errorBuffer;
const char *source = (const char *)data;
const char *profile = stage_ == ShaderStage::FRAGMENT ? "ps_2_0" : "vs_2_0"; const char *profile = stage_ == ShaderStage::FRAGMENT ? "ps_2_0" : "vs_2_0";
HRESULT hr = dyn_D3DXCompileShader(source, (UINT)strlen(source), defines, includes, "main", profile, flags, &codeBuffer, &errorBuffer, &constantTable_); HRESULT hr = dyn_D3DXCompileShader(source, (UINT)strlen(source), defines, includes, "main", profile, flags, &codeBuffer, &errorBuffer, &constantTable_);
if (FAILED(hr)) { if (FAILED(hr)) {

View file

@ -348,7 +348,7 @@ public:
glDeleteShader(shader_); glDeleteShader(shader_);
} }
bool Compile(const char *source); bool Compile(ShaderLanguage language, const uint8_t *data, size_t dataSize);
GLuint GetShader() const { GLuint GetShader() const {
return shader_; return shader_;
} }
@ -357,30 +357,36 @@ public:
void Unset() { void Unset() {
shader_ = 0; shader_ = 0;
} }
ShaderLanguage GetLanguage() {
return language_;
}
ShaderStage GetStage() const override { ShaderStage GetStage() const override {
return stage_; return stage_;
} }
private: private:
ShaderStage stage_; ShaderStage stage_;
ShaderLanguage language_;
GLuint shader_; GLuint shader_;
GLuint glstage_; GLuint glstage_;
bool ok_; bool ok_;
std::string source_; // So we can recompile in case of context loss. std::string source_; // So we can recompile in case of context loss.
}; };
bool OpenGLShaderModule::Compile(const char *source) { bool OpenGLShaderModule::Compile(ShaderLanguage language, const uint8_t *data, size_t dataSize) {
source_ = source; source_ = std::string((const char *)data);
shader_ = glCreateShader(glstage_); shader_ = glCreateShader(glstage_);
language_ = language;
std::string temp; std::string temp;
// Add the prelude on automatically for fragment shaders. // Add the prelude on automatically for fragment shaders.
if (glstage_ == GL_FRAGMENT_SHADER) { if (glstage_ == GL_FRAGMENT_SHADER) {
temp = std::string(glsl_fragment_prelude) + source; temp = std::string(glsl_fragment_prelude) + source_;
source = temp.c_str(); source_ = temp.c_str();
} }
glShaderSource(shader_, 1, &source, nullptr); const char *code = source_.c_str();
glShaderSource(shader_, 1, &code, nullptr);
glCompileShader(shader_); glCompileShader(shader_);
GLint success = 0; GLint success = 0;
glGetShaderiv(shader_, GL_COMPILE_STATUS, &success); glGetShaderiv(shader_, GL_COMPILE_STATUS, &success);
@ -465,7 +471,7 @@ public:
void GLRestore() override { void GLRestore() override {
for (auto iter : shaders) { for (auto iter : shaders) {
iter->Compile(iter->GetSource().c_str()); iter->Compile(iter->GetLanguage(), (const uint8_t *)iter->GetSource().c_str(), iter->GetSource().size());
} }
LinkShaders(); LinkShaders();
} }
@ -494,7 +500,7 @@ public:
#if defined(USING_GLES2) #if defined(USING_GLES2)
return (uint32_t)ShaderLanguage::GLSL_ES_200 | (uint32_t)ShaderLanguage::GLSL_ES_300; return (uint32_t)ShaderLanguage::GLSL_ES_200 | (uint32_t)ShaderLanguage::GLSL_ES_300;
#else #else
return (uint32_t)ShaderLanguage::GLSL_410; return (uint32_t)ShaderLanguage::GLSL_ES_200 | (uint32_t)ShaderLanguage::GLSL_410;
#endif #endif
} }
@ -505,7 +511,7 @@ public:
Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override; Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override;
Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override; Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override;
InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override; InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override;
ShaderModule *CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) override; ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) override;
Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override; Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override;
Texture *CreateTexture() override; Texture *CreateTexture() override;
@ -931,9 +937,9 @@ void OpenGLContext::BindTextures(int start, int count, Texture **textures) {
} }
ShaderModule *OpenGLContext::CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) { ShaderModule *OpenGLContext::CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) {
OpenGLShaderModule *shader = new OpenGLShaderModule(stage); OpenGLShaderModule *shader = new OpenGLShaderModule(stage);
if (shader->Compile(glsl_source)) { if (shader->Compile(language, data, dataSize)) {
return shader; return shader;
} else { } else {
shader->Release(); shader->Release();

View file

@ -226,7 +226,7 @@ public:
VKShaderModule(ShaderStage stage) : module_(VK_NULL_HANDLE), ok_(false), stage_(stage) { VKShaderModule(ShaderStage stage) : module_(VK_NULL_HANDLE), ok_(false), stage_(stage) {
vkstage_ = StageToVulkan(stage); vkstage_ = StageToVulkan(stage);
} }
bool Compile(VulkanContext *vulkan, const char *source); bool Compile(VulkanContext *vulkan, ShaderLanguage language, const uint8_t *data, size_t size);
const std::string &GetSource() const { return source_; } const std::string &GetSource() const { return source_; }
~VKShaderModule() { ~VKShaderModule() {
if (module_) { if (module_) {
@ -247,12 +247,12 @@ private:
std::string source_; // So we can recompile in case of context loss. std::string source_; // So we can recompile in case of context loss.
}; };
bool VKShaderModule::Compile(VulkanContext *vulkan, const char *source) { bool VKShaderModule::Compile(VulkanContext *vulkan, ShaderLanguage language, const uint8_t *data, size_t size) {
// We'll need this to free it later. // We'll need this to free it later.
device_ = vulkan->GetDevice(); device_ = vulkan->GetDevice();
this->source_ = source; this->source_ = (const char *)data;
std::vector<uint32_t> spirv; std::vector<uint32_t> spirv;
if (!GLSLtoSPV(vkstage_, source, spirv)) { if (!GLSLtoSPV(vkstage_, source_.c_str(), spirv)) {
return false; return false;
} }
@ -270,7 +270,6 @@ bool VKShaderModule::Compile(VulkanContext *vulkan, const char *source) {
} else { } else {
ok_ = false; ok_ = false;
} }
return ok_; return ok_;
} }
@ -363,7 +362,7 @@ public:
SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override; SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override;
RasterState *CreateRasterState(const RasterStateDesc &desc) override; RasterState *CreateRasterState(const RasterStateDesc &desc) override;
Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override; Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override;
ShaderModule *CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) override; ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) override;
Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override; Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override;
Texture *CreateTexture() override; Texture *CreateTexture() override;
@ -1023,12 +1022,12 @@ void VKContext::BindTextures(int start, int count, Texture **textures) {
} }
} }
ShaderModule *VKContext::CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) { ShaderModule *VKContext::CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t size) {
VKShaderModule *shader = new VKShaderModule(stage); VKShaderModule *shader = new VKShaderModule(stage);
if (shader->Compile(vulkan_, vulkan_source)) { if (shader->Compile(vulkan_, language, data, size)) {
return shader; return shader;
} else { } else {
ELOG("Failed to compile shader: %s", vulkan_source); ELOG("Failed to compile shader: %s", (const char *)data);
shader->Release(); shader->Release();
return nullptr; return nullptr;
} }