summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2019-07-29 15:29:43 -0300
committerJuan Linietsky <reduzio@gmail.com>2020-02-11 11:53:29 +0100
commit6ecedd1e6ca7d8b10b13a3dab19074fd51b17bcf (patch)
tree8b66186e969d81834ed5a24ec1b91fd3bc8d73ee
parentc613ead5fa2361296cf8d9a80d4648492ff4e16f (diff)
Add a system to properly update materials if the uniform set is gone (likely deleted texture)
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp27
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_canvas_rd.h3
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_rd.cpp3
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_rd.h4
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp10
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_storage_rd.h1
6 files changed, 40 insertions, 8 deletions
diff --git a/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp
index 9dd8f7ce50..44a8af236e 100644
--- a/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp
@@ -1,6 +1,7 @@
#include "rasterizer_canvas_rd.h"
#include "core/math/math_funcs.h"
#include "core/project_settings.h"
+#include "rasterizer_rd.h"
void RasterizerCanvasRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) {
@@ -1500,14 +1501,25 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
if (ci->material.is_valid()) {
MaterialData *md = (MaterialData *)storage->material_get_data(ci->material, RasterizerStorageRD::SHADER_TYPE_2D);
- if (md && md->shader_data->valid && md->shader_data->uses_screen_texture) {
- if (!material_screen_texture_found) {
- backbuffer_copy = true;
- back_buffer_rect = Rect2();
+ if (md && md->shader_data->valid) {
+
+ if (md->shader_data->uses_screen_texture) {
+ if (!material_screen_texture_found) {
+ backbuffer_copy = true;
+ back_buffer_rect = Rect2();
+ }
+ if (screen_uniform_set.is_null()) {
+ RID backbuffer_shader = shader.canvas_shader.version_get_shader(md->shader_data->version, 0); //any version is fine
+ screen_uniform_set = storage->render_target_get_back_buffer_uniform_set(p_to_render_target, backbuffer_shader);
+ }
}
- if (screen_uniform_set.is_null()) {
- RID backbuffer_shader = shader.canvas_shader.version_get_shader(md->shader_data->version, 0); //any version is fine
- screen_uniform_set = storage->render_target_get_back_buffer_uniform_set(p_to_render_target, backbuffer_shader);
+
+ if (md->last_frame != RasterizerRD::get_frame_number()) {
+ md->last_frame = RasterizerRD::get_frame_number();
+ if (!RD::get_singleton()->uniform_set_is_valid(md->uniform_set)) {
+ //textures may have been removed, hence invalidating this uniform set.
+ storage->material_force_update_textures(ci->material, RasterizerStorageRD::SHADER_TYPE_2D);
+ }
}
}
}
@@ -2149,6 +2161,7 @@ RasterizerCanvasRD::MaterialData::~MaterialData() {
RasterizerStorageRD::MaterialData *RasterizerCanvasRD::_create_material_func(ShaderData *p_shader) {
MaterialData *material_data = memnew(MaterialData);
material_data->shader_data = p_shader;
+ material_data->last_frame = false;
//update will happen later anyway so do nothing.
return material_data;
}
diff --git a/servers/visual/rasterizer_rd/rasterizer_canvas_rd.h b/servers/visual/rasterizer_rd/rasterizer_canvas_rd.h
index edb8007f5c..e8da79755b 100644
--- a/servers/visual/rasterizer_rd/rasterizer_canvas_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_canvas_rd.h
@@ -4,10 +4,10 @@
#include "servers/visual/rasterizer.h"
#include "servers/visual/rasterizer_rd/rasterizer_storage_rd.h"
#include "servers/visual/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h"
-#include "servers/visual/rendering_device.h"
#include "servers/visual/rasterizer_rd/shader_compiler_rd.h"
#include "servers/visual/rasterizer_rd/shaders/canvas.glsl.gen.h"
#include "servers/visual/rasterizer_rd/shaders/canvas_occlusion.glsl.gen.h"
+#include "servers/visual/rendering_device.h"
class RasterizerCanvasRD : public RasterizerCanvas {
@@ -167,6 +167,7 @@ class RasterizerCanvasRD : public RasterizerCanvas {
}
struct MaterialData : public RasterizerStorageRD::MaterialData {
+ uint64_t last_frame;
ShaderData *shader_data;
RID uniform_buffer;
RID uniform_set;
diff --git a/servers/visual/rasterizer_rd/rasterizer_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_rd.cpp
index 8a77d9a71e..682f87e519 100644
--- a/servers/visual/rasterizer_rd/rasterizer_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_rd.cpp
@@ -46,6 +46,7 @@ void RasterizerRD::blit_render_targets_to_screen(int p_screen, const BlitToScree
}
void RasterizerRD::begin_frame(double frame_step) {
+ frame++;
time += frame_step;
canvas->set_time(time);
}
@@ -121,6 +122,7 @@ void RasterizerRD::initialize() {
}
ThreadWorkPool RasterizerRD::thread_work_pool;
+uint32_t RasterizerRD::frame = 1;
void RasterizerRD::finalize() {
@@ -139,6 +141,7 @@ void RasterizerRD::finalize() {
RasterizerRD::RasterizerRD() {
thread_work_pool.init();
time = 0;
+
storage = memnew(RasterizerStorageRD);
canvas = memnew(RasterizerCanvasRD(storage));
scene = memnew(RasterizerSceneForwardRD);
diff --git a/servers/visual/rasterizer_rd/rasterizer_rd.h b/servers/visual/rasterizer_rd/rasterizer_rd.h
index f5ee7ddc76..b9151260c9 100644
--- a/servers/visual/rasterizer_rd/rasterizer_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_rd.h
@@ -24,6 +24,8 @@ protected:
double time;
+ static uint32_t frame;
+
public:
RasterizerStorage *get_storage() { return storage; }
RasterizerCanvas *get_canvas() { return canvas; }
@@ -39,6 +41,8 @@ public:
void end_frame(bool p_swap_buffers);
void finalize();
+ static _ALWAYS_INLINE_ uint64_t get_frame_number() { return frame; }
+
static Error is_viable() {
return OK;
}
diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
index fef3418d53..07cc6d6989 100644
--- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
@@ -1631,6 +1631,16 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va
}
}
+void RasterizerStorageRD::material_force_update_textures(RID p_material, ShaderType p_shader_type) {
+ Material *material = material_owner.getornull(p_material);
+ if (material->shader_type != p_shader_type) {
+ return;
+ }
+ if (material->data) {
+ material->data->update_parameters(material->params, false, true);
+ }
+}
+
void RasterizerStorageRD::_update_queued_materials() {
Material *material = material_update_list;
while (material) {
diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.h b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
index c05d9a41f6..13d3dcaf43 100644
--- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
@@ -329,6 +329,7 @@ public:
bool material_casts_shadows(RID p_material);
void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance);
+ void material_force_update_textures(RID p_material, ShaderType p_shader_type);
void material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function);