diff options
Diffstat (limited to 'servers/rendering')
8 files changed, 96 insertions, 49 deletions
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 885ea18151..5776414b14 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -280,7 +280,7 @@ void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderData for (int i = 1; i < mipmaps; i++) { RID source = dest; dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, v, i); - Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, v, i); + Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, i); if (can_use_storage) { copy_effects->make_mipmap(source, dest, msize); @@ -448,7 +448,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende float luminance_multiplier = _render_buffers_get_luminance_multiplier(); for (uint32_t l = 0; l < rb->get_view_count(); l++) { for (int i = 0; i < (max_glow_level + 1); i++) { - Size2i vp_size = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, l, i); + Size2i vp_size = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, i); if (i == 0) { RID luminance_texture; @@ -502,7 +502,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende tonemap.glow_levels[i] = environment_get_glow_levels(p_render_data->environment)[i]; } - Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, 0, 0); + Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, 0); tonemap.glow_texture_size.x = msize.width; tonemap.glow_texture_size.y = msize.height; tonemap.glow_use_bicubic_upscale = glow_bicubic_upscale; diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index f65676185c..96618c3352 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -586,6 +586,8 @@ void MeshStorage::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) { Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND(!mesh); mesh->custom_aabb = p_aabb; + + mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); } AABB MeshStorage::mesh_get_custom_aabb(RID p_mesh) const { @@ -1803,8 +1805,12 @@ void MeshStorage::multimesh_set_visible_instances(RID p_multimesh, int p_visible } if (multimesh->data_cache.size()) { - //there is a data cache.. + // There is a data cache, but we may need to update some sections. _multimesh_mark_all_dirty(multimesh, false, true); + int start = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances; + for (int i = start; i < p_visible; i++) { + _multimesh_mark_dirty(multimesh, i, true); + } } multimesh->visible_instances = p_visible; diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp index 255719183f..f5d6404f01 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp @@ -50,25 +50,19 @@ void RenderSceneBuffersRD::_bind_methods() { // ClassDB::bind_method(D_METHOD("create_texture_view", "context", "name", "view_name", "view"), &RenderSceneBuffersRD::has_texture); ClassDB::bind_method(D_METHOD("get_texture", "context", "name"), &RenderSceneBuffersRD::get_texture); // ClassDB::bind_method(D_METHOD("get_texture_format", "context", "name"), &RenderSceneBuffersRD::get_texture_format); - ClassDB::bind_method(D_METHOD("get_texture_slice", "context", "name", "layer", "mipmap"), &RenderSceneBuffersRD::get_texture_slice); - ClassDB::bind_method(D_METHOD("get_texture_slice_size", "context", "name", "layer", "mipmap"), &RenderSceneBuffersRD::get_texture_slice_size); + ClassDB::bind_method(D_METHOD("get_texture_slice", "context", "name", "layer", "mipmap", "layers", "mipmaps"), &RenderSceneBuffersRD::get_texture_slice); + ClassDB::bind_method(D_METHOD("get_texture_slice_size", "context", "name", "mipmap"), &RenderSceneBuffersRD::get_texture_slice_size); ClassDB::bind_method(D_METHOD("clear_context", "context"), &RenderSceneBuffersRD::clear_context); } void RenderSceneBuffersRD::update_sizes(NamedTexture &p_named_texture) { ERR_FAIL_COND(p_named_texture.texture.is_null()); - uint32_t size = p_named_texture.format.array_layers * p_named_texture.format.mipmaps; - p_named_texture.sizes.resize(size); + p_named_texture.sizes.resize(p_named_texture.format.mipmaps); Size2i mipmap_size = Size2i(p_named_texture.format.width, p_named_texture.format.height); - for (uint32_t mipmap = 0; mipmap < p_named_texture.format.mipmaps; mipmap++) { - for (uint32_t layer = 0; layer < p_named_texture.format.array_layers; layer++) { - uint32_t index = layer * p_named_texture.format.mipmaps + mipmap; - - p_named_texture.sizes.ptrw()[index] = mipmap_size; - } + p_named_texture.sizes.ptrw()[mipmap] = mipmap_size; mipmap_size.width = MAX(1, mipmap_size.width >> 1); mipmap_size.height = MAX(1, mipmap_size.height >> 1); @@ -324,7 +318,7 @@ const RD::TextureFormat RenderSceneBuffersRD::get_texture_format(const StringNam return named_textures[key].format; } -RID RenderSceneBuffersRD::get_texture_slice(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap) { +RID RenderSceneBuffersRD::get_texture_slice(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap, const uint32_t p_layers, const uint32_t p_mipmaps) { NTKey key(p_context, p_texture_name); // check if this is a known texture @@ -334,36 +328,41 @@ RID RenderSceneBuffersRD::get_texture_slice(const StringName &p_context, const S // check if we're in bounds ERR_FAIL_UNSIGNED_INDEX_V(p_layer, named_texture.format.array_layers, RID()); + ERR_FAIL_COND_V(p_layers == 0, RID()); + ERR_FAIL_COND_V(p_layer + p_layers > named_texture.format.array_layers, RID()); ERR_FAIL_UNSIGNED_INDEX_V(p_mipmap, named_texture.format.mipmaps, RID()); + ERR_FAIL_COND_V(p_mipmaps == 0, RID()); + ERR_FAIL_COND_V(p_mipmap + p_mipmaps > named_texture.format.mipmaps, RID()); - // if we don't have multiple layers or mipmaps, we can just return our texture as is - if (named_texture.format.array_layers == 1 && named_texture.format.mipmaps == 1) { + // asking the whole thing? just return the original + if (p_layer == 0 && p_mipmap == 0 && named_texture.format.array_layers == p_layers && named_texture.format.mipmaps == p_mipmaps) { return named_texture.texture; } - // get our index and make sure we have enough entries in our slices vector - uint32_t index = p_layer * named_texture.format.mipmaps + p_mipmap; - while (named_texture.slices.size() <= int(index)) { - named_texture.slices.push_back(RID()); + // see if we have this + NTSliceKey slice_key(p_layer, p_layers, p_mipmap, p_mipmaps); + if (named_texture.slices.has(slice_key)) { + return named_texture.slices[slice_key]; } - // create our slice if we don't have it already - if (named_texture.slices[index].is_null()) { - named_texture.slices.ptrw()[index] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), named_texture.texture, p_layer, p_mipmap); + // create our slice + RID &slice = named_texture.slices[slice_key]; + slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), named_texture.texture, p_layer, p_mipmap, p_mipmaps, p_layers > 1 ? RD::TEXTURE_SLICE_2D_ARRAY : RD::TEXTURE_SLICE_2D, p_layers); - Array arr; - arr.push_back(p_context); - arr.push_back(p_texture_name); - arr.push_back(itos(p_layer)); - arr.push_back(itos(p_mipmap)); - RD::get_singleton()->set_resource_name(named_texture.slices[index], String("RenderBuffer {0}/{1} slice {2}/{3}").format(arr)); - } + Array arr; + arr.push_back(p_context); + arr.push_back(p_texture_name); + arr.push_back(itos(p_layer)); + arr.push_back(itos(p_layers)); + arr.push_back(itos(p_mipmap)); + arr.push_back(itos(p_mipmaps)); + RD::get_singleton()->set_resource_name(slice, String("RenderBuffer {0}/{1}, layer {2}/{3}, mipmap {4}/{5}").format(arr)); // and return our slice - return named_texture.slices[index]; + return slice; } -Size2i RenderSceneBuffersRD::get_texture_slice_size(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap) { +Size2i RenderSceneBuffersRD::get_texture_slice_size(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_mipmap) { NTKey key(p_context, p_texture_name); // check if this is a known texture @@ -372,14 +371,10 @@ Size2i RenderSceneBuffersRD::get_texture_slice_size(const StringName &p_context, ERR_FAIL_COND_V(named_texture.texture.is_null(), Size2i()); // check if we're in bounds - ERR_FAIL_UNSIGNED_INDEX_V(p_layer, named_texture.format.array_layers, Size2i()); ERR_FAIL_UNSIGNED_INDEX_V(p_mipmap, named_texture.format.mipmaps, Size2i()); - // get our index - uint32_t index = p_layer * named_texture.format.mipmaps + p_mipmap; - - // and return our size - return named_texture.sizes[index]; + // return our size + return named_texture.sizes[p_mipmap]; } void RenderSceneBuffersRD::clear_context(const StringName &p_context) { diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h index 50fb06c0d9..9a299a3415 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h @@ -93,7 +93,6 @@ private: } static uint32_t hash(const NTKey &p_val) { - // FIXME, properly hash two stringnames together uint32_t h = p_val.context.hash(); h = hash_murmur3_one_32(p_val.buffer_name.hash(), h); return hash_fmix32(h); @@ -106,6 +105,33 @@ private: } }; + struct NTSliceKey { + uint32_t layer; + uint32_t layers; + uint32_t mipmap; + uint32_t mipmaps; + + bool operator==(const NTSliceKey &p_val) const { + return (layer == p_val.layer) && (layers == p_val.layers) && (mipmap == p_val.mipmap) && (mipmaps == p_val.mipmaps); + } + + static uint32_t hash(const NTSliceKey &p_val) { + uint32_t h = hash_murmur3_one_32(p_val.layer); + h = hash_murmur3_one_32(p_val.layers, h); + h = hash_murmur3_one_32(p_val.mipmap, h); + h = hash_murmur3_one_32(p_val.mipmaps, h); + return hash_fmix32(h); + } + + NTSliceKey() {} + NTSliceKey(uint32_t p_layer, uint32_t p_layers, uint32_t p_mipmap, uint32_t p_mipmaps) { + layer = p_layer; + layers = p_layers; + mipmap = p_mipmap; + mipmaps = p_mipmaps; + } + }; + struct NamedTexture { // Cache the data used to create our texture RD::TextureFormat format; @@ -113,7 +139,7 @@ private: // Our texture objects, slices are lazy (i.e. only created when requested). RID texture; - Vector<RID> slices; + mutable HashMap<NTSliceKey, RID, NTSliceKey> slices; Vector<Size2i> sizes; }; @@ -154,8 +180,8 @@ public: RID create_texture_view(const StringName &p_context, const StringName &p_texture_name, const StringName p_view_name, RD::TextureView p_view = RD::TextureView()); RID get_texture(const StringName &p_context, const StringName &p_texture_name) const; const RD::TextureFormat get_texture_format(const StringName &p_context, const StringName &p_texture_name) const; - RID get_texture_slice(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap); - Size2i get_texture_slice_size(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap); + RID get_texture_slice(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap, const uint32_t p_layers = 1, const uint32_t p_mipmaps = 1); + Size2i get_texture_slice_size(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_mipmap); void clear_context(const StringName &p_context); diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index 2ec75b03ef..c3eec83d44 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -485,6 +485,7 @@ public: singleton->_instance_queue_update(instance, true, false); } break; + case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: case Dependency::DEPENDENCY_CHANGED_MATERIAL: { singleton->_instance_queue_update(instance, false, true); } break; @@ -496,9 +497,6 @@ public: case Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE: { singleton->_instance_queue_update(instance, true, true); } break; - case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { - //ignored - } break; case Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR: { //requires repairing if (instance->indexer_id.is_valid()) { diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 08ca25b64b..9117669124 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -530,7 +530,7 @@ public: TEXTURE_SLICE_2D_ARRAY, }; - virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps = 1, TextureSliceType p_slice_type = TEXTURE_SLICE_2D) = 0; + virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps = 1, TextureSliceType p_slice_type = TEXTURE_SLICE_2D, uint32_t p_layers = 0) = 0; virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0; virtual Vector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer) = 0; // CPU textures will return immediately, while GPU textures will most likely force a flush diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 44c4ad6e56..2dc1c70064 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -1225,7 +1225,7 @@ void ShaderLanguage::clear() { char_idx = 0; error_set = false; error_str = ""; - last_const = false; + is_const_decl = false; while (nodes) { Node *n = nodes; nodes = nodes->next; @@ -3561,6 +3561,14 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Functio return false; } + if (is_const_decl && arg->type == Node::TYPE_VARIABLE) { + const VariableNode *var = static_cast<const VariableNode *>(arg); + if (!var->is_const) { + _set_error(RTR("Expected constant expression.")); + return false; + } + } + p_func->arguments.push_back(arg); tk = _get_token(); @@ -5184,6 +5192,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = func; } else { //a function call + if (p_block == nullptr) { // Non-constructor function call in global space is forbidden. + if (is_const_decl) { + _set_error(RTR("Expected constant expression.")); + } + return nullptr; + } const StringName &name = identifier; @@ -5460,6 +5474,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons _set_error(vformat(RTR("Unknown identifier in expression: '%s'."), String(identifier))); return nullptr; } + if (is_const_decl && !is_const) { + _set_error(RTR("Expected constant expression.")); + return nullptr; + } if (ident_type == IDENTIFIER_VARYING) { TkPos prev_pos = _get_tkpos(); Token next_token = _get_token(); @@ -6977,6 +6995,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun } } #endif // DEBUG_ENABLED + is_const_decl = is_const; BlockNode::Variable var; var.type = type; @@ -7233,6 +7252,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun vdnode->declarations.push_back(decl); p_block->variables[name] = var; + is_const_decl = false; if (!fixed_array_size) { array_size = 0; @@ -9101,6 +9121,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f constant.precision = precision; constant.initializer = nullptr; constant.array_size = array_size; + is_const_decl = true; if (tk.type == TK_BRACKET_OPEN) { Error error = _parse_array_size(nullptr, constants, false, nullptr, &constant.array_size, &unknown_size); @@ -9360,6 +9381,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f unknown_size = false; } else if (tk.type == TK_SEMICOLON) { + is_const_decl = false; break; } else { _set_expected_error(",", ";"); diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 32e497aa46..aea61e42c3 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -953,7 +953,7 @@ private: StringName shader_type_identifier; StringName current_function; - bool last_const = false; + bool is_const_decl = false; StringName last_name; bool is_shader_inc = false; |