Add a system to properly update materials if the uniform set is gone (likely deleted texture)
This commit is contained in:
parent
c613ead5fa
commit
6ecedd1e6c
6 changed files with 40 additions and 8 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue