summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_rd.cpp16
-rw-r--r--servers/visual/rasterizer_rd/shader_rd.cpp65
-rw-r--r--servers/visual/rendering_device.cpp31
-rw-r--r--servers/visual/rendering_device.h52
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;
/******************/