Add a system to properly update materials if the uniform set is gone (likely deleted texture)

This commit is contained in:
Juan Linietsky 2019-07-29 15:29:43 -03:00
parent c613ead5fa
commit 6ecedd1e6c
6 changed files with 40 additions and 8 deletions

View file

@ -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;
}

View file

@ -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;

View file

@ -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);

View file

@ -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;
}

View file

@ -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) {

View file

@ -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);