summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2019-07-10 17:44:55 -0300
committerJuan Linietsky <reduzio@gmail.com>2020-02-11 11:53:28 +0100
commitef083a583b3bd833d36fadb80a9ee8e9081d394e (patch)
treeb26b4497b8f1b6f6442121ae0181a3038500df59 /servers
parenta3f8ffac63a95d0ebcbe2f0b864e0ea33d29e1d3 (diff)
Modified light rendering to make it more compatible.
Modified polygon management to make it more compatible with MoltenVK
Diffstat (limited to 'servers')
-rw-r--r--servers/visual/rasterizer/rasterizer.h15
-rw-r--r--servers/visual/rasterizer/rasterizer_canvas_rd.cpp562
-rw-r--r--servers/visual/rasterizer/rasterizer_canvas_rd.h79
-rw-r--r--servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.cpp50
-rw-r--r--servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h22
-rw-r--r--servers/visual/rasterizer/shader_rd.cpp6
-rw-r--r--servers/visual/rasterizer/shader_rd.h3
-rw-r--r--servers/visual/rasterizer/shaders/SCsub1
-rw-r--r--servers/visual/rasterizer/shaders/canvas.glsl58
-rw-r--r--servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl99
-rw-r--r--servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl47
-rw-r--r--servers/visual/rendering_device.h41
-rw-r--r--servers/visual/visual_server_canvas.cpp32
-rw-r--r--servers/visual/visual_server_canvas.h1
-rw-r--r--servers/visual/visual_server_raster.h1
-rw-r--r--servers/visual/visual_server_wrap_mt.h1
-rw-r--r--servers/visual_server.cpp1
-rw-r--r--servers/visual_server.h1
18 files changed, 544 insertions, 476 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 *&current_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 *&current_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 *&current_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 *&current_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
diff --git a/servers/visual/rendering_device.h b/servers/visual/rendering_device.h
index 8f0578b874..11a3e7e052 100644
--- a/servers/visual/rendering_device.h
+++ b/servers/visual/rendering_device.h
@@ -334,6 +334,7 @@ public:
}
};
+
struct TextureView {
DataFormat format_override;
TextureSwizzle swizzle_r;
@@ -352,6 +353,8 @@ public:
virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<PoolVector<uint8_t> > &p_data = Vector<PoolVector<uint8_t> >()) = 0;
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture) = 0;
+ virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture,int p_layer,int p_mipmap) = 0;
+
virtual Error texture_update(RID p_texture, uint32_t p_layer, const PoolVector<uint8_t> &p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the begining of the frame, unless sync with draw is used, which is used to mix updates with draw calls
virtual PoolVector<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
@@ -373,6 +376,7 @@ public:
// This ID is warranted to be unique for the same formats, does not need to be freed
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format) = 0;
+ virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format) =0;
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID) = 0;
@@ -865,12 +869,49 @@ public:
virtual void draw_list_end() = 0;
+
/***************/
/**** FREE! ****/
/***************/
virtual void free(RID p_id) = 0;
+ /****************/
+ /**** LIMITS ****/
+ /****************/
+
+ enum Limit {
+ LIMIT_MAX_BOUND_UNIFORM_SETS,
+ LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS,
+ LIMIT_MAX_TEXTURES_PER_UNIFORM_SET,
+ LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET,
+ LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET,
+ LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET,
+ LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET,
+ LIMIT_MAX_DRAW_INDEXED_INDEX,
+ LIMIT_MAX_FRAMEBUFFER_HEIGHT,
+ LIMIT_MAX_FRAMEBUFFER_WIDTH,
+ LIMIT_MAX_TEXTURE_ARRAY_LAYERS,
+ LIMIT_MAX_TEXTURE_SIZE_1D,
+ LIMIT_MAX_TEXTURE_SIZE_2D,
+ LIMIT_MAX_TEXTURE_SIZE_3D,
+ LIMIT_MAX_TEXTURE_SIZE_CUBE,
+ LIMIT_MAX_TEXTURES_PER_SHADER_STAGE,
+ LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE,
+ LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE,
+ LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE,
+ LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE,
+ LIMIT_MAX_PUSH_CONSTANT_SIZE,
+ LIMIT_MAX_UNIFORM_BUFFER_SIZE,
+ LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET,
+ LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES,
+ LIMIT_MAX_VERTEX_INPUT_BINDINGS,
+ LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE,
+ LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT ,
+ };
+
+ virtual int limit_get(Limit p_limit) =0;
+
//methods below not exposed, used by RenderingDeviceRD
virtual void prepare_screen_for_drawing() =0;
virtual void finalize_frame() = 0;
diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp
index 9854fa5491..80d7f70f2b 100644
--- a/servers/visual/visual_server_canvas.cpp
+++ b/servers/visual/visual_server_canvas.cpp
@@ -65,14 +65,13 @@ void VisualServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas
VSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_transform);
}
-void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2D p_transform, VisualServerCanvas::Item *p_material_owner, const Color p_modulate, VisualServerCanvas::Item **r_items, int &r_index) {
+void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2D p_transform, VisualServerCanvas::Item *p_material_owner, VisualServerCanvas::Item **r_items, int &r_index) {
int child_item_count = p_canvas_item->child_items.size();
VisualServerCanvas::Item **child_items = p_canvas_item->child_items.ptrw();
for (int i = 0; i < child_item_count; i++) {
if (child_items[i]->visible) {
if (r_items) {
r_items[r_index] = child_items[i];
- child_items[i]->ysort_modulate = p_modulate;
child_items[i]->ysort_xform = p_transform;
child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.elements[2]);
child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : NULL;
@@ -81,11 +80,7 @@ void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2
r_index++;
if (child_items[i]->sort_y)
- _collect_ysort_children(child_items[i],
- p_transform * child_items[i]->xform,
- child_items[i]->use_parent_material ? p_material_owner : child_items[i],
- p_modulate * child_items[i]->modulate,
- r_items, r_index);
+ _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index);
}
}
}
@@ -146,14 +141,14 @@ void VisualServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transform2
if (ci->ysort_children_count == -1) {
ci->ysort_children_count = 0;
- _collect_ysort_children(ci, Transform2D(), p_material_owner, Color(1, 1, 1, 1), NULL, ci->ysort_children_count);
+ _collect_ysort_children(ci, Transform2D(), p_material_owner, NULL, ci->ysort_children_count);
}
child_item_count = ci->ysort_children_count;
child_items = (Item **)alloca(child_item_count * sizeof(Item *));
int i = 0;
- _collect_ysort_children(ci, Transform2D(), p_material_owner, Color(1, 1, 1, 1), child_items, i);
+ _collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i);
SortArray<Item *, ItemPtrSort> sorter;
sorter.sort(child_items, child_item_count);
@@ -169,7 +164,7 @@ void VisualServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transform2
if (!child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y))
continue;
if (ci->sort_y) {
- _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate * child_items[i]->ysort_modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
+ _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
} else {
_cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
}
@@ -213,7 +208,7 @@ void VisualServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transform2
if (child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y))
continue;
if (ci->sort_y) {
- _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate * child_items[i]->ysort_modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
+ _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
} else {
_cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
}
@@ -835,7 +830,7 @@ void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector
ERR_FAIL_COND(!p_bones.empty() && p_bones.size() != vertex_count * 4);
ERR_FAIL_COND(!p_weights.empty() && p_weights.size() != vertex_count * 4);
- const Vector<int> &indices = p_indices;
+ Vector<int> indices = p_indices;
Item::CommandPolygon *polygon = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!polygon);
@@ -1057,6 +1052,7 @@ void VisualServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture) {
ERR_FAIL_COND(!clight);
clight->texture = p_texture;
+ clight->version++;
VSG::canvas_render->light_set_texture(clight->light_internal, p_texture);
}
void VisualServerCanvas::canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) {
@@ -1134,7 +1130,7 @@ void VisualServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_ena
return;
}
clight->use_shadow = p_enabled;
-
+ clight->version++;
VSG::canvas_render->light_set_use_shadow(clight->light_internal, clight->use_shadow, clight->shadow_buffer_size);
}
@@ -1150,19 +1146,11 @@ void VisualServerCanvas::canvas_light_set_shadow_buffer_size(RID p_light, int p_
return;
clight->shadow_buffer_size = next_power_of_2(p_size);
+ clight->version++;
VSG::canvas_render->light_set_use_shadow(clight->light_internal, clight->use_shadow, clight->shadow_buffer_size);
}
-void VisualServerCanvas::canvas_light_set_shadow_gradient_length(RID p_light, float p_length) {
-
- ERR_FAIL_COND(p_length < 0);
-
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
- ERR_FAIL_COND(!clight);
-
- clight->shadow_gradient_length = p_length;
-}
void VisualServerCanvas::canvas_light_set_shadow_filter(RID p_light, VS::CanvasLightShadowFilter p_filter) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h
index 1f8d0bba59..d87d40739f 100644
--- a/servers/visual/visual_server_canvas.h
+++ b/servers/visual/visual_server_canvas.h
@@ -245,7 +245,6 @@ public:
void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled);
void canvas_light_set_shadow_buffer_size(RID p_light, int p_size);
- void canvas_light_set_shadow_gradient_length(RID p_light, float p_length);
void canvas_light_set_shadow_filter(RID p_light, VS::CanvasLightShadowFilter p_filter);
void canvas_light_set_shadow_color(RID p_light, const Color &p_color);
void canvas_light_set_shadow_smooth(RID p_light, float p_smooth);
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 203aba1b95..feb454c425 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -658,7 +658,6 @@ public:
BIND2(canvas_light_set_shadow_enabled, RID, bool)
BIND2(canvas_light_set_shadow_buffer_size, RID, int)
- BIND2(canvas_light_set_shadow_gradient_length, RID, float)
BIND2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter)
BIND2(canvas_light_set_shadow_color, RID, const Color &)
BIND2(canvas_light_set_shadow_smooth, RID, float)
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index ab0bb78175..bd813be6b1 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -571,7 +571,6 @@ public:
FUNC2(canvas_light_set_shadow_enabled, RID, bool)
FUNC2(canvas_light_set_shadow_buffer_size, RID, int)
- FUNC2(canvas_light_set_shadow_gradient_length, RID, float)
FUNC2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter)
FUNC2(canvas_light_set_shadow_color, RID, const Color &)
FUNC2(canvas_light_set_shadow_smooth, RID, float)
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 02f7e2869d..0b2b339a31 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1977,7 +1977,6 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("canvas_light_set_mode", "light", "mode"), &VisualServer::canvas_light_set_mode);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_enabled", "light", "enabled"), &VisualServer::canvas_light_set_shadow_enabled);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_buffer_size", "light", "size"), &VisualServer::canvas_light_set_shadow_buffer_size);
- ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_gradient_length", "light", "length"), &VisualServer::canvas_light_set_shadow_gradient_length);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_filter", "light", "filter"), &VisualServer::canvas_light_set_shadow_filter);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_color", "light", "color"), &VisualServer::canvas_light_set_shadow_color);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_smooth", "light", "smooth"), &VisualServer::canvas_light_set_shadow_smooth);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index f92caf9ccf..5d24a9cd84 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -965,7 +965,6 @@ public:
virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) = 0;
virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size) = 0;
- virtual void canvas_light_set_shadow_gradient_length(RID p_light, float p_length) = 0;
virtual void canvas_light_set_shadow_filter(RID p_light, CanvasLightShadowFilter p_filter) = 0;
virtual void canvas_light_set_shadow_color(RID p_light, const Color &p_color) = 0;
virtual void canvas_light_set_shadow_smooth(RID p_light, float p_smooth) = 0;