diff options
Diffstat (limited to 'servers')
-rw-r--r-- | servers/visual/rasterizer_rd/rasterizer_rd.cpp | 16 | ||||
-rw-r--r-- | servers/visual/rasterizer_rd/shader_rd.cpp | 65 | ||||
-rw-r--r-- | servers/visual/rendering_device.cpp | 31 | ||||
-rw-r--r-- | servers/visual/rendering_device.h | 52 |
4 files changed, 114 insertions, 50 deletions
diff --git a/servers/visual/rasterizer_rd/rasterizer_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_rd.cpp index d1c7549409..9be7a6e3f7 100644 --- a/servers/visual/rasterizer_rd/rasterizer_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_rd.cpp @@ -61,9 +61,9 @@ void RasterizerRD::end_frame(bool p_swap_buffers) { void RasterizerRD::initialize() { { //create framebuffer copy shader - RenderingDevice::ShaderStageSource vert; + RenderingDevice::ShaderStageData vert; vert.shader_stage = RenderingDevice::SHADER_STAGE_VERTEX; - vert.shader_source = + vert.spir_v = RenderingDevice::get_singleton()->shader_compile_from_source(RenderingDevice::SHADER_STAGE_VERTEX, "#version 450\n" "layout(push_constant, binding = 0, std140) uniform Pos { vec4 dst_rect; } pos;\n" "layout(location =0) out vec2 uv;\n" @@ -72,22 +72,22 @@ void RasterizerRD::initialize() { " uv = base_arr[gl_VertexIndex];\n" " vec2 vtx = pos.dst_rect.xy+uv*pos.dst_rect.zw;\n" " gl_Position = vec4(vtx * 2.0 - 1.0,0.0,1.0);\n" - "}\n"; + "}\n"); - RenderingDevice::ShaderStageSource frag; + RenderingDevice::ShaderStageData frag; frag.shader_stage = RenderingDevice::SHADER_STAGE_FRAGMENT; - frag.shader_source = + frag.spir_v =RenderingDevice::get_singleton()->shader_compile_from_source(RenderingDevice::SHADER_STAGE_FRAGMENT, "#version 450\n" "layout (location = 0) in vec2 uv;\n" "layout (location = 0) out vec4 color;\n" "layout (binding = 0) uniform sampler2D src_rt;\n" - "void main() { color=texture(src_rt,uv); }\n"; + "void main() { color=texture(src_rt,uv); }\n"); - Vector<RenderingDevice::ShaderStageSource> source; + Vector<RenderingDevice::ShaderStageData> source; source.push_back(vert); source.push_back(frag); String error; - copy_viewports_rd_shader = RD::get_singleton()->shader_create_from_source(source, &error); + copy_viewports_rd_shader = RD::get_singleton()->shader_create(source); if (!copy_viewports_rd_shader.is_valid()) { print_line("failed compilation: " + error); } else { diff --git a/servers/visual/rasterizer_rd/shader_rd.cpp b/servers/visual/rasterizer_rd/shader_rd.cpp index d4b3db60ac..945fc25cab 100644 --- a/servers/visual/rasterizer_rd/shader_rd.cpp +++ b/servers/visual/rasterizer_rd/shader_rd.cpp @@ -171,7 +171,12 @@ void ShaderRD::_compile_version(Version *p_version) { for (int i = 0; i < variant_defines.size(); i++) { - Vector<RD::ShaderStageSource> stages; + Vector<RD::ShaderStageData> stages; + + String error; + String current_source; + RD::ShaderStage current_stage = RD::SHADER_STAGE_VERTEX; + bool build_ok=true; { //vertex stage @@ -201,15 +206,21 @@ void ShaderRD::_compile_version(Version *p_version) { builder.append(vertex_code3.get_data()); //fourth of vertex - RD::ShaderStageSource stage; - stage.shader_source = builder.as_string(); - stage.shader_stage = RD::SHADER_STAGE_VERTEX; + current_source = builder.as_string(); + RD::ShaderStageData stage; + stage.spir_v = RD::get_singleton()->shader_compile_from_source(RD::SHADER_STAGE_VERTEX,current_source,RD::SHADER_LANGUAGE_GLSL,&error); + if (stage.spir_v.size()==0) { + build_ok=false; + } else { - stages.push_back(stage); + stage.shader_stage = RD::SHADER_STAGE_VERTEX; + stages.push_back(stage); + } } - { + if (build_ok){ //fragment stage + current_stage =RD::SHADER_STAGE_FRAGMENT; StringBuilder builder; @@ -240,29 +251,26 @@ void ShaderRD::_compile_version(Version *p_version) { builder.append(fragment_code4.get_data()); //fourth part of fragment - RD::ShaderStageSource stage; - stage.shader_source = builder.as_string(); - stage.shader_stage = RD::SHADER_STAGE_FRAGMENT; -#if 0 - if (stage.shader_stage == RD::SHADER_STAGE_FRAGMENT && p_version->uniforms.length()) { - print_line(stage.shader_source.get_with_code_lines()); + current_source = builder.as_string(); + RD::ShaderStageData stage; + stage.spir_v = RD::get_singleton()->shader_compile_from_source(RD::SHADER_STAGE_FRAGMENT,current_source,RD::SHADER_LANGUAGE_GLSL,&error); + if (stage.spir_v.size()==0) { + build_ok=false; + } else { + + stage.shader_stage = RD::SHADER_STAGE_FRAGMENT; + stages.push_back(stage); } -#endif - stages.push_back(stage); + } - String error; - RD::ShaderStage error_stage; - RID shader = RD::get_singleton()->shader_create_from_source(stages, &error, &error_stage); - if (shader.is_null() && error != String()) { - ERR_PRINT("Error compiling shader, variant #" + itos(i) + " (" + variant_defines[i].get_data() + ")."); + if (!build_ok) { + ERR_PRINT("Error compiling " + String(current_stage == RD::SHADER_STAGE_VERTEX ? "Vertex" : "Fragment") + " shader, variant #" + itos(i) + " (" + variant_defines[i].get_data() + ")."); ERR_PRINT(error); #ifdef DEBUG_ENABLED - if (error_stage < RD::SHADER_STAGE_MAX) { - ERR_PRINT("code:\n" + stages[error_stage].shader_source.get_with_code_lines()); - } + ERR_PRINT("code:\n" + current_source.get_with_code_lines()); #endif //clear versions if they exist for (int j = 0; j < i; j++) { @@ -274,6 +282,19 @@ void ShaderRD::_compile_version(Version *p_version) { return; } + RID shader = RD::get_singleton()->shader_create(stages); + + if (shader.is_null()) { + //clear versions if they exist + for (int j = 0; j < i; j++) { + RD::get_singleton()->free(p_version->variants[j]); + } + + memdelete_arr(p_version->variants); + p_version->variants = NULL; + return; + } + p_version->variants[i] = shader; } diff --git a/servers/visual/rendering_device.cpp b/servers/visual/rendering_device.cpp index eaecc76b55..55707acc8c 100644 --- a/servers/visual/rendering_device.cpp +++ b/servers/visual/rendering_device.cpp @@ -1,13 +1,38 @@ #include "rendering_device.h" - -RenderingDevice *RenderingDevice::singleton=NULL; +RenderingDevice *RenderingDevice::singleton = NULL; RenderingDevice *RenderingDevice::get_singleton() { return singleton; } +RenderingDevice::ShaderCompileFunction RenderingDevice::compile_function = NULL; +RenderingDevice::ShaderCacheFunction RenderingDevice::cache_function = NULL; + +void RenderingDevice::shader_set_compile_function(ShaderCompileFunction p_function) { + compile_function = p_function; +} +void RenderingDevice::shader_set_cache_function(ShaderCacheFunction p_function) { + cache_function = p_function; +} + +PoolVector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error, bool p_allow_cache) { + if (p_allow_cache && cache_function) { + PoolVector<uint8_t> cache = cache_function(p_stage, p_source_code, p_language); + if (cache.size()) { + return cache; + } + } + + ERR_FAIL_COND_V(!compile_function, PoolVector<uint8_t>()); + + return compile_function(p_stage, p_source_code, p_language, r_error); +} + RenderingDevice::RenderingDevice() { - singleton=this; + ShaderCompileFunction compile_function; + ShaderCacheFunction cache_function; + + singleton = this; } diff --git a/servers/visual/rendering_device.h b/servers/visual/rendering_device.h index fed2b0e79d..4f32673dc7 100644 --- a/servers/visual/rendering_device.h +++ b/servers/visual/rendering_device.h @@ -5,6 +5,32 @@ class RenderingDevice : public Object { GDCLASS(RenderingDevice, Object) +public: + enum ShaderStage { + SHADER_STAGE_VERTEX, + SHADER_STAGE_FRAGMENT, + SHADER_STAGE_TESSELATION_CONTROL, + SHADER_STAGE_TESSELATION_EVALUATION, + SHADER_STAGE_COMPUTE, + SHADER_STAGE_MAX, + SHADER_STAGE_VERTEX_BIT = (1 << SHADER_STAGE_VERTEX), + SHADER_STAGE_FRAGMENT_BIT = (1 << SHADER_STAGE_FRAGMENT), + SHADER_STAGE_TESSELATION_CONTROL_BIT = (1 << SHADER_STAGE_TESSELATION_CONTROL), + SHADER_STAGE_TESSELATION_EVALUATION_BIT = (1 << SHADER_STAGE_TESSELATION_EVALUATION), + SHADER_STAGE_COMPUTE_BIT = (1 << SHADER_STAGE_COMPUTE), + }; + + enum ShaderLanguage { + SHADER_LANGUAGE_GLSL, + SHADER_LANGUAGE_HLSL + }; + + typedef PoolVector<uint8_t> (*ShaderCompileFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error); + typedef PoolVector<uint8_t> (*ShaderCacheFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language); + +private: + static ShaderCompileFunction compile_function; + static ShaderCacheFunction cache_function; static RenderingDevice *singleton; @@ -497,29 +523,21 @@ public: /**** SHADER ****/ /****************/ - enum ShaderStage { - SHADER_STAGE_VERTEX, - SHADER_STAGE_FRAGMENT, - SHADER_STAGE_TESSELATION_CONTROL, - SHADER_STAGE_TESSELATION_EVALUATION, - SHADER_STAGE_COMPUTE, - SHADER_STAGE_MAX, - SHADER_STAGE_VERTEX_BIT = (1 << SHADER_STAGE_VERTEX), - SHADER_STAGE_FRAGMENT_BIT = (1 << SHADER_STAGE_FRAGMENT), - SHADER_STAGE_TESSELATION_CONTROL_BIT = (1 << SHADER_STAGE_TESSELATION_CONTROL), - SHADER_STAGE_TESSELATION_EVALUATION_BIT = (1 << SHADER_STAGE_TESSELATION_EVALUATION), - SHADER_STAGE_COMPUTE_BIT = (1 << SHADER_STAGE_COMPUTE), - }; + virtual PoolVector<uint8_t> shader_compile_from_source(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language = SHADER_LANGUAGE_GLSL, String *r_error = NULL, bool p_allow_cache = true); - struct ShaderStageSource { + static void shader_set_compile_function(ShaderCompileFunction p_function); + static void shader_set_cache_function(ShaderCacheFunction p_function); + + struct ShaderStageData { ShaderStage shader_stage; - String shader_source; - ShaderStageSource() { + PoolVector<uint8_t> spir_v; + + ShaderStageData() { shader_stage = SHADER_STAGE_VERTEX; } }; - virtual RID shader_create_from_source(const Vector<ShaderStageSource> &p_stages, String *r_error = NULL, ShaderStage *r_error_stage = NULL, bool p_allow_cache = true) = 0; + virtual RID shader_create(const Vector<ShaderStageData> &p_stages) = 0; virtual Vector<int> shader_get_vertex_input_locations_used(RID p_shader) = 0; /******************/ |