mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Slightly saner way to choose shaders depending on language. More work needed.
This commit is contained in:
parent
c79712d9f9
commit
1c337f72bb
6 changed files with 190 additions and 161 deletions
|
@ -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<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
|
||||
|
||||
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<ShaderSource> 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<ShaderSource> 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<ShaderSource> &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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<uint32_t> 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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue