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
|
@ -1,6 +1,7 @@
|
||||||
#include "rasterizer_canvas_rd.h"
|
#include "rasterizer_canvas_rd.h"
|
||||||
#include "core/math/math_funcs.h"
|
#include "core/math/math_funcs.h"
|
||||||
#include "core/project_settings.h"
|
#include "core/project_settings.h"
|
||||||
|
#include "rasterizer_rd.h"
|
||||||
|
|
||||||
void RasterizerCanvasRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) {
|
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()) {
|
if (ci->material.is_valid()) {
|
||||||
MaterialData *md = (MaterialData *)storage->material_get_data(ci->material, RasterizerStorageRD::SHADER_TYPE_2D);
|
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 (md && md->shader_data->valid) {
|
||||||
if (!material_screen_texture_found) {
|
|
||||||
backbuffer_copy = true;
|
if (md->shader_data->uses_screen_texture) {
|
||||||
back_buffer_rect = Rect2();
|
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
|
if (md->last_frame != RasterizerRD::get_frame_number()) {
|
||||||
screen_uniform_set = storage->render_target_get_back_buffer_uniform_set(p_to_render_target, backbuffer_shader);
|
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) {
|
RasterizerStorageRD::MaterialData *RasterizerCanvasRD::_create_material_func(ShaderData *p_shader) {
|
||||||
MaterialData *material_data = memnew(MaterialData);
|
MaterialData *material_data = memnew(MaterialData);
|
||||||
material_data->shader_data = p_shader;
|
material_data->shader_data = p_shader;
|
||||||
|
material_data->last_frame = false;
|
||||||
//update will happen later anyway so do nothing.
|
//update will happen later anyway so do nothing.
|
||||||
return material_data;
|
return material_data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
#include "servers/visual/rasterizer.h"
|
#include "servers/visual/rasterizer.h"
|
||||||
#include "servers/visual/rasterizer_rd/rasterizer_storage_rd.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/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/shader_compiler_rd.h"
|
||||||
#include "servers/visual/rasterizer_rd/shaders/canvas.glsl.gen.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/rasterizer_rd/shaders/canvas_occlusion.glsl.gen.h"
|
||||||
|
#include "servers/visual/rendering_device.h"
|
||||||
|
|
||||||
class RasterizerCanvasRD : public RasterizerCanvas {
|
class RasterizerCanvasRD : public RasterizerCanvas {
|
||||||
|
|
||||||
|
@ -167,6 +167,7 @@ class RasterizerCanvasRD : public RasterizerCanvas {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MaterialData : public RasterizerStorageRD::MaterialData {
|
struct MaterialData : public RasterizerStorageRD::MaterialData {
|
||||||
|
uint64_t last_frame;
|
||||||
ShaderData *shader_data;
|
ShaderData *shader_data;
|
||||||
RID uniform_buffer;
|
RID uniform_buffer;
|
||||||
RID uniform_set;
|
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) {
|
void RasterizerRD::begin_frame(double frame_step) {
|
||||||
|
frame++;
|
||||||
time += frame_step;
|
time += frame_step;
|
||||||
canvas->set_time(time);
|
canvas->set_time(time);
|
||||||
}
|
}
|
||||||
|
@ -121,6 +122,7 @@ void RasterizerRD::initialize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadWorkPool RasterizerRD::thread_work_pool;
|
ThreadWorkPool RasterizerRD::thread_work_pool;
|
||||||
|
uint32_t RasterizerRD::frame = 1;
|
||||||
|
|
||||||
void RasterizerRD::finalize() {
|
void RasterizerRD::finalize() {
|
||||||
|
|
||||||
|
@ -139,6 +141,7 @@ void RasterizerRD::finalize() {
|
||||||
RasterizerRD::RasterizerRD() {
|
RasterizerRD::RasterizerRD() {
|
||||||
thread_work_pool.init();
|
thread_work_pool.init();
|
||||||
time = 0;
|
time = 0;
|
||||||
|
|
||||||
storage = memnew(RasterizerStorageRD);
|
storage = memnew(RasterizerStorageRD);
|
||||||
canvas = memnew(RasterizerCanvasRD(storage));
|
canvas = memnew(RasterizerCanvasRD(storage));
|
||||||
scene = memnew(RasterizerSceneForwardRD);
|
scene = memnew(RasterizerSceneForwardRD);
|
||||||
|
|
|
@ -24,6 +24,8 @@ protected:
|
||||||
|
|
||||||
double time;
|
double time;
|
||||||
|
|
||||||
|
static uint32_t frame;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RasterizerStorage *get_storage() { return storage; }
|
RasterizerStorage *get_storage() { return storage; }
|
||||||
RasterizerCanvas *get_canvas() { return canvas; }
|
RasterizerCanvas *get_canvas() { return canvas; }
|
||||||
|
@ -39,6 +41,8 @@ public:
|
||||||
void end_frame(bool p_swap_buffers);
|
void end_frame(bool p_swap_buffers);
|
||||||
void finalize();
|
void finalize();
|
||||||
|
|
||||||
|
static _ALWAYS_INLINE_ uint64_t get_frame_number() { return frame; }
|
||||||
|
|
||||||
static Error is_viable() {
|
static Error is_viable() {
|
||||||
return OK;
|
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() {
|
void RasterizerStorageRD::_update_queued_materials() {
|
||||||
Material *material = material_update_list;
|
Material *material = material_update_list;
|
||||||
while (material) {
|
while (material) {
|
||||||
|
|
|
@ -329,6 +329,7 @@ public:
|
||||||
bool material_casts_shadows(RID p_material);
|
bool material_casts_shadows(RID p_material);
|
||||||
|
|
||||||
void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance);
|
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);
|
void material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue