Skip to content

Commit

Permalink
Implement render_target_was_used API so that Viewports can properly c…
Browse files Browse the repository at this point in the history
…heck if they have been used.

For the RD renderer, this does not work for Viewports used in scene shaders yet
  • Loading branch information
clayjohn committed Dec 16, 2022
1 parent 47ef054 commit 2b34609
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 6 deletions.
14 changes: 13 additions & 1 deletion drivers/gles3/rasterizer_canvas_gles3.cpp
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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;
}
}
}

Expand Down Expand Up @@ -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();
Expand Down
12 changes: 12 additions & 0 deletions drivers/gles3/storage/material_storage.cpp
Expand Up @@ -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*
Expand Down Expand Up @@ -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*
Expand Down Expand Up @@ -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*
Expand Down Expand Up @@ -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*
Expand Down
2 changes: 1 addition & 1 deletion drivers/gles3/storage/particles_storage.cpp
Expand Up @@ -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
Expand Down
11 changes: 7 additions & 4 deletions drivers/gles3/storage/texture_storage.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions servers/rendering/renderer_rd/environment/fog.cpp
Expand Up @@ -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);
Expand Down
8 changes: 8 additions & 0 deletions servers/rendering/renderer_rd/environment/sky.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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();

Expand Down
Expand Up @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions servers/rendering/renderer_rd/storage_rd/material_storage.cpp
Expand Up @@ -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()) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
4 changes: 4 additions & 0 deletions servers/rendering/renderer_rd/storage_rd/material_storage.h
Expand Up @@ -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"
Expand Down Expand Up @@ -74,8 +76,10 @@ class MaterialStorage : public RendererMaterialStorage {
};

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;
Expand Down
Expand Up @@ -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));
Expand Down
17 changes: 17 additions & 0 deletions servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions servers/rendering/renderer_rd/storage_rd/texture_storage.h
Expand Up @@ -108,6 +108,8 @@ class TextureStorage : public RendererTextureStorage {

/* Texture API */

struct RenderTarget;

class Texture {
public:
TextureType type;
Expand Down Expand Up @@ -141,6 +143,7 @@ class TextureStorage : public RendererTextureStorage {
Vector<BufferSlice3D> buffer_slices_3d;
uint32_t buffer_size_3d = 0;

RenderTarget *render_target = nullptr;
bool is_render_target;
bool is_proxy;

Expand Down

0 comments on commit 2b34609

Please sign in to comment.