mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 12:12:28 +00:00
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:
parent
47ef0549ee
commit
1b330820bf
@ -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();
|
||||
|
@ -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*
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user