Implement render_target_was_used API so that Viewports can properly check if they have been used.

For the RD renderer, this does not work for Viewports used in scene shaders yet
This commit is contained in:
clayjohn 2022-12-15 16:07:00 -08:00
parent 47ef0549ee
commit 1b330820bf
16 changed files with 85 additions and 6 deletions

View File

@ -2101,6 +2101,9 @@ void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTe
if (t) {
ERR_FAIL_COND(!t->canvas_texture);
ct = t->canvas_texture;
if (t->render_target) {
t->render_target->used_in_frame = true;
}
} else {
ct = texture_storage->get_canvas_texture(p_texture);
}
@ -2128,6 +2131,9 @@ void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTe
glBindTexture(GL_TEXTURE_2D, texture->tex_id);
texture->gl_set_filter(filter);
texture->gl_set_repeat(repeat);
if (texture->render_target) {
texture->render_target->used_in_frame = true;
}
}
GLES3::Texture *normal_map = texture_storage->get_texture(ct->normal_map);
@ -2141,6 +2147,9 @@ void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTe
glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
normal_map->gl_set_filter(filter);
normal_map->gl_set_repeat(repeat);
if (normal_map->render_target) {
normal_map->render_target->used_in_frame = true;
}
}
GLES3::Texture *specular_map = texture_storage->get_texture(ct->specular);
@ -2154,6 +2163,9 @@ void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTe
glBindTexture(GL_TEXTURE_2D, specular_map->tex_id);
specular_map->gl_set_filter(filter);
specular_map->gl_set_repeat(repeat);
if (specular_map->render_target) {
specular_map->render_target->used_in_frame = true;
}
}
}
@ -2631,7 +2643,7 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
global_defines += "#define MAX_LIGHTS " + itos(data.max_lights_per_render) + "\n";
global_defines += "#define MAX_DRAW_DATA_INSTANCES " + itos(data.max_instances_per_batch) + "\n";
GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.initialize(global_defines);
GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.initialize(global_defines, 1);
data.canvas_shader_default_version = GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_create();
shadow_render.shader.initialize();

View File

@ -3027,6 +3027,9 @@ void CanvasMaterialData::bind_uniforms() {
Texture *texture = TextureStorage::get_singleton()->get_texture(textures[ti]);
glActiveTexture(GL_TEXTURE1 + ti); // Start at GL_TEXTURE1 because texture slot 0 is used by the base texture
glBindTexture(target_from_type[texture_uniforms[ti].type], texture->tex_id);
if (texture->render_target) {
texture->render_target->used_in_frame = true;
}
// Set sampler state here as the same texture can be used in multiple places with different flags
// Need to convert sampler state from ShaderLanguage::Texture* to RS::CanvasItemTexture*
@ -3194,6 +3197,9 @@ void SkyMaterialData::bind_uniforms() {
Texture *texture = TextureStorage::get_singleton()->get_texture(textures[ti]);
glActiveTexture(GL_TEXTURE0 + ti);
glBindTexture(target_from_type[texture_uniforms[ti].type], texture->tex_id);
if (texture->render_target) {
texture->render_target->used_in_frame = true;
}
// Set sampler state here as the same texture can be used in multiple places with different flags
// Need to convert sampler state from ShaderLanguage::Texture* to RS::CanvasItemTexture*
@ -3447,6 +3453,9 @@ void SceneMaterialData::bind_uniforms() {
Texture *texture = TextureStorage::get_singleton()->get_texture(textures[ti]);
glActiveTexture(GL_TEXTURE0 + ti);
glBindTexture(target_from_type[texture_uniforms[ti].type], texture->tex_id);
if (texture->render_target) {
texture->render_target->used_in_frame = true;
}
// Set sampler state here as the same texture can be used in multiple places with different flags
// Need to convert sampler state from ShaderLanguage::Texture* to RS::CanvasItemTexture*
@ -3562,6 +3571,9 @@ void ParticleProcessMaterialData::bind_uniforms() {
Texture *texture = TextureStorage::get_singleton()->get_texture(textures[ti]);
glActiveTexture(GL_TEXTURE1 + ti); // Start at GL_TEXTURE1 because texture slot 0 is reserved for the heightmap texture.
glBindTexture(target_from_type[texture_uniforms[ti].type], texture->tex_id);
if (texture->render_target) {
texture->render_target->used_in_frame = true;
}
// Set sampler state here as the same texture can be used in multiple places with different flags
// Need to convert sampler state from ShaderLanguage::Texture* to RS::CanvasItemTexture*

View File

@ -53,7 +53,7 @@ ParticlesStorage::ParticlesStorage() {
{
String global_defines;
global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now
material_storage->shaders.particles_process_shader.initialize(global_defines);
material_storage->shaders.particles_process_shader.initialize(global_defines, 1);
}
{
// default material and shader for particles shader

View File

@ -1606,9 +1606,9 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
return;
}
if (rt->overridden.color.is_valid()) {
texture->is_render_target = true;
} else {
texture->is_render_target = true;
texture->render_target = rt;
if (rt->overridden.color.is_null()) {
texture->format = rt->image_format;
texture->real_format = rt->image_format;
texture->target = texture_target;
@ -1717,9 +1717,12 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
tex->width = 0;
tex->height = 0;
tex->active = false;
tex->render_target = nullptr;
tex->is_render_target = false;
}
} else {
Texture *tex = get_texture(rt->overridden.color);
tex->render_target = nullptr;
tex->is_render_target = false;
}
@ -1751,7 +1754,7 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
RID TextureStorage::render_target_create() {
RenderTarget render_target;
//render_target.was_used = false;
render_target.used_in_frame = false;
render_target.clear_requested = false;
Texture t;

View File

@ -699,6 +699,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, volumetric_fog.base_uniform_set, VolumetricFogShader::FogSet::FOG_SET_BASE);
if (material->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material->uniform_set)) { // Material may not have a uniform set.
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, material->uniform_set, VolumetricFogShader::FogSet::FOG_SET_MATERIAL);
material->set_as_used();
}
RD::get_singleton()->compute_list_dispatch_threads(compute_list, kernel_size.x, kernel_size.y, kernel_size.z);

View File

@ -1053,6 +1053,8 @@ void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const P
ERR_FAIL_COND(!shader_data);
material->set_as_used();
// Invalidate supbass buffers if screen size changes
if (sky->screen_size != p_screen_size) {
sky->screen_size = p_screen_size;
@ -1453,6 +1455,8 @@ void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth
ERR_FAIL_COND(!shader_data);
material->set_as_used();
Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env);
sky_transform.invert();
@ -1550,6 +1554,8 @@ void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projectio
ERR_FAIL_COND(!shader_data);
material->set_as_used();
Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env);
sky_transform.invert();
@ -1643,6 +1649,8 @@ void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_vie
ERR_FAIL_COND(!shader_data);
material->set_as_used();
Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env);
sky_transform.invert();

View File

@ -348,6 +348,7 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
#endif
material_uniform_set = surf->material_uniform_set;
shader = surf->shader;
surf->material->set_as_used();
#ifdef DEBUG_ENABLED
}
#endif
@ -3378,6 +3379,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet
sdcache->flags = flags;
sdcache->shader = p_material->shader_data;
sdcache->material = p_material;
sdcache->material_uniform_set = p_material->uniform_set;
sdcache->surface = mesh_storage->mesh_get_surface(p_mesh, p_surface);
sdcache->primitive = mesh_storage->mesh_surface_get_primitive(sdcache->surface);

View File

@ -441,6 +441,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
void *surface = nullptr;
RID material_uniform_set;
SceneShaderForwardClustered::ShaderData *shader = nullptr;
SceneShaderForwardClustered::MaterialData *material = nullptr;
void *surface_shadow = nullptr;
RID material_uniform_set_shadow;

View File

@ -2092,6 +2092,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
#endif
material_uniform_set = surf->material_uniform_set;
shader = surf->shader;
surf->material->set_as_used();
#ifdef DEBUG_ENABLED
}
#endif
@ -2407,6 +2408,7 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI
sdcache->flags = flags;
sdcache->shader = p_material->shader_data;
sdcache->material = p_material;
sdcache->material_uniform_set = p_material->uniform_set;
sdcache->surface = mesh_storage->mesh_get_surface(p_mesh, p_surface);
sdcache->primitive = mesh_storage->mesh_surface_get_primitive(sdcache->surface);

View File

@ -440,6 +440,7 @@ protected:
void *surface = nullptr;
RID material_uniform_set;
SceneShaderForwardMobile::ShaderData *shader = nullptr;
SceneShaderForwardMobile::MaterialData *material = nullptr;
void *surface_shadow = nullptr;
RID material_uniform_set_shadow;

View File

@ -1136,6 +1136,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
// Update uniform set.
if (material_data->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material_data->uniform_set)) { // Material may not have a uniform set.
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material_data->uniform_set, MATERIAL_UNIFORM_SET);
material_data->set_as_used();
}
} else {
pipeline_variants = &shader.pipeline_variants;

View File

@ -1319,6 +1319,10 @@ void MaterialStorage::MaterialData::update_textures(const HashMap<StringName, Va
roughness_detect_texture = tex;
roughness_channel = RS::TextureDetectRoughnessChannel(p_texture_uniforms[i].hint - ShaderLanguage::ShaderNode::Uniform::HINT_ROUGHNESS_R);
}
if (tex->render_target) {
tex->render_target->was_used = true;
render_target_cache.push_back(tex->render_target);
}
#endif
}
if (rd_texture.is_null()) {
@ -1405,6 +1409,7 @@ bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap<
if ((uint32_t)texture_cache.size() != tex_uniform_count || p_textures_dirty) {
texture_cache.resize(tex_uniform_count);
render_target_cache.clear();
p_textures_dirty = true;
//clear previous uniform set
@ -1465,6 +1470,12 @@ bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap<
return true;
}
void MaterialStorage::MaterialData::set_as_used() {
for (int i = 0; i < render_target_cache.size(); i++) {
render_target_cache[i]->was_used = true;
}
}
///////////////////////////////////////////////////////////////////////////
// MaterialStorage

View File

@ -31,6 +31,8 @@
#ifndef MATERIAL_STORAGE_RD_H
#define MATERIAL_STORAGE_RD_H
#include "texture_storage.h"
#include "core/math/projection.h"
#include "core/templates/local_vector.h"
#include "core/templates/rid_owner.h"
@ -74,8 +76,10 @@ public:
};
struct MaterialData {
Vector<RendererRD::TextureStorage::RenderTarget *> render_target_cache;
void update_uniform_buffer(const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const HashMap<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color);
void update_textures(const HashMap<StringName, Variant> &p_parameters, const HashMap<StringName, HashMap<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color);
void set_as_used();
virtual void set_render_priority(int p_priority) = 0;
virtual void set_next_pass(RID p_pass) = 0;

View File

@ -1107,6 +1107,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
if (m->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(m->uniform_set)) {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, m->uniform_set, 3);
m->set_as_used();
}
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ParticlesShader::PushConstant));

View File

@ -581,6 +581,9 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte
}
ct = t->canvas_texture;
if (t->render_target) {
t->render_target->was_used = true;
}
} else {
ct = canvas_texture_owner.get_or_null(p_texture);
}
@ -611,6 +614,9 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte
} else {
u.append_id(t->rd_texture);
ct->size_cache = Size2i(t->width_2d, t->height_2d);
if (t->render_target) {
t->render_target->was_used = true;
}
}
uniforms.push_back(u);
}
@ -626,6 +632,9 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte
} else {
u.append_id(t->rd_texture);
ct->use_normal_cache = true;
if (t->render_target) {
t->render_target->was_used = true;
}
}
uniforms.push_back(u);
}
@ -641,6 +650,9 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte
} else {
u.append_id(t->rd_texture);
ct->use_specular_cache = true;
if (t->render_target) {
t->render_target->was_used = true;
}
}
uniforms.push_back(u);
}
@ -2398,6 +2410,10 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
rt->color = RID();
rt->color_multisample = RID();
if (rt->texture.is_valid()) {
Texture *tex = get_texture(rt->texture);
tex->render_target = nullptr;
}
}
void TextureStorage::_update_render_target(RenderTarget *rt) {
@ -2478,6 +2494,7 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
tex->rd_texture = RID();
tex->rd_texture_srgb = RID();
tex->render_target = rt;
//create shared textures to the color buffer,
//so transparent can be supported

View File

@ -108,6 +108,8 @@ private:
/* Texture API */
struct RenderTarget;
class Texture {
public:
TextureType type;
@ -141,6 +143,7 @@ private:
Vector<BufferSlice3D> buffer_slices_3d;
uint32_t buffer_size_3d = 0;
RenderTarget *render_target = nullptr;
bool is_render_target;
bool is_proxy;