diff options
Diffstat (limited to 'servers/visual/rasterizer')
-rw-r--r-- | servers/visual/rasterizer/rasterizer.h | 15 | ||||
-rw-r--r-- | servers/visual/rasterizer/rasterizer_canvas_rd.cpp | 562 | ||||
-rw-r--r-- | servers/visual/rasterizer/rasterizer_canvas_rd.h | 79 | ||||
-rw-r--r-- | servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.cpp | 50 | ||||
-rw-r--r-- | servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h | 22 | ||||
-rw-r--r-- | servers/visual/rasterizer/shader_rd.cpp | 6 | ||||
-rw-r--r-- | servers/visual/rasterizer/shader_rd.h | 3 | ||||
-rw-r--r-- | servers/visual/rasterizer/shaders/SCsub | 1 | ||||
-rw-r--r-- | servers/visual/rasterizer/shaders/canvas.glsl | 58 | ||||
-rw-r--r-- | servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl | 99 | ||||
-rw-r--r-- | servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl | 47 |
11 files changed, 493 insertions, 449 deletions
diff --git a/servers/visual/rasterizer/rasterizer.h b/servers/visual/rasterizer/rasterizer.h index 88520a6a79..46695f5647 100644 --- a/servers/visual/rasterizer/rasterizer.h +++ b/servers/visual/rasterizer/rasterizer.h @@ -618,7 +618,6 @@ public: RID canvas; bool use_shadow; int shadow_buffer_size; - float shadow_gradient_length; VS::CanvasLightShadowFilter shadow_filter; Color shadow_color; float shadow_smooth; @@ -638,10 +637,12 @@ public: Light *mask_next_ptr; RID light_internal; + uint64_t version; int32_t render_index_cache; Light() { + version = 0; enabled = true; color = Color(1, 1, 1); shadow_color = Color(0, 0, 0, 0); @@ -661,7 +662,6 @@ public: filter_next_ptr = NULL; use_shadow = false; shadow_buffer_size = 2048; - shadow_gradient_length = 0; shadow_filter = VS::CANVAS_LIGHT_FILTER_NONE; shadow_smooth = 0.0; render_index_cache = -1; @@ -1064,6 +1064,13 @@ public: return command; } + struct CustomData { + + virtual ~CustomData() {} + }; + + mutable CustomData *custom_data; //implementation dependent + void clear() { Command *c = commands; while (c) { @@ -1112,6 +1119,7 @@ public: light_masked = false; update_when_visible = false; z_final = 0; + custom_data = NULL; } virtual ~Item() { clear(); @@ -1119,6 +1127,9 @@ public: memfree(blocks[i].memory); } if (copy_back_buffer) memdelete(copy_back_buffer); + if (custom_data) { + memdelete(custom_data); + } } }; diff --git a/servers/visual/rasterizer/rasterizer_canvas_rd.cpp b/servers/visual/rasterizer/rasterizer_canvas_rd.cpp index d09b353007..93f905b72b 100644 --- a/servers/visual/rasterizer/rasterizer_canvas_rd.cpp +++ b/servers/visual/rasterizer/rasterizer_canvas_rd.cpp @@ -225,42 +225,34 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int // that need to be created for these formats. uint32_t vertex_count = p_points.size(); - uint32_t base_offset = 0; uint32_t stride = 2; //vertices always repeat - if ((uint32_t)p_colors.size() == vertex_count) { + if ((uint32_t)p_colors.size() == vertex_count || p_colors.size() == 1) { stride += 4; - } else { - base_offset += 4; } if ((uint32_t)p_uvs.size() == vertex_count) { stride += 2; - } else { - base_offset += 2; } if ((uint32_t)p_bones.size() == vertex_count * 4) { stride += 4; - } else { - base_offset += 4; } if ((uint32_t)p_weights.size() == vertex_count * 4) { stride += 4; - } else { - base_offset += 4; } - uint32_t buffer_size = base_offset + stride * p_points.size(); + uint32_t buffer_size = stride * p_points.size(); PoolVector<uint8_t> polygon_buffer; polygon_buffer.resize(buffer_size * sizeof(float)); Vector<RD::VertexDescription> descriptions; descriptions.resize(5); + Vector<RID> buffers; + buffers.resize(5); { PoolVector<uint8_t>::Read r = polygon_buffer.read(); float *fptr = (float *)r.ptr(); uint32_t *uptr = (uint32_t *)r.ptr(); - uint32_t single_offset = 0; - + uint32_t base_offset = 0; { //vertices RD::VertexDescription vd; vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; @@ -281,7 +273,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int } //colors - if ((uint32_t)p_colors.size() == vertex_count) { + if ((uint32_t)p_colors.size() == vertex_count || p_colors.size() == 1) { RD::VertexDescription vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; vd.offset = base_offset * sizeof(float); @@ -290,31 +282,34 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int descriptions.write[1] = vd; - const Color *color_ptr = p_colors.ptr(); + if (p_colors.size() == 1) { + Color color = p_colors[0]; + for (uint32_t i = 0; i < vertex_count; i++) { + fptr[base_offset + i * stride + 0] = color.r; + fptr[base_offset + i * stride + 1] = color.g; + fptr[base_offset + i * stride + 2] = color.b; + fptr[base_offset + i * stride + 3] = color.a; + } + } else { + const Color *color_ptr = p_colors.ptr(); - for (uint32_t i = 0; i < vertex_count; i++) { - fptr[base_offset + i * stride + 0] = color_ptr[i].r; - fptr[base_offset + i * stride + 1] = color_ptr[i].g; - fptr[base_offset + i * stride + 2] = color_ptr[i].b; - fptr[base_offset + i * stride + 3] = color_ptr[i].a; + for (uint32_t i = 0; i < vertex_count; i++) { + fptr[base_offset + i * stride + 0] = color_ptr[i].r; + fptr[base_offset + i * stride + 1] = color_ptr[i].g; + fptr[base_offset + i * stride + 2] = color_ptr[i].b; + fptr[base_offset + i * stride + 3] = color_ptr[i].a; + } } base_offset += 4; } else { RD::VertexDescription vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; - vd.offset = single_offset * sizeof(float); + vd.offset = 0; vd.location = VS::ARRAY_COLOR; vd.stride = 0; descriptions.write[1] = vd; - - Color color = p_colors.size() ? p_colors[0] : Color(1, 1, 1, 1); - fptr[single_offset + 0] = color.r; - fptr[single_offset + 1] = color.g; - fptr[single_offset + 2] = color.b; - fptr[single_offset + 3] = color.a; - - single_offset += 4; + buffers.write[1] = polygon_buffers.default_color_buffer; } //uvs @@ -337,17 +332,12 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int } else { RD::VertexDescription vd; vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; - vd.offset = single_offset * sizeof(float); + vd.offset = 0; vd.location = VS::ARRAY_TEX_UV; vd.stride = 0; descriptions.write[2] = vd; - - Vector2 uv; - fptr[single_offset + 0] = uv.x; - fptr[single_offset + 1] = uv.y; - - single_offset += 2; + buffers.write[2] = polygon_buffers.default_uv_buffer; } //bones @@ -373,17 +363,12 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int } else { RD::VertexDescription vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; - vd.offset = single_offset * sizeof(float); + vd.offset = 0; vd.location = VS::ARRAY_BONES; vd.stride = 0; descriptions.write[3] = vd; - - uptr[single_offset + 0] = 0; - uptr[single_offset + 1] = 0; - uptr[single_offset + 2] = 0; - uptr[single_offset + 3] = 0; - single_offset += 4; + buffers.write[3] = polygon_buffers.default_bone_buffer; } //bones @@ -409,22 +394,16 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int } else { RD::VertexDescription vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; - vd.offset = single_offset * sizeof(float); + vd.offset = 0; vd.location = VS::ARRAY_WEIGHTS; vd.stride = 0; descriptions.write[4] = vd; - - fptr[single_offset + 0] = 0.0; - fptr[single_offset + 1] = 0.0; - fptr[single_offset + 2] = 0.0; - fptr[single_offset + 3] = 0.0; - single_offset += 4; + buffers.write[4] = polygon_buffers.default_weight_buffer; } //check that everything is as it should be - ERR_FAIL_COND_V(single_offset != (base_offset - stride), 0); - ERR_FAIL_COND_V(((base_offset - stride) + stride * vertex_count) != buffer_size, 0); + ERR_FAIL_COND_V(base_offset != stride, 0); //bug } RD::VertexFormatID vertex_id = RD::get_singleton()->vertex_format_create(descriptions); @@ -432,11 +411,12 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int PolygonBuffers pb; pb.vertex_buffer = RD::get_singleton()->vertex_buffer_create(polygon_buffer.size(), polygon_buffer); - Vector<RID> buffers; - buffers.resize(descriptions.size()); for (int i = 0; i < descriptions.size(); i++) { - buffers.write[i] = pb.vertex_buffer; + if (buffers[i] == RID()) { //if put in vertex, use as vertex + buffers.write[i] = pb.vertex_buffer; + } } + pb.vertex_array = RD::get_singleton()->vertex_array_create(p_points.size(), vertex_id, buffers); if (p_indices.size()) { @@ -508,9 +488,10 @@ Size2i RasterizerCanvasRD::_bind_texture_binding(TextureBindingID p_binding, RD: } //////////////////// -void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RenderTargetFormat p_render_target_format, RD::TextureSamples p_samples, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights) { +void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights) { //create an empty push constant + PushConstant push_constant; Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform; _update_transform_2d_to_mat2x3(base_transform, push_constant.world); @@ -538,30 +519,190 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ uint32_t base_flags = 0; + bool light_uniform_set_dirty = false; + + if (!p_item->custom_data) { + p_item->custom_data = memnew(ItemStateData); + light_uniform_set_dirty = true; + } + + ItemStateData *state_data = (ItemStateData *)p_item->custom_data; + + Light *light_cache[DEFAULT_MAX_LIGHTS_PER_ITEM]; + uint16_t light_count = 0; + PipelineLightMode light_mode; + { + Light *light = p_lights; - uint16_t light_count = 0; while (light) { if (light->render_index_cache >= 0 && p_item->light_mask & light->item_mask && p_item->z_final >= light->z_min && p_item->z_final <= light->z_max && p_item->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) { uint32_t light_index = light->render_index_cache; push_constant.lights[light_count >> 2] |= light_index << ((light_count & 3) * 8); + + if (!light_uniform_set_dirty && (state_data->light_cache[light_count].light != light || state_data->light_cache[light_count].light_version != light->version)) { + light_uniform_set_dirty = true; + } + + light_cache[light_count] = light; + light_count++; if (light->mode == VS::CANVAS_LIGHT_MODE_MASK) { base_flags |= FLAGS_USING_LIGHT_MASK; } - if (light_count == MAX_LIGHTS_PER_ITEM) { + if (light_count == state.max_lights_per_item) { break; } } light = light->next_ptr; } + if (light_count != state_data->light_cache_count) { + light_uniform_set_dirty = true; + } base_flags |= light_count << FLAGS_LIGHT_COUNT_SHIFT; } + if (light_count) { + + //validate and update lighs if they are being used + bool invalid_uniform = state_data->light_uniform_set.is_valid() && !RD::get_singleton()->uniform_set_is_valid(state_data->light_uniform_set); + + if (state_data->light_uniform_set.is_null() || invalid_uniform || light_uniform_set_dirty) { + //recreate uniform set + if (state_data->light_uniform_set.is_valid() && !invalid_uniform) { + RD::get_singleton()->free(state_data->light_uniform_set); + } + + state_data->light_uniform_set = RID(); + + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 0; + u.ids.push_back(state.lights_uniform_buffer); + uniforms.push_back(u); + } + + { + + RD::Uniform u_lights; + u_lights.type = RD::UNIFORM_TYPE_TEXTURE; + u_lights.binding = 1; + + RD::Uniform u_shadows; + u_shadows.type = RD::UNIFORM_TYPE_TEXTURE; + u_shadows.binding = 2; + + //lights + for (uint32_t i = 0; i < state.max_lights_per_item; i++) { + if (i < light_count) { + + CanvasLight *cl = canvas_light_owner.getornull(light_cache[i]->light_internal); + ERR_CONTINUE(!cl); + + RID rd_texture; + + if (cl->texture.is_valid()) { + rd_texture = storage->texture_get_rd_texture(cl->texture); + } + if (rd_texture.is_valid()) { + u_lights.ids.push_back(rd_texture); + } else { + u_lights.ids.push_back(default_textures.white_texture); + } + if (cl->shadow.texture.is_valid()) { + u_shadows.ids.push_back(cl->shadow.texture); + } else { + u_shadows.ids.push_back(default_textures.black_texture); + } + } else { + u_lights.ids.push_back(default_textures.white_texture); + u_shadows.ids.push_back(default_textures.black_texture); + } + } + + uniforms.push_back(u_lights); + uniforms.push_back(u_shadows); + } + + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_SAMPLER; + u.binding = 3; + u.ids.push_back(state.shadow_sampler); + uniforms.push_back(u); + } + + state_data->light_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader_light, 3); + } + + RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, state_data->light_uniform_set, 3); + light_mode = PIPELINE_LIGHT_MODE_ENABLED; + } else { + light_mode = PIPELINE_LIGHT_MODE_DISABLED; + } + + { + //state uniform + bool invalid_uniform = state_data->state_uniform_set.is_valid() && !RD::get_singleton()->uniform_set_is_valid(state_data->state_uniform_set); + + if (state_data->state_uniform_set.is_null() || invalid_uniform) { + if (state_data->state_uniform_set.is_valid() && !invalid_uniform) { + RD::get_singleton()->free(state_data->state_uniform_set); + } + state_data->state_uniform_set = RID(); + + Vector<RD::Uniform> uniforms; + + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 0; + u.ids.push_back(state.canvas_state_buffer); + uniforms.push_back(u); + } + + if (false && p_item->skeleton.is_valid()) { + //bind skeleton stuff + } else { + //bind default + + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 0; + u.ids.push_back(state.canvas_state_buffer); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_TEXTURE_BUFFER; + u.binding = 1; + u.ids.push_back(shader.default_skeleton_texture_buffer); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 2; + u.ids.push_back(shader.default_skeleton_uniform_buffer); + uniforms.push_back(u); + } + } + + state_data->state_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, 2); + } + + RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, state_data->state_uniform_set, 2); + } + PipelineVariants *pipeline_variants = &shader.pipeline_variants; bool reclip = false; @@ -579,7 +720,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ //bind pipeline { - RID pipeline = pipeline_variants->variants[p_render_target_format][PIPELINE_VARIANT_QUAD].get_render_pipeline(RD::INVALID_ID, p_samples); + RID pipeline = pipeline_variants->variants[light_mode][PIPELINE_VARIANT_QUAD].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format); RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline); } @@ -679,7 +820,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ //bind pipeline { - RID pipeline = pipeline_variants->variants[p_render_target_format][PIPELINE_VARIANT_NINEPATCH].get_render_pipeline(RD::INVALID_ID, p_samples); + RID pipeline = pipeline_variants->variants[light_mode][PIPELINE_VARIANT_NINEPATCH].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format); RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline); } @@ -761,7 +902,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ { static const PipelineVariant variant[VS::PRIMITIVE_MAX] = { PIPELINE_VARIANT_ATTRIBUTE_POINTS, PIPELINE_VARIANT_ATTRIBUTE_LINES, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLES }; ERR_CONTINUE(polygon->primitive < 0 || polygon->primitive >= VS::PRIMITIVE_MAX); - RID pipeline = pipeline_variants->variants[p_render_target_format][variant[polygon->primitive]].get_render_pipeline(pb->vertex_format_id, p_samples); + RID pipeline = pipeline_variants->variants[light_mode][variant[polygon->primitive]].get_render_pipeline(pb->vertex_format_id, p_framebuffer_format); RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline); } @@ -815,7 +956,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ { static const PipelineVariant variant[4] = { PIPELINE_VARIANT_PRIMITIVE_POINTS, PIPELINE_VARIANT_PRIMITIVE_LINES, PIPELINE_VARIANT_PRIMITIVE_TRIANGLES, PIPELINE_VARIANT_PRIMITIVE_TRIANGLES }; ERR_CONTINUE(primitive->point_count == 0 || primitive->point_count > 4); - RID pipeline = pipeline_variants->variants[p_render_target_format][variant[primitive->point_count - 1]].get_render_pipeline(RD::INVALID_ID, p_samples); + RID pipeline = pipeline_variants->variants[light_mode][variant[primitive->point_count - 1]].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format); RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline); } @@ -1184,7 +1325,6 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, Item *current_clip = NULL; - RenderTargetFormat render_target_format = RENDER_TARGET_FORMAT_8_BIT_INT; Transform2D canvas_transform_inverse = p_canvas_transform_inverse; RID framebuffer = storage->render_target_get_rd_framebuffer(p_to_render_target); @@ -1197,10 +1337,9 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, storage->render_target_disable_clear_request(p_to_render_target); } #warning TODO obtain from framebuffer format eventually when this is implemented - RD::TextureSamples texture_samples = RD::TEXTURE_SAMPLES_1; - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH, clear_colors); + RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, state.canvas_state_uniform_set, 3); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH, clear_colors); for (int i = 0; i < p_item_count; i++) { @@ -1221,104 +1360,18 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, } } - if (false) { //not skeleton - - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, shader.default_skeleton_uniform_set, 1); - } - - _render_item(draw_list, ci, render_target_format, texture_samples, canvas_transform_inverse, current_clip, p_lights); + _render_item(draw_list, ci, fb_format, canvas_transform_inverse, current_clip, p_lights); } RD::get_singleton()->draw_list_end(); } -void RasterizerCanvasRD::_update_canvas_state_uniform_set() { - - if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) { - return; //nothing to update - } - - Vector<RD::Uniform> uniforms; - - { - RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 0; - u.ids.push_back(state.canvas_state_buffer); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 1; - u.ids.push_back(state.lights_uniform_buffer); - uniforms.push_back(u); - } - - { - - RD::Uniform u_lights; - u_lights.type = RD::UNIFORM_TYPE_TEXTURE; - u_lights.binding = 2; - - RD::Uniform u_shadows; - u_shadows.type = RD::UNIFORM_TYPE_TEXTURE; - u_shadows.binding = 3; - - //lights - for (uint32_t i = 0; i < MAX_LIGHT_TEXTURES; i++) { - if (i < canvas_light_owner.get_rid_count()) { - CanvasLight *cl = canvas_light_owner.get_rid_by_index(i); - cl->texture_index = i; - RID rd_texture; - - if (cl->texture.is_valid()) { - rd_texture = storage->texture_get_rd_texture(cl->texture); - } - if (rd_texture.is_valid()) { - u_lights.ids.push_back(rd_texture); - } else { - u_lights.ids.push_back(default_textures.white_texture); - } - if (cl->shadow.texture.is_valid()) { - u_shadows.ids.push_back(cl->shadow.texture); - } else { - u_shadows.ids.push_back(default_textures.black_texture); - } - } else { - u_lights.ids.push_back(default_textures.white_texture); - u_shadows.ids.push_back(default_textures.black_texture); - } - } - - //in case there are more - for (uint32_t i = MAX_LIGHT_TEXTURES; i < canvas_light_owner.get_rid_count(); i++) { - CanvasLight *cl = canvas_light_owner.get_rid_by_index(i); - cl->texture_index = -1; //make invalid (no texture) - } - - uniforms.push_back(u_lights); - uniforms.push_back(u_shadows); - } - - { - RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 4; - u.ids.push_back(state.shadow_sampler); - uniforms.push_back(u); - } - - state.canvas_state_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, 3); // uses index 3 -} - void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform) { int item_count = 0; //setup canvas state uniforms if needed - _update_canvas_state_uniform_set(); + Transform2D canvas_transform_inverse = p_canvas_transform.affine_inverse(); { @@ -1356,14 +1409,14 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite while (l) { - if (index == MAX_RENDER_LIGHTS) { + if (index == state.max_lights_per_render) { l->render_index_cache = -1; l = l->next_ptr; continue; } CanvasLight *clight = canvas_light_owner.getornull(l->light_internal); - if (!clight || clight->texture_index < 0) { //unused or invalid texture + if (!clight) { //unused or invalid texture l->render_index_cache = -1; l = l->next_ptr; ERR_CONTINUE(!clight); @@ -1390,7 +1443,7 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite } else { state.light_uniforms[index].shadow_pixel_size = 1.0; } - state.light_uniforms[index].flags = clight->texture_index; + state.light_uniforms[index].flags |= l->mode << LIGHT_FLAGS_BLEND_SHIFT; state.light_uniforms[index].flags |= l->shadow_filter << LIGHT_FLAGS_FILTER_SHIFT; if (clight->shadow.texture.is_valid()) { @@ -1439,7 +1492,6 @@ RID RasterizerCanvasRD::light_create() { CanvasLight canvas_light; canvas_light.shadow.size = 0; - canvas_light.texture_index = -1; return canvas_light_owner.make_rid(canvas_light); } @@ -1451,11 +1503,6 @@ void RasterizerCanvasRD::light_set_texture(RID p_rid, RID p_texture) { } cl->texture = p_texture; - - //canvas state uniform set needs updating - if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) { - RD::get_singleton()->free(state.canvas_state_uniform_set); - } } void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_resolution) { CanvasLight *cl = canvas_light_owner.getornull(p_rid); @@ -1506,11 +1553,6 @@ void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_re } cl->shadow.size = p_resolution; - - //canvas state uniform set needs updating - if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) { - RD::get_singleton()->free(state.canvas_state_uniform_set); - } } void RasterizerCanvasRD::light_update_shadow(RID p_rid, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) { @@ -1831,35 +1873,58 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { } { //shader variants + + uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); + + String global_defines; + if (textures_per_stage <= 16) { + //ARM pretty much, and very old Intel GPUs under Linux + state.max_lights_per_item = 4; //sad + global_defines += "#define MAX_LIGHT_TEXTURES 4\n"; + } else if (textures_per_stage <= 32) { + //Apple (Metal) + state.max_lights_per_item = 8; //sad + global_defines += "#define MAX_LIGHT_TEXTURES 8\n"; + } else { + //Anything else (16 lights per item) + state.max_lights_per_item = DEFAULT_MAX_LIGHTS_PER_ITEM; + global_defines += "#define MAX_LIGHT_TEXTURES " + itos(DEFAULT_MAX_LIGHTS_PER_ITEM) + "\n"; + } + + uint32_t uniform_max_size = RD::get_singleton()->limit_get(RD::LIMIT_MAX_UNIFORM_BUFFER_SIZE); + if (uniform_max_size < 65536) { + //Yes, you guessed right, ARM again + state.max_lights_per_render = 64; + global_defines += "#define MAX_LIGHTS 64\n"; + } else { + state.max_lights_per_render = DEFAULT_MAX_LIGHTS_PER_RENDER; + global_defines += "#define MAX_LIGHTS " + itos(DEFAULT_MAX_LIGHTS_PER_RENDER) + "\n"; + } + + state.light_uniforms = memnew_arr(LightUniform, state.max_lights_per_render); Vector<String> variants; + //non light variants variants.push_back(""); //none by default is first variant variants.push_back("#define USE_NINEPATCH\n"); //ninepatch is the second variant variants.push_back("#define USE_PRIMITIVE\n"); //primitve is the third variants.push_back("#define USE_PRIMITIVE\n#define USE_POINT_SIZE\n"); //points need point size variants.push_back("#define USE_ATTRIBUTES\n"); // attributes for vertex arrays variants.push_back("#define USE_ATTRIBUTES\n#define USE_POINT_SIZE\n"); //attributes with point size - shader.canvas_shader.initialize(variants); + //light variants + variants.push_back("#define USE_LIGHTING\n"); //none by default is first variant + variants.push_back("#define USE_LIGHTING\n#define USE_NINEPATCH\n"); //ninepatch is the second variant + variants.push_back("#define USE_LIGHTING\n#define USE_PRIMITIVE\n"); //primitve is the third + variants.push_back("#define USE_LIGHTING\n#define USE_PRIMITIVE\n#define USE_POINT_SIZE\n"); //points need point size + variants.push_back("#define USE_LIGHTING\n#define USE_ATTRIBUTES\n"); // attributes for vertex arrays + variants.push_back("#define USE_LIGHTING\n#define USE_ATTRIBUTES\n#define USE_POINT_SIZE\n"); //attributes with point size - shader.default_version = shader.canvas_shader.version_create(); + shader.canvas_shader.initialize(variants, global_defines); - { - //framebuffer formats - RD::AttachmentFormat af; - af.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - af.samples = RD::TEXTURE_SAMPLES_1; - af.usage_flags = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_RETRIEVE_BIT; - Vector<RD::AttachmentFormat> formats; - formats.push_back(af); - shader.framebuffer_formats[RENDER_TARGET_FORMAT_8_BIT_INT] = RD::get_singleton()->framebuffer_format_create(formats); - - formats.clear(); - af.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - formats.push_back(af); - shader.framebuffer_formats[RENDER_TARGET_FORMAT_16_BIT_FLOAT] = RD::get_singleton()->framebuffer_format_create(formats); - } + shader.default_version = shader.canvas_shader.version_create(); + shader.default_version_rd_shader = shader.canvas_shader.version_get_shader(shader.default_version, SHADER_VARIANT_QUAD); + shader.default_version_rd_shader_light = shader.canvas_shader.version_get_shader(shader.default_version, SHADER_VARIANT_QUAD_LIGHT); - for (int i = 0; i < RENDER_TARGET_FORMAT_MAX; i++) { - RD::FramebufferFormatID fb_format = shader.framebuffer_formats[i]; + for (int i = 0; i < PIPELINE_LIGHT_MODE_MAX; i++) { for (int j = 0; j < PIPELINE_VARIANT_MAX; j++) { RD::RenderPrimitive primitive[PIPELINE_VARIANT_MAX] = { RD::RENDER_PRIMITIVE_TRIANGLES, @@ -1871,23 +1936,31 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { RD::RENDER_PRIMITIVE_LINES, RD::RENDER_PRIMITIVE_POINTS, }; - ShaderVariant shader_variants[PIPELINE_VARIANT_MAX] = { - SHADER_VARIANT_QUAD, - SHADER_VARIANT_NINEPATCH, - SHADER_VARIANT_PRIMITIVE, - SHADER_VARIANT_PRIMITIVE, - SHADER_VARIANT_PRIMITIVE_POINTS, - SHADER_VARIANT_ATTRIBUTES, - SHADER_VARIANT_ATTRIBUTES, - SHADER_VARIANT_ATTRIBUTES_POINTS + ShaderVariant shader_variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX] = { + { //non lit + SHADER_VARIANT_QUAD, + SHADER_VARIANT_NINEPATCH, + SHADER_VARIANT_PRIMITIVE, + SHADER_VARIANT_PRIMITIVE, + SHADER_VARIANT_PRIMITIVE_POINTS, + SHADER_VARIANT_ATTRIBUTES, + SHADER_VARIANT_ATTRIBUTES, + SHADER_VARIANT_ATTRIBUTES_POINTS }, + { //lit + SHADER_VARIANT_QUAD_LIGHT, + SHADER_VARIANT_NINEPATCH_LIGHT, + SHADER_VARIANT_PRIMITIVE_LIGHT, + SHADER_VARIANT_PRIMITIVE_LIGHT, + SHADER_VARIANT_PRIMITIVE_POINTS_LIGHT, + SHADER_VARIANT_ATTRIBUTES_LIGHT, + SHADER_VARIANT_ATTRIBUTES_LIGHT, + SHADER_VARIANT_ATTRIBUTES_POINTS_LIGHT }, }; - RID shader_variant = shader.canvas_shader.version_get_shader(shader.default_version, shader_variants[j]); - shader.pipeline_variants.variants[i][j].setup(shader_variant, fb_format, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_blend(), 0); + RID shader_variant = shader.canvas_shader.version_get_shader(shader.default_version, shader_variants[i][j]); + shader.pipeline_variants.variants[i][j].setup(shader_variant, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_blend(), 0); } } - - shader.default_version_rd_shader = shader.canvas_shader.version_get_shader(shader.default_version, 0); } { //shadow rendering @@ -1901,6 +1974,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { RD::AttachmentFormat af_color; af_color.format = RD::DATA_FORMAT_R32_SFLOAT; af_color.usage_flags = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + af_color.samples = RenderingDevice::TEXTURE_SAMPLES_64; attachments.push_back(af_color); @@ -1908,6 +1982,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { af_depth.format = RD::DATA_FORMAT_D24_UNORM_S8_UINT; af_depth.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_X8_D24_UNORM_PACK32, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_X8_D24_UNORM_PACK32 : RD::DATA_FORMAT_D32_SFLOAT; af_depth.usage_flags = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + af_depth.samples = RenderingDevice::TEXTURE_SAMPLES_64; attachments.push_back(af_depth); @@ -1944,7 +2019,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { { //state allocate state.canvas_state_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(State::Buffer)); - state.lights_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(LightUniform) * MAX_RENDER_LIGHTS); + state.lights_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(LightUniform) * state.max_lights_per_render); RD::SamplerState shadow_sampler_state; shadow_sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR; @@ -1956,6 +2031,60 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { } { + { + PoolVector<uint8_t> colors; + colors.resize(sizeof(float) * 4); + { + PoolVector<uint8_t>::Write w = colors.write(); + float *fptr = (float *)w.ptr(); + fptr[0] = 1.0; + fptr[1] = 1.0; + fptr[2] = 1.0; + fptr[3] = 1.0; + } + polygon_buffers.default_color_buffer = RD::get_singleton()->vertex_buffer_create(colors.size(), colors); + } + + { + PoolVector<uint8_t> uvs; + uvs.resize(sizeof(float) * 2); + { + PoolVector<uint8_t>::Write w = uvs.write(); + float *fptr = (float *)w.ptr(); + fptr[0] = 0.0; + fptr[1] = 0.0; + } + polygon_buffers.default_uv_buffer = RD::get_singleton()->vertex_buffer_create(uvs.size(), uvs); + } + + { + PoolVector<uint8_t> bones; + bones.resize(sizeof(uint32_t) * 4); + { + PoolVector<uint8_t>::Write w = bones.write(); + uint32_t *iptr = (uint32_t *)w.ptr(); + iptr[0] = 0; + iptr[1] = 0; + iptr[2] = 0; + iptr[3] = 0; + } + polygon_buffers.default_bone_buffer = RD::get_singleton()->vertex_buffer_create(bones.size(), bones); + } + + { + PoolVector<uint8_t> weights; + weights.resize(sizeof(float) * 4); + { + PoolVector<uint8_t>::Write w = weights.write(); + float *fptr = (float *)w.ptr(); + fptr[0] = 0.0; + fptr[1] = 0.0; + fptr[2] = 0.0; + fptr[3] = 0.0; + } + polygon_buffers.default_weight_buffer = RD::get_singleton()->vertex_buffer_create(weights.size(), weights); + } + //polygon buffers polygon_buffers.last_id = 1; } @@ -1987,28 +2116,13 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { { //default skeleton buffer - shader.default_skeleton_uniform = RD::get_singleton()->uniform_buffer_create(sizeof(SkeletonUniform)); + shader.default_skeleton_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkeletonUniform)); SkeletonUniform su; _update_transform_2d_to_mat4(Transform2D(), su.skeleton_inverse); _update_transform_2d_to_mat4(Transform2D(), su.skeleton_transform); - RD::get_singleton()->buffer_update(shader.default_skeleton_uniform, 0, sizeof(SkeletonUniform), &su); - } + RD::get_singleton()->buffer_update(shader.default_skeleton_uniform_buffer, 0, sizeof(SkeletonUniform), &su); - { //default material uniform set - Vector<RD::Uniform> default_material_uniforms; - RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 2; - u.ids.push_back(shader.default_skeleton_uniform); - default_material_uniforms.push_back(u); - - u.ids.clear(); - u.type = RD::UNIFORM_TYPE_TEXTURE_BUFFER; - u.binding = 1; - u.ids.push_back(default_textures.default_multimesh_tb); - default_material_uniforms.push_back(u); - - shader.default_skeleton_uniform_set = RD::get_singleton()->uniform_set_create(default_material_uniforms, shader.canvas_shader.version_get_shader(shader.default_version, SHADER_VARIANT_ATTRIBUTES), 2); + shader.default_skeleton_texture_buffer = RD::get_singleton()->texture_buffer_create(32, RD::DATA_FORMAT_R32G32B32A32_SFLOAT); } ERR_FAIL_COND(sizeof(PushConstant) != 128); @@ -2021,10 +2135,6 @@ bool RasterizerCanvasRD::free(RID p_rid) { ERR_FAIL_COND_V(!cl, false); light_set_use_shadow(p_rid, false, 64); canvas_light_owner.free(p_rid); - //canvas state uniform set needs updating - if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) { - RD::get_singleton()->free(state.canvas_state_uniform_set); - } } else if (occluder_polygon_owner.owns(p_rid)) { occluder_polygon_set_shape_as_lines(p_rid, PoolVector<Vector2>()); occluder_polygon_owner.free(p_rid); @@ -2043,10 +2153,6 @@ RasterizerCanvasRD::~RasterizerCanvasRD() { RD::get_singleton()->free(state.canvas_state_buffer); } - if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) { - RD::get_singleton()->free(state.canvas_state_uniform_set); - } - //bindings { @@ -2070,8 +2176,6 @@ RasterizerCanvasRD::~RasterizerCanvasRD() { //shaders - RD::get_singleton()->free(shader.default_skeleton_uniform_set); - RD::get_singleton()->free(shader.default_skeleton_uniform); shader.canvas_shader.version_free(shader.default_version); //buffers diff --git a/servers/visual/rasterizer/rasterizer_canvas_rd.h b/servers/visual/rasterizer/rasterizer_canvas_rd.h index 81e2815d6f..dfeecddfc1 100644 --- a/servers/visual/rasterizer/rasterizer_canvas_rd.h +++ b/servers/visual/rasterizer/rasterizer_canvas_rd.h @@ -6,7 +6,6 @@ #include "servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h" #include "servers/visual/rasterizer/shaders/canvas.glsl.gen.h" #include "servers/visual/rasterizer/shaders/canvas_occlusion.glsl.gen.h" -#include "servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl.gen.h" #include "servers/visual/rendering_device.h" class RasterizerCanvasRD : public RasterizerCanvas { @@ -20,15 +19,15 @@ class RasterizerCanvasRD : public RasterizerCanvas { 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 }; - enum RenderTargetFormat { - RENDER_TARGET_FORMAT_8_BIT_INT, - RENDER_TARGET_FORMAT_16_BIT_FLOAT, - RENDER_TARGET_FORMAT_MAX - }; - enum { FLAGS_INSTANCING_STRIDE_MASK = 0xF, FLAGS_INSTANCING_ENABLED = (1 << 4), @@ -71,8 +70,8 @@ class RasterizerCanvasRD : public RasterizerCanvas { enum { MAX_RENDER_ITEMS = 256 * 1024, MAX_LIGHT_TEXTURES = 1024, - MAX_LIGHTS_PER_ITEM = 16, - MAX_RENDER_LIGHTS = 256 + DEFAULT_MAX_LIGHTS_PER_ITEM = 16, + DEFAULT_MAX_LIGHTS_PER_RENDER = 256 }; /****************/ @@ -90,22 +89,28 @@ class RasterizerCanvasRD : public RasterizerCanvas { PIPELINE_VARIANT_ATTRIBUTE_POINTS, PIPELINE_VARIANT_MAX }; + enum PipelineLightMode { + PIPELINE_LIGHT_MODE_DISABLED, + PIPELINE_LIGHT_MODE_ENABLED, + PIPELINE_LIGHT_MODE_MAX + }; + struct PipelineVariants { - RenderPipelineVertexFormatCacheRD variants[RENDER_TARGET_FORMAT_MAX][PIPELINE_VARIANT_MAX]; + RenderPipelineVertexFormatCacheRD variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX]; }; struct { CanvasShaderRD canvas_shader; - RD::FramebufferFormatID framebuffer_formats[RENDER_TARGET_FORMAT_MAX]; RID default_version; RID default_version_rd_shader; + RID default_version_rd_shader_light; RID quad_index_buffer; RID quad_index_array; PipelineVariants pipeline_variants; // default_skeleton uniform set - RID default_skeleton_uniform; - RID default_skeleton_uniform_set; + RID default_skeleton_uniform_buffer; + RID default_skeleton_texture_buffer; } shader; @@ -194,6 +199,10 @@ class RasterizerCanvasRD : public RasterizerCanvas { struct { HashMap<PolygonID, PolygonBuffers> polygons; PolygonID last_id; + RID default_color_buffer; + RID default_uv_buffer; + RID default_bone_buffer; + RID default_weight_buffer; } polygon_buffers; /********************/ @@ -214,7 +223,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { struct CanvasLight { - int32_t texture_index; RID texture; struct { int size; @@ -256,9 +264,8 @@ class RasterizerCanvasRD : public RasterizerCanvas { float position[2]; uint32_t flags; //index to light texture float height; - float shadow_softness; float shadow_pixel_size; - float pad[2]; + float pad[3]; }; RID_Owner<OccluderPolygon> occluder_polygon_owner; @@ -277,6 +284,36 @@ class RasterizerCanvasRD : public RasterizerCanvas { //state that does not vary across rendering all items + struct ItemStateData : public Item::CustomData { + + struct LightCache { + uint64_t light_version; + Light *light; + }; + + LightCache light_cache[DEFAULT_MAX_LIGHTS_PER_ITEM]; + uint32_t light_cache_count; + RID light_uniform_set; + RID state_uniform_set; + ItemStateData() { + + for (int i = 0; i < DEFAULT_MAX_LIGHTS_PER_ITEM; i++) { + light_cache[i].light_version = 0; + light_cache[i].light = NULL; + } + light_cache_count = 0xFFFFFFFF; + } + + ~ItemStateData() { + if (light_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(light_uniform_set)) { + RD::get_singleton()->free(light_uniform_set); + } + if (state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state_uniform_set)) { + RD::get_singleton()->free(state_uniform_set); + } + } + }; + struct State { //state buffer @@ -289,14 +326,14 @@ class RasterizerCanvasRD : public RasterizerCanvas { //uint32_t pad[3]; }; - LightUniform light_uniforms[MAX_RENDER_LIGHTS]; + LightUniform *light_uniforms; RID lights_uniform_buffer; RID canvas_state_buffer; RID shadow_sampler; - //uniform set for all the above - RID canvas_state_uniform_set; + uint32_t max_lights_per_render; + uint32_t max_lights_per_item; } state; struct PushConstant { @@ -331,7 +368,7 @@ class RasterizerCanvasRD : public RasterizerCanvas { Item *items[MAX_RENDER_ITEMS]; Size2i _bind_texture_binding(TextureBindingID p_binding, RenderingDevice::DrawListID p_draw_list, uint32_t &flags); - void _render_item(RenderingDevice::DrawListID p_draw_list, const Item *p_item, RenderTargetFormat p_render_target_format, RenderingDevice::TextureSamples p_samples, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights); + void _render_item(RenderingDevice::DrawListID p_draw_list, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights); void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights); _FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4); @@ -342,8 +379,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { _FORCE_INLINE_ void _update_specular_shininess(const Color &p_transform, uint32_t *r_ss); - void _update_canvas_state_uniform_set(); - public: TextureBindingID request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, VS::CanvasItemTextureFilter p_filter, VS::CanvasItemTextureRepeat p_repeat, RID p_multimesh); void free_texture_binding(TextureBindingID p_binding); diff --git a/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.cpp b/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.cpp index be2aa95c34..2c2d6e9ca0 100644 --- a/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.cpp +++ b/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.cpp @@ -1,43 +1,39 @@ #include "render_pipeline_vertex_format_cache_rd.h" #include "core/os/memory.h" -RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_format_id, RenderingDevice::TextureSamples p_samples) { +RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id) { - RD::PipelineMultisampleState multisample_state_version; - if (p_samples != RD::TEXTURE_SAMPLES_1) { - multisample_state_version = multisample_state; - multisample_state_version.sample_count = p_samples; - } - RID pipeline = RD::get_singleton()->render_pipeline_create(shader, framebuffer_format, p_format_id, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags); + RD::PipelineMultisampleState multisample_state_version = multisample_state; + multisample_state_version.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_framebuffer_format_id); + + RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, rasterization_state, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags); ERR_FAIL_COND_V(pipeline.is_null(), RID()); - versions[p_samples] = (Version *)memrealloc(versions[p_samples], sizeof(Version) * (version_count[p_samples] + 1)); - versions[p_samples][version_count[p_samples]].format_id = p_format_id; - versions[p_samples][version_count[p_samples]].pipeline = pipeline; - version_count[p_samples]++; + versions = (Version *)memrealloc(versions, sizeof(Version) * (version_count + 1)); + versions[version_count].framebuffer_id = p_framebuffer_format_id; + versions[version_count].vertex_id= p_vertex_format_id; + versions[version_count].pipeline = pipeline; + version_count++; return pipeline; } void RenderPipelineVertexFormatCacheRD::_clear() { - for (int v = 0; v < RD::TEXTURE_SAMPLES_MAX; v++) { - if (versions[v]) { - for (uint32_t i = 0; i < version_count[v]; i++) { - //shader may be gone, so this may not be valid - if (RD::get_singleton()->render_pipeline_is_valid(versions[v][i].pipeline)) { - RD::get_singleton()->free(versions[v][i].pipeline); - } + if (versions) { + for (uint32_t i = 0; i < version_count; i++) { + //shader may be gone, so this may not be valid + if (RD::get_singleton()->render_pipeline_is_valid(versions[i].pipeline)) { + RD::get_singleton()->free(versions[i].pipeline); } - version_count[v] = 0; - memfree(versions[v]); - versions[v] = NULL; } + version_count = 0; + memfree(versions); + versions = NULL; } } -void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::FramebufferFormatID p_framebuffer_format, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) { +void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) { ERR_FAIL_COND(p_shader.is_null()); shader = p_shader; - framebuffer_format = p_framebuffer_format; render_primitive = p_primitive; rasterization_state = p_rasterization_state; multisample_state = p_multisample; @@ -49,14 +45,12 @@ void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::FramebufferForma void RenderPipelineVertexFormatCacheRD::update_shader(RID p_shader) { ERR_FAIL_COND(p_shader.is_null()); _clear(); - setup(p_shader, framebuffer_format, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags); + setup(p_shader, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags); } RenderPipelineVertexFormatCacheRD::RenderPipelineVertexFormatCacheRD() { - for (int i = 0; i < RD::TEXTURE_SAMPLES_MAX; i++) { - version_count[i] = 0; - versions[i] = NULL; - } + version_count = 0; + versions = NULL; } RenderPipelineVertexFormatCacheRD::~RenderPipelineVertexFormatCacheRD() { diff --git a/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h b/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h index 02b34c3a1b..cdbfda05f1 100644 --- a/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h +++ b/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h @@ -16,29 +16,29 @@ class RenderPipelineVertexFormatCacheRD { int dynamic_state_flags; struct Version { - RD::VertexFormatID format_id; + RD::VertexFormatID vertex_id; + RD::FramebufferFormatID framebuffer_id; RID pipeline; }; - Version *versions[RD::TEXTURE_SAMPLES_MAX]; - uint32_t version_count[RD::TEXTURE_SAMPLES_MAX]; + Version *versions; + uint32_t version_count; - RID _generate_version(RD::VertexFormatID p_format_id, RD::TextureSamples p_samples); + RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id); void _clear(); public: - void setup(RID p_shader, RD::FramebufferFormatID p_framebuffer_format, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0); + void setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0); void update_shader(RID p_shader); - _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_format_id, RD::TextureSamples p_samples) { - ERR_FAIL_INDEX_V(p_samples, RD::TEXTURE_SAMPLES_MAX, RID()); - for (uint32_t i = 0; i < version_count[p_samples]; i++) { - if (versions[p_samples][i].format_id == p_format_id) { - return versions[p_samples][i].pipeline; + _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id) { + for (uint32_t i = 0; i < version_count; i++) { + if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id) { + return versions[i].pipeline; } } - return _generate_version(p_format_id, p_samples); + return _generate_version(p_vertex_format_id, p_framebuffer_format_id); } RenderPipelineVertexFormatCacheRD(); diff --git a/servers/visual/rasterizer/shader_rd.cpp b/servers/visual/rasterizer/shader_rd.cpp index 9bc3442dd2..1a62a32c4d 100644 --- a/servers/visual/rasterizer/shader_rd.cpp +++ b/servers/visual/rasterizer/shader_rd.cpp @@ -180,7 +180,9 @@ void ShaderRD::_compile_version(Version *p_version) { builder.append(vertex_codev.get_data()); // version info (if exists) builder.append("\n"); //make sure defines begin at newline + builder.append(general_defines.get_data()); builder.append(variant_defines[i].get_data()); + for (int j = 0; j < p_version->custom_defines.size(); j++) { builder.append(p_version->custom_defines[j].get_data()); } @@ -214,6 +216,7 @@ void ShaderRD::_compile_version(Version *p_version) { builder.append(fragment_codev.get_data()); // version info (if exists) builder.append("\n"); //make sure defines begin at newline + builder.append(general_defines.get_data()); builder.append(variant_defines[i].get_data()); for (int j = 0; j < p_version->custom_defines.size(); j++) { builder.append(p_version->custom_defines[j].get_data()); @@ -307,9 +310,10 @@ bool ShaderRD::version_free(RID p_version) { return true; } -void ShaderRD::initialize(const Vector<String> &p_variant_defines) { +void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String &p_general_defines) { ERR_FAIL_COND(variant_defines.size()); ERR_FAIL_COND(p_variant_defines.size() == 0); + general_defines = p_general_defines.utf8(); for (int i = 0; i < p_variant_defines.size(); i++) { variant_defines.push_back(p_variant_defines[i].utf8()); diff --git a/servers/visual/rasterizer/shader_rd.h b/servers/visual/rasterizer/shader_rd.h index 814c87d281..c7a8cdaa37 100644 --- a/servers/visual/rasterizer/shader_rd.h +++ b/servers/visual/rasterizer/shader_rd.h @@ -44,6 +44,7 @@ class ShaderRD { //versions + CharString general_defines; Vector<CharString> variant_defines; int vertex_code_start; @@ -114,7 +115,7 @@ public: bool version_free(RID p_version); - void initialize(const Vector<String> &p_variant_defines); + void initialize(const Vector<String> &p_variant_defines, const String &p_general_defines = ""); virtual ~ShaderRD(); }; diff --git a/servers/visual/rasterizer/shaders/SCsub b/servers/visual/rasterizer/shaders/SCsub index ef1df0c203..37290e997f 100644 --- a/servers/visual/rasterizer/shaders/SCsub +++ b/servers/visual/rasterizer/shaders/SCsub @@ -5,4 +5,3 @@ Import('env') if 'RD_GLSL' in env['BUILDERS']: env.RD_GLSL('canvas.glsl'); env.RD_GLSL('canvas_occlusion.glsl'); - env.RD_GLSL('canvas_occlusion_fix.glsl'); diff --git a/servers/visual/rasterizer/shaders/canvas.glsl b/servers/visual/rasterizer/shaders/canvas.glsl index defe8630be..8d36a2e3ea 100644 --- a/servers/visual/rasterizer/shaders/canvas.glsl +++ b/servers/visual/rasterizer/shaders/canvas.glsl @@ -426,8 +426,11 @@ FRAGMENT_SHADER_CODE } color*=canvas_data.canvas_modulation; - - for(uint i=0;i<light_count;i++) { +#ifdef USE_LIGHTING + for(uint i=0;i<MAX_LIGHT_TEXTURES;i++) { + if (i>=light_count) { + break; + } uint light_base; if (i<8) { if (i<4) { @@ -445,16 +448,8 @@ FRAGMENT_SHADER_CODE light_base>>=(i&3)*8; light_base&=0xFF; -#define LIGHT_FLAGS_BLEND_MASK (3<<16) -#define LIGHT_FLAGS_BLEND_MODE_ADD (0<<16) -#define LIGHT_FLAGS_BLEND_MODE_SUB (1<<16) -#define LIGHT_FLAGS_BLEND_MODE_MIX (2<<16) -#define LIGHT_FLAGS_BLEND_MODE_MASK (3<<16) - - vec2 tex_uv = (vec4(vertex,0.0,1.0) * mat4(light_array.data[light_base].matrix[0],light_array.data[light_base].matrix[1],vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations. - uint texture_idx = light_array.data[light_base].flags&LIGHT_FLAGS_TEXTURE_MASK; - vec4 light_color = texture(sampler2D(light_textures[texture_idx],texture_sampler),tex_uv); + vec4 light_color = texture(sampler2D(light_textures[i],texture_sampler),tex_uv); vec4 light_base_color = light_array.data[light_base].color; light_color.rgb*=light_base_color.rgb*light_base_color.a; @@ -526,32 +521,32 @@ FRAGMENT_SHADER_CODE vec4 shadow_uv = vec4(tex_ofs,0.0,distance,1.0); if (shadow_mode==LIGHT_FLAGS_SHADOW_NEAREST) { - shadow = textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x; + shadow = textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv).x; } else if (shadow_mode==LIGHT_FLAGS_SHADOW_PCF5) { vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size,0.0,0.0,0.0); shadow = 0.0; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x; shadow/=5.0; - } else if (shadow_mode==LIGHT_FLAGS_SHADOW_PCF13) { + } else { //PCF13 vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size,0.0,0.0,0.0); shadow = 0.0; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*6.0).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*5.0).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*4.0).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*3.0).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*3.0).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*4.0).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*5.0).x; - shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*6.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*6.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*5.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*4.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*3.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*3.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*4.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*5.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*6.0).x; shadow/=13.0; } @@ -577,6 +572,7 @@ FRAGMENT_SHADER_CODE } break; } } +#endif frag_color = color; diff --git a/servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl b/servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl deleted file mode 100644 index 7c9651201e..0000000000 --- a/servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl +++ /dev/null @@ -1,99 +0,0 @@ -/* clang-format off */ -[vertex] -/* clang-format on */ - -#version 450 - -layout(location = 0) out highp float u; - -void main() { - - if (gl_VertexIndex==0) { - u=0.0; - gl_Position=vec4(-1.0,-1.0,0.0,1.0); - } else if (gl_VertexIndex==1) { - u=0.0; - gl_Position=vec4(-1.0,1.0,0.0,1.0); - } else if (gl_VertexIndex==2) { - u=1.0; - gl_Position=vec4(1.0,1.0,0.0,1.0); - } else { - u=1.0; - gl_Position=vec4(1.0,-1.0,0.0,1.0); - } -} - -/* clang-format off */ -[fragment] -/* clang-format on */ - -#version 450 - -#define PI 3.14159265359 - -layout(set=0, binding=0) uniform sampler2D textures[4]; -layout(location = 0) in highp float u; -layout(location = 0) out highp float distance; - -layout(push_constant, binding = 0, std430) uniform Constants { - mat4 projection; - float far; - float pad[3]; -} constants; - -void main() { - - //0-1 in the texture we are writing to represents a circle, 0-2PI) - //obtain the quarter circle from the source textures - float angle=fract(u+1.0-0.125); - - float depth; -#if 0 - if (angle<0.25) { - highp float sub_angle = ((angle/0.25)*2.0-1.0)*(PI/4.0); - highp float x=tan(sub_angle)*0.5+0.5; - depth=texture(textures[0],vec2(x,0.0)).x; - } else if (angle<0.50) { - highp float sub_angle = (((angle-0.25)/0.25)*2.0-1.0)*(PI/4.0); - highp float x=tan(sub_angle)*0.5+0.5; - depth=texture(textures[1],vec2(x,0.0)).x; - } else if (angle<0.75) { - highp float sub_angle = (((angle-0.5)/0.25)*2.0-1.0)*(PI/4.0); - highp float x=tan(sub_angle)*0.5+0.5; - depth=texture(textures[2],vec2(x,0.0)).x; - } else { - highp float sub_angle = (((angle-0.75)/0.25)*2.0-1.0)*(PI/4.0); - highp float x=tan(sub_angle)*0.5+0.5; - depth=texture(textures[3],vec2(x,0.0)).x; - } -#else - if (angle<0.25) { - highp float sub_angle = ((angle/0.25)*2.0-1.0)*(PI/4.0); - vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far; - vec4 proj = constants.projection * vec4(pos,0.0,1.0); - float coord = (proj.x/proj.w)*0.5+0.5; - depth=texture(textures[0],vec2(coord,0.0)).x; - } else if (angle<0.50) { - highp float sub_angle = (((angle-0.25)/0.25)*2.0-1.0)*(PI/4.0); - vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far; - vec4 proj = constants.projection * vec4(pos,0.0,1.0); - float coord = (proj.x/proj.w)*0.5+0.5; - depth=texture(textures[1],vec2(coord,0.0)).x; - } else if (angle<0.75) { - highp float sub_angle = (((angle-0.5)/0.25)*2.0-1.0)*(PI/4.0); - vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far; - vec4 proj = constants.projection * vec4(pos,0.0,1.0); - float coord = (proj.x/proj.w)*0.5+0.5; - depth=texture(textures[2],vec2(coord,0.0)).x; - } else { - highp float sub_angle = (((angle-0.75)/0.25)*2.0-1.0)*(PI/4.0); - vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far; - vec4 proj = constants.projection * vec4(pos,0.0,1.0); - float coord = (proj.x/proj.w)*0.5+0.5; - depth=texture(textures[3],vec2(coord,0.0)).x; - } - - -#endif - distance=depth; -} diff --git a/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl b/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl index 36a86c7f63..7b2ec81fb1 100644 --- a/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl +++ b/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl @@ -1,11 +1,8 @@ -/* SET0: Per draw primitive settings */ +/* SET0: Draw Primitive */ #define M_PI 3.14159265359 -#define MAX_LIGHT_TEXTURES 1024 -#define MAX_RENDER_LIGHTS 256 - #define FLAGS_INSTANCING_STRIDE_MASK 0xF #define FLAGS_INSTANCING_ENABLED (1<<4) #define FLAGS_INSTANCING_HAS_COLORS (1 << 5) @@ -64,30 +61,30 @@ layout(set = 0, binding = 5) uniform textureBuffer instancing_buffer; // -/* SET2: Is the skeleton */ +/* SET2: Canvas Item State */ -#ifdef USE_ATTRIBUTES -layout(set = 2, binding = 0) uniform textureBuffer skeleton_buffer; +layout(set = 2, binding = 0, std140) uniform CanvasData { + mat4 canvas_transform; + mat4 screen_transform; + mat4 canvas_normal_transform; + vec4 canvas_modulation; + //uint light_count; +} canvas_data; -layout(set = 2, binding = 1, std140) uniform SkeletonData { +layout(set = 2, binding = 1) uniform textureBuffer skeleton_buffer; + +layout(set = 2, binding = 2, std140) uniform SkeletonData { mat4 skeleton_transform; //in world coordinates mat4 skeleton_transform_inverse; } skeleton_data; -#endif -/* SET3: Per Scene settings */ -layout(set = 3, binding = 0, std140) uniform CanvasData { - mat4 canvas_transform; - mat4 screen_transform; - mat4 canvas_normal_transform; - vec4 canvas_modulation; - //uint light_count; -} canvas_data; +/* SET3: Lighting */ + +#ifdef USE_LIGHTING -#define LIGHT_FLAGS_TEXTURE_MASK 0xFFFF #define LIGHT_FLAGS_BLEND_MASK (3<<16) #define LIGHT_FLAGS_BLEND_MODE_ADD (0<<16) #define LIGHT_FLAGS_BLEND_MODE_SUB (1<<16) @@ -109,17 +106,19 @@ struct Light { vec2 position; uint flags; //index to light texture float height; - float shadow_softness; float shadow_pixel_size; float pad0; float pad1; + float pad2; }; -layout(set = 3, binding = 1, std140) uniform LightData { - Light data[MAX_RENDER_LIGHTS]; +layout(set = 3, binding = 0, std140) uniform LightData { + Light data[MAX_LIGHTS]; } light_array; -layout(set = 3, binding = 2) uniform texture2D light_textures[MAX_LIGHT_TEXTURES]; -layout(set = 3, binding = 3) uniform texture2D shadow_textures[MAX_LIGHT_TEXTURES]; +layout(set = 3, binding = 1) uniform texture2D light_textures[MAX_LIGHT_TEXTURES]; +layout(set = 3, binding = 2) uniform texture2D shadow_textures[MAX_LIGHT_TEXTURES]; -layout(set = 3, binding = 4) uniform sampler shadow_sampler; +layout(set = 3, binding = 3) uniform sampler shadow_sampler; + +#endif |