diff options
Diffstat (limited to 'servers/rendering/renderer_rd/renderer_canvas_render_rd.h')
-rw-r--r-- | servers/rendering/renderer_rd/renderer_canvas_render_rd.h | 169 |
1 files changed, 83 insertions, 86 deletions
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 8d90cd23ce..07445b5c53 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -34,6 +34,7 @@ #include "servers/rendering/renderer_canvas_render.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" +#include "servers/rendering/renderer_rd/pipeline_hash_map_rd.h" #include "servers/rendering/renderer_rd/shaders/canvas.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl.gen.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" @@ -45,8 +46,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { BASE_UNIFORM_SET = 0, MATERIAL_UNIFORM_SET = 1, TRANSFORMS_UNIFORM_SET = 2, - CANVAS_TEXTURE_UNIFORM_SET = 3, - INSTANCE_DATA_UNIFORM_SET = 4, + BATCH_UNIFORM_SET = 3, }; const int SAMPLERS_BINDING_FIRST_INDEX = 10; @@ -58,12 +58,6 @@ class RendererCanvasRenderRD : public RendererCanvasRender { SHADER_VARIANT_PRIMITIVE_POINTS, SHADER_VARIANT_ATTRIBUTES, SHADER_VARIANT_ATTRIBUTES_POINTS, - SHADER_VARIANT_QUAD_LIGHT, - SHADER_VARIANT_NINEPATCH_LIGHT, - SHADER_VARIANT_PRIMITIVE_LIGHT, - SHADER_VARIANT_PRIMITIVE_POINTS_LIGHT, - SHADER_VARIANT_ATTRIBUTES_LIGHT, - SHADER_VARIANT_ATTRIBUTES_POINTS_LIGHT, SHADER_VARIANT_MAX }; @@ -85,14 +79,14 @@ class RendererCanvasRenderRD : public RendererCanvasRender { FLAGS_NINEPATCH_V_MODE_SHIFT = 18, FLAGS_LIGHT_COUNT_SHIFT = 20, - FLAGS_DEFAULT_NORMAL_MAP_USED = (1 << 26), - FLAGS_DEFAULT_SPECULAR_MAP_USED = (1 << 27), + FLAGS_DEFAULT_NORMAL_MAP_USED = (1 << 24), + FLAGS_DEFAULT_SPECULAR_MAP_USED = (1 << 25), - FLAGS_USE_MSDF = (1 << 28), - FLAGS_USE_LCD = (1 << 29), + FLAGS_USE_MSDF = (1 << 26), + FLAGS_USE_LCD = (1 << 27), - FLAGS_FLIP_H = (1 << 30), - FLAGS_FLIP_V = (1 << 31), + FLAGS_FLIP_H = (1 << 28), + FLAGS_FLIP_V = (1 << 29), }; enum { @@ -119,76 +113,82 @@ class RendererCanvasRenderRD : public RendererCanvasRender { /**** SHADER ****/ /****************/ - enum PipelineVariant { - PIPELINE_VARIANT_QUAD, - PIPELINE_VARIANT_NINEPATCH, - PIPELINE_VARIANT_PRIMITIVE_TRIANGLES, - PIPELINE_VARIANT_PRIMITIVE_LINES, - PIPELINE_VARIANT_PRIMITIVE_POINTS, - PIPELINE_VARIANT_ATTRIBUTE_TRIANGLES, - PIPELINE_VARIANT_ATTRIBUTE_TRIANGLE_STRIP, - PIPELINE_VARIANT_ATTRIBUTE_LINES, - PIPELINE_VARIANT_ATTRIBUTE_LINES_STRIP, - PIPELINE_VARIANT_ATTRIBUTE_POINTS, - PIPELINE_VARIANT_QUAD_LCD_BLEND, - PIPELINE_VARIANT_MAX - }; - enum PipelineLightMode { - PIPELINE_LIGHT_MODE_DISABLED, - PIPELINE_LIGHT_MODE_ENABLED, - PIPELINE_LIGHT_MODE_MAX - }; + struct ShaderSpecialization { + union { + struct { + uint32_t use_lighting : 1; + }; - struct PipelineVariants { - PipelineCacheRD variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX]; + uint32_t packed_0; + }; }; - struct { - CanvasShaderRD canvas_shader; - RID default_version; - RID default_version_rd_shader; - RID quad_index_buffer; - RID quad_index_array; - PipelineVariants pipeline_variants; - - ShaderCompiler compiler; - } shader; + struct PipelineKey { + ShaderVariant variant = SHADER_VARIANT_MAX; + RD::FramebufferFormatID framebuffer_format_id = RD::INVALID_FORMAT_ID; + RD::VertexFormatID vertex_format_id = RD::INVALID_ID; + RD::RenderPrimitive render_primitive = RD::RENDER_PRIMITIVE_MAX; + ShaderSpecialization shader_specialization = {}; + uint32_t lcd_blend = 0; + uint32_t ubershader = 0; + + uint32_t hash() const { + uint32_t h = hash_murmur3_one_32(variant); + h = hash_murmur3_one_32(framebuffer_format_id, h); + h = hash_murmur3_one_32(vertex_format_id, h); + h = hash_murmur3_one_32(render_primitive, h); + h = hash_murmur3_one_32(shader_specialization.packed_0, h); + h = hash_murmur3_one_32(lcd_blend, h); + h = hash_murmur3_one_32(ubershader, h); + return hash_fmix32(h); + } + }; struct CanvasShaderData : public RendererRD::MaterialStorage::ShaderData { - enum BlendMode { //used internally - BLEND_MODE_MIX, - BLEND_MODE_ADD, - BLEND_MODE_SUB, - BLEND_MODE_MUL, - BLEND_MODE_PMALPHA, - BLEND_MODE_DISABLED, - }; - - bool valid = false; - RID version; - PipelineVariants pipeline_variants; - Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; + int blend_mode = 0; Vector<uint32_t> ubo_offsets; uint32_t ubo_size = 0; String code; + RID version; + PipelineHashMapRD<PipelineKey, CanvasShaderData, void (CanvasShaderData::*)(PipelineKey)> pipeline_hash_map; + + static const uint32_t VERTEX_INPUT_MASKS_SIZE = SHADER_VARIANT_MAX * 2; + std::atomic<uint64_t> vertex_input_masks[VERTEX_INPUT_MASKS_SIZE] = {}; bool uses_screen_texture = false; bool uses_screen_texture_mipmaps = false; bool uses_sdf = false; bool uses_time = false; + void _clear_vertex_input_mask_cache(); + void _create_pipeline(PipelineKey p_pipeline_key); virtual void set_code(const String &p_Code); virtual bool is_animated() const; virtual bool casts_shadows() const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; + RID get_shader(ShaderVariant p_shader_variant, bool p_ubershader) const; + uint64_t get_vertex_input_mask(ShaderVariant p_shader_variant, bool p_ubershader); + bool is_valid() const; - CanvasShaderData() {} + CanvasShaderData(); virtual ~CanvasShaderData(); }; + struct { + // Data must be guaranteed to be erased before the rest on the destructor. + CanvasShaderData *default_version_data = nullptr; + CanvasShaderRD canvas_shader; + RID default_version_rd_shader; + RID quad_index_buffer; + RID quad_index_array; + ShaderCompiler compiler; + uint32_t pipeline_compilations[RS::PIPELINE_SOURCE_MAX] = {}; + Mutex mutex; + } shader; + RendererRD::MaterialStorage::ShaderData *_create_shader_func(); static RendererRD::MaterialStorage::ShaderData *_create_shader_funcs() { return static_cast<RendererCanvasRenderRD *>(singleton)->_create_shader_func(); @@ -365,7 +365,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { struct PushConstant { uint32_t base_instance_index; - uint32_t pad1; + ShaderSpecialization shader_specialization; uint32_t pad2; uint32_t pad3; }; @@ -423,24 +423,25 @@ class RendererCanvasRenderRD : public RendererCanvasRender { } }; + struct TextureInfo { + TextureState state; + uint32_t specular_shininess = 0; + uint32_t flags = 0; + Vector2 texpixel_size; + + RID diffuse; + RID normal; + RID specular; + RID sampler; + }; + struct Batch { // Position in the UBO measured in bytes uint32_t start = 0; uint32_t instance_count = 0; uint32_t instance_buffer_index = 0; - TextureState tex_state; - RID tex_uniform_set; - - // The following tex_ prefixed fields are used to cache the texture data for the current batch. - // These values are applied to new InstanceData for the batch - - // The cached specular shininess derived from the current texture. - uint32_t tex_specular_shininess = 0; - // The cached texture flags, such as FLAGS_DEFAULT_SPECULAR_MAP_USED and FLAGS_DEFAULT_NORMAL_MAP_USED - uint32_t tex_flags = 0; - // The cached texture pixel size. - Vector2 tex_texpixel_size; + TextureInfo tex_info; Color modulate = Color(1.0, 1.0, 1.0, 1.0); @@ -448,11 +449,12 @@ class RendererCanvasRenderRD : public RendererCanvasRender { RID material; CanvasMaterialData *material_data = nullptr; - PipelineLightMode light_mode = PipelineLightMode::PIPELINE_LIGHT_MODE_DISABLED; - PipelineVariant pipeline_variant = PipelineVariant::PIPELINE_VARIANT_QUAD; const Item::Command *command = nullptr; Item::Command::Type command_type = Item::Command::TYPE_ANIMATION_SLICE; // Can default to any type that doesn't form a batch. + ShaderVariant shader_variant = SHADER_VARIANT_QUAD; + RD::RenderPrimitive render_primitive = RD::RENDER_PRIMITIVE_TRIANGLES; + bool use_lighting = false; // batch-specific data union { @@ -462,14 +464,6 @@ class RendererCanvasRenderRD : public RendererCanvasRender { uint32_t mesh_instance_count; }; bool has_blend = false; - - void set_tex_state(TextureState &p_tex_state) { - tex_state = p_tex_state; - tex_uniform_set = RID(); - tex_texpixel_size = Size2(); - tex_specular_shininess = 0; - tex_flags = 0; - } }; struct DataBuffer { @@ -509,7 +503,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { uint32_t max_instances_per_buffer = 16384; uint32_t max_instance_buffer_size = 16384 * sizeof(InstanceData); - RID current_tex_uniform_set; + RID current_batch_uniform_set; LightUniform *light_uniforms = nullptr; @@ -532,6 +526,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender { Item *items[MAX_RENDER_ITEMS]; + TextureInfo default_texture_info; + bool using_directional_lights = false; RID default_canvas_texture; @@ -558,11 +554,11 @@ class RendererCanvasRenderRD : public RendererCanvasRender { uint32_t base_flags = 0; }; + inline RID _get_pipeline_specialization_or_ubershader(CanvasShaderData *p_shader_data, PipelineKey &r_pipeline_key, PushConstant &r_push_constant, RID p_mesh_instance = RID(), void *p_surface = nullptr, uint32_t p_surface_index = 0, RID *r_vertex_array = nullptr); void _render_batch_items(RenderTarget p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer = false, RenderingMethod::RenderInfo *r_render_info = nullptr); void _record_item_commands(const Item *p_item, RenderTarget p_render_target, const Transform2D &p_base_transform, Item *&r_current_clip, Light *p_lights, uint32_t &r_index, bool &r_batch_broken, bool &r_sdf_used, Batch *&r_current_batch); - void _render_batch(RD::DrawListID p_draw_list, PipelineVariants *p_pipeline_variants, RenderingDevice::FramebufferFormatID p_framebuffer_format, Light *p_lights, Batch const *p_batch, RenderingMethod::RenderInfo *r_render_info = nullptr); - void _prepare_batch_texture(Batch *p_current_batch, RID p_texture) const; - void _bind_canvas_texture(RD::DrawListID p_draw_list, RID p_uniform_set); + void _render_batch(RD::DrawListID p_draw_list, CanvasShaderData *p_shader_data, RenderingDevice::FramebufferFormatID p_framebuffer_format, Light *p_lights, Batch const *p_batch, RenderingMethod::RenderInfo *r_render_info = nullptr); + void _prepare_batch_texture_info(Batch *p_current_batch, RID p_texture) const; [[nodiscard]] Batch *_new_batch(bool &r_batch_broken); void _add_to_batch(uint32_t &r_index, bool &r_batch_broken, Batch *&r_current_batch); void _allocate_instance_buffer(); @@ -596,6 +592,7 @@ public: virtual void set_shadow_texture_size(int p_size) override; void set_debug_redraw(bool p_enabled, double p_time, const Color &p_color) override; + uint32_t get_pipeline_compilations(RS::PipelineSource p_source) override; void set_time(double p_time); void update() override; |