diff --git a/ext/native/thin3d/thin3d.cpp b/ext/native/thin3d/thin3d.cpp index 3605668a84..b2c7ef7199 100644 --- a/ext/native/thin3d/thin3d.cpp +++ b/ext/native/thin3d/thin3d.cpp @@ -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. -static const char * const glsl_fsTexCol = -"#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"; - -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"; +struct ShaderSource { + ShaderLanguage lang; + const char *src; +}; +static const std::vector 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 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 -static const char * const glsl_vsCol = -"attribute vec3 Position;\n" -"attribute vec4 Color0;\n" -"varying vec4 oColor0;\n" -"uniform mat4 WorldViewProj;\n" -"void main() {\n" -" gl_Position = WorldViewProj * vec4(Position, 1.0);\n" -" oColor0 = Color0;\n" -"}"; +static const std::vector vsCol = { + { ShaderLanguage::GLSL_ES_200, + "attribute vec3 Position;\n" + "attribute vec4 Color0;\n" + "varying vec4 oColor0;\n" + "uniform mat4 WorldViewProj;\n" + "void main() {\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 = -"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 } } }; +static const UniformBufferDesc vsColBuf { { { 0, UniformType::MATRIX4X4, 0 } } }; struct VsColUB { float WorldViewProj[16]; }; -static const char * const glsl_vsTexCol = -"attribute vec3 Position;\n" -"attribute vec4 Color0;\n" -"attribute vec2 TexCoord0;\n" -"varying vec4 oColor0;\n" -"varying vec2 oTexCoord0;\n" -"uniform mat4 WorldViewProj;\n" -"void main() {\n" -" gl_Position = WorldViewProj * vec4(Position, 1.0);\n" -" oColor0 = Color0;\n" -" oTexCoord0 = TexCoord0;\n" -"}\n"; - -static const char * const hlslVsTexCol = -"struct VS_INPUT { float3 Position : POSITION; float2 Texcoord0 : TEXCOORD0; float4 Color0 : COLOR0; };\n" -"struct VS_OUTPUT { float4 Position : POSITION; float2 Texcoord0 : TEXCOORD0; 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.Texcoord0 = input.Texcoord0;\n" -" output.Color0 = input.Color0;\n" -" return output;\n" -"}\n"; - -static const char * const vulkan_vsTexCol = -"#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 = 2) in vec2 inTexCoord;\n" -"layout (location = 0) out vec4 outColor;\n" -"layout (location = 1) out vec2 outTexCoord;\n" -"out gl_PerVertex { vec4 gl_Position; };\n" -"void main() {\n" -" outColor = inColor;\n" -" outTexCoord = inTexCoord;\n" -" gl_Position = myBufferVals.WorldViewProj * pos;\n" -"}\n"; +static const std::vector vsTexCol = { + { ShaderLanguage::GLSL_ES_200, + "attribute vec3 Position;\n" + "attribute vec4 Color0;\n" + "attribute vec2 TexCoord0;\n" + "varying vec4 oColor0;\n" + "varying vec2 oTexCoord0;\n" + "uniform mat4 WorldViewProj;\n" + "void main() {\n" + " gl_Position = WorldViewProj * vec4(Position, 1.0);\n" + " oColor0 = Color0;\n" + " oTexCoord0 = TexCoord0;\n" + "}\n" + }, + { ShaderLanguage::HLSL_D3D9, + "struct VS_INPUT { float3 Position : POSITION; float2 Texcoord0 : TEXCOORD0; float4 Color0 : COLOR0; };\n" + "struct VS_OUTPUT { float4 Position : POSITION; float2 Texcoord0 : TEXCOORD0; 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.Texcoord0 = input.Texcoord0;\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 = 2) in vec2 inTexCoord;\n" + "layout (location = 0) out vec4 outColor;\n" + "layout (location = 1) out vec2 outTexCoord;\n" + "out gl_PerVertex { vec4 gl_Position; };\n" + "void main() {\n" + " outColor = inColor;\n" + " outTexCoord = inTexCoord;\n" + " gl_Position = myBufferVals.WorldViewProj * pos;\n" + "}\n" + } +}; static const UniformBufferDesc vsTexColDesc{ { { 0, UniformType::MATRIX4X4, 0 } } }; struct VsTexColUB { float WorldViewProj[16]; }; -void DrawContext::CreatePresets() { - vsPresets_[VS_TEXTURE_COLOR_2D] = CreateShaderModule(ShaderStage::VERTEX, glsl_vsTexCol, hlslVsTexCol, vulkan_vsTexCol); - vsPresets_[VS_COLOR_2D] = CreateShaderModule(ShaderStage::VERTEX, glsl_vsCol, hlslVsCol, vulkan_vsCol); +inline ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector &sources) { + uint32_t supported = draw->GetSupportedShaderLanguages(); + 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); - fsPresets_[FS_COLOR_2D] = CreateShaderModule(ShaderStage::FRAGMENT, glsl_fsCol, hlslFsCol, vulkan_fsCol); +void DrawContext::CreatePresets() { + 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() { diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index f3e8cd660b..7005941b32 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -494,7 +494,6 @@ public: virtual BlendState *CreateBlendState(const BlendStateDesc &desc) = 0; virtual SamplerState *CreateSamplerState(const SamplerStateDesc &desc) = 0; virtual RasterState *CreateRasterState(const RasterStateDesc &desc) = 0; - virtual Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) = 0; // virtual ComputePipeline CreateComputePipeline(const ComputePipelineDesc &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 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; - - // The implementation makes the choice of which shader code to use. - virtual ShaderModule *CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) = 0; + virtual ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) = 0; + virtual Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) = 0; // Dynamic state virtual void SetScissorRect(int left, int top, int width, int height) = 0; diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index 991c2b299b..69bb318a26 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -20,7 +20,6 @@ public: 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; DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override; BlendState *CreateBlendState(const BlendStateDesc &desc) override; @@ -30,6 +29,7 @@ public: Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override; Texture *CreateTexture() 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 BindSamplerStates(int start, int count, SamplerState **states) override; diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index 7977dee605..5291cfb676 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -300,7 +300,7 @@ public: if (constantTable_) constantTable_->Release(); } - bool Compile(LPDIRECT3DDEVICE9 device, const char *source); + bool Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, size_t size); void Apply(LPDIRECT3DDEVICE9 device) { if (stage_ == ShaderStage::FRAGMENT) { device->SetPixelShader(pshader_); @@ -518,7 +518,7 @@ public: 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; BlendState *CreateBlendState(const BlendStateDesc &desc) override; SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override; @@ -592,9 +592,9 @@ D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, ID 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); - if (shader->Compile(device_, hlsl_source)) { + if (shader->Compile(device_, data, size)) { return shader; } else { delete shader; @@ -854,12 +854,13 @@ void D3D9Context::SetBlendFactor(float color[4]) { 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; LPD3DXINCLUDE includes = NULL; DWORD flags = 0; LPD3DXBUFFER codeBuffer; LPD3DXBUFFER errorBuffer; + const char *source = (const char *)data; 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_); if (FAILED(hr)) { diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index f56fe3da8b..108722bdd0 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -348,7 +348,7 @@ public: glDeleteShader(shader_); } - bool Compile(const char *source); + bool Compile(ShaderLanguage language, const uint8_t *data, size_t dataSize); GLuint GetShader() const { return shader_; } @@ -357,30 +357,36 @@ public: void Unset() { shader_ = 0; } + ShaderLanguage GetLanguage() { + return language_; + } ShaderStage GetStage() const override { return stage_; } private: ShaderStage stage_; + ShaderLanguage language_; GLuint shader_; GLuint glstage_; bool ok_; std::string source_; // So we can recompile in case of context loss. }; -bool OpenGLShaderModule::Compile(const char *source) { - source_ = source; +bool OpenGLShaderModule::Compile(ShaderLanguage language, const uint8_t *data, size_t dataSize) { + source_ = std::string((const char *)data); shader_ = glCreateShader(glstage_); + language_ = language; std::string temp; // Add the prelude on automatically for fragment shaders. if (glstage_ == GL_FRAGMENT_SHADER) { - temp = std::string(glsl_fragment_prelude) + source; - source = temp.c_str(); + temp = std::string(glsl_fragment_prelude) + source_; + source_ = temp.c_str(); } - glShaderSource(shader_, 1, &source, nullptr); + const char *code = source_.c_str(); + glShaderSource(shader_, 1, &code, nullptr); glCompileShader(shader_); GLint success = 0; glGetShaderiv(shader_, GL_COMPILE_STATUS, &success); @@ -465,7 +471,7 @@ public: void GLRestore() override { 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(); } @@ -494,7 +500,7 @@ public: #if defined(USING_GLES2) return (uint32_t)ShaderLanguage::GLSL_ES_200 | (uint32_t)ShaderLanguage::GLSL_ES_300; #else - return (uint32_t)ShaderLanguage::GLSL_410; + return (uint32_t)ShaderLanguage::GLSL_ES_200 | (uint32_t)ShaderLanguage::GLSL_410; #endif } @@ -505,7 +511,7 @@ public: Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override; Pipeline *CreateGraphicsPipeline(const PipelineDesc &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() 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); - if (shader->Compile(glsl_source)) { + if (shader->Compile(language, data, dataSize)) { return shader; } else { shader->Release(); diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 83b748c24d..9008aee50a 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -226,7 +226,7 @@ public: VKShaderModule(ShaderStage stage) : module_(VK_NULL_HANDLE), ok_(false), stage_(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_; } ~VKShaderModule() { if (module_) { @@ -247,12 +247,12 @@ private: 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. device_ = vulkan->GetDevice(); - this->source_ = source; + this->source_ = (const char *)data; std::vector spirv; - if (!GLSLtoSPV(vkstage_, source, spirv)) { + if (!GLSLtoSPV(vkstage_, source_.c_str(), spirv)) { return false; } @@ -270,7 +270,6 @@ bool VKShaderModule::Compile(VulkanContext *vulkan, const char *source) { } else { ok_ = false; } - return ok_; } @@ -363,7 +362,7 @@ public: SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override; RasterState *CreateRasterState(const RasterStateDesc &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() 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); - if (shader->Compile(vulkan_, vulkan_source)) { + if (shader->Compile(vulkan_, language, data, size)) { return shader; } else { - ELOG("Failed to compile shader: %s", vulkan_source); + ELOG("Failed to compile shader: %s", (const char *)data); shader->Release(); return nullptr; }