diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/SCsub | 1 | ||||
-rw-r--r-- | drivers/gles3/effects/copy_effects.cpp | 4 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.cpp | 203 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.h | 9 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 9 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 2 | ||||
-rw-r--r-- | drivers/gles3/shaders/canvas.glsl | 219 | ||||
-rw-r--r-- | drivers/gles3/shaders/canvas_uniforms_inc.glsl | 36 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 51 | ||||
-rw-r--r-- | drivers/gles3/storage/config.cpp | 2 | ||||
-rw-r--r-- | drivers/gles3/storage/config.h | 2 | ||||
-rw-r--r-- | drivers/gles3/storage/material_storage.cpp | 465 | ||||
-rw-r--r-- | drivers/gles3/storage/material_storage.h | 57 | ||||
-rw-r--r-- | drivers/gles3/storage/utilities.cpp | 3 | ||||
-rw-r--r-- | drivers/register_driver_types.cpp | 2 | ||||
-rw-r--r-- | drivers/spirv-reflect/SCsub | 17 | ||||
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.cpp | 662 | ||||
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.h | 20 |
18 files changed, 483 insertions, 1281 deletions
diff --git a/drivers/SCsub b/drivers/SCsub index 6cfcb1d18c..276b99e10b 100644 --- a/drivers/SCsub +++ b/drivers/SCsub @@ -24,7 +24,6 @@ SConscript("winmidi/SCsub") # Graphics drivers if env["vulkan"]: - SConscript("spirv-reflect/SCsub") SConscript("vulkan/SCsub") if env["opengl3"]: SConscript("gl_context/SCsub") diff --git a/drivers/gles3/effects/copy_effects.cpp b/drivers/gles3/effects/copy_effects.cpp index b552b52cd5..58cdc90a7c 100644 --- a/drivers/gles3/effects/copy_effects.cpp +++ b/drivers/gles3/effects/copy_effects.cpp @@ -148,8 +148,8 @@ void CopyEffects::bilinear_blur(GLuint p_source_texture, int p_mipmap_count, con dest_region.size.y = MAX(1, dest_region.size.y >> 1); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[i % 2]); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_source_texture, i); - glBlitFramebuffer(source_region.position.x, source_region.position.y, source_region.size.x, source_region.size.y, - dest_region.position.x, dest_region.position.y, dest_region.size.x, dest_region.size.y, GL_COLOR_BUFFER_BIT, GL_LINEAR); + glBlitFramebuffer(source_region.position.x, source_region.position.y, source_region.position.x + source_region.size.x, source_region.position.y + source_region.size.y, + dest_region.position.x, dest_region.position.y, dest_region.position.x + dest_region.size.x, dest_region.position.y + dest_region.size.y, GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[i % 2]); source_region = dest_region; } diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index e5d4077393..be18b008be 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -454,7 +454,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ update_skeletons = false; } // Canvas group begins here, render until before this item - _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, starting_index, false); + _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, starting_index, r_sdf_used); item_count = 0; if (ci->canvas_group_owner->canvas_group->mode != RS::CANVAS_GROUP_MODE_TRANSPARENT) { @@ -485,7 +485,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ mesh_storage->update_mesh_instances(); update_skeletons = false; } - _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, starting_index, true); + _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, starting_index, r_sdf_used, true); item_count = 0; if (ci->canvas_group->blur_mipmaps) { @@ -504,7 +504,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ } //render anything pending, including clearing if no items - _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, starting_index, false); + _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, starting_index, r_sdf_used); item_count = 0; texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, backbuffer_gen_mipmaps); @@ -530,7 +530,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ mesh_storage->update_mesh_instances(); update_skeletons = false; } - _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, starting_index, false); + _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, starting_index, r_sdf_used); //then reset item_count = 0; } @@ -549,7 +549,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ state.current_buffer = (state.current_buffer + 1) % state.canvas_instance_data_buffers.size(); } -void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, uint32_t &r_last_index, bool p_to_backbuffer) { +void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, uint32_t &r_last_index, bool &r_sdf_used, bool p_to_backbuffer) { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); canvas_begin(p_to_render_target, p_to_backbuffer); @@ -568,9 +568,8 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou _new_batch(batch_broken, index); // Override the start position and index as we want to start from where we finished off last time. - state.canvas_instance_batches[state.current_batch_index].start = r_last_index * sizeof(InstanceData); + state.canvas_instance_batches[state.current_batch_index].start = r_last_index; index = 0; - _align_instance_data_buffer(index); for (int i = 0; i < p_item_count; i++) { Item *ci = items[i]; @@ -588,10 +587,12 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou material = default_clip_children_material; } } else { - if (ci->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_ONLY) { - material = default_clip_children_material; - } else { - material = default_canvas_group_material; + if (material.is_null()) { + if (ci->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_ONLY) { + material = default_clip_children_material; + } else { + material = default_canvas_group_material; + } } } } @@ -617,7 +618,7 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou GLES3::CanvasShaderData::BlendMode blend_mode = shader_data_cache ? shader_data_cache->blend_mode : GLES3::CanvasShaderData::BLEND_MODE_MIX; - _record_item_commands(ci, p_to_render_target, p_canvas_transform_inverse, current_clip, blend_mode, p_lights, index, batch_broken); + _record_item_commands(ci, p_to_render_target, p_canvas_transform_inverse, current_clip, blend_mode, p_lights, index, batch_broken, r_sdf_used); } if (index == 0) { @@ -628,14 +629,14 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou } // Copy over all data needed for rendering. - glBindBuffer(GL_UNIFORM_BUFFER, state.canvas_instance_data_buffers[state.current_buffer].ubo); + glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_buffer].buffer); #ifdef WEB_ENABLED - glBufferSubData(GL_UNIFORM_BUFFER, r_last_index * sizeof(InstanceData), sizeof(InstanceData) * index, state.instance_data_array); + glBufferSubData(GL_ARRAY_BUFFER, r_last_index * sizeof(InstanceData), sizeof(InstanceData) * index, state.instance_data_array); #else // On Desktop and mobile we map the memory without synchronizing for maximum speed. - void *ubo = glMapBufferRange(GL_UNIFORM_BUFFER, r_last_index * sizeof(InstanceData), index * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); - memcpy(ubo, state.instance_data_array, index * sizeof(InstanceData)); - glUnmapBuffer(GL_UNIFORM_BUFFER); + void *buffer = glMapBufferRange(GL_ARRAY_BUFFER, r_last_index * sizeof(InstanceData), index * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); + memcpy(buffer, state.instance_data_array, index * sizeof(InstanceData)); + glUnmapBuffer(GL_ARRAY_BUFFER); #endif glDisable(GL_SCISSOR_TEST); @@ -662,7 +663,17 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou uint64_t specialization = 0; specialization |= uint64_t(state.canvas_instance_batches[i].lights_disabled); specialization |= uint64_t(!GLES3::Config::get_singleton()->float_texture_supported) << 1; - bool success = _bind_material(material_data, variant, specialization); + RID shader_version = data.canvas_shader_default_version; + + if (material_data) { + if (material_data->shader_data->version.is_valid() && material_data->shader_data->valid) { + // Bind uniform buffer and textures + material_data->bind_uniforms(); + shader_version = material_data->shader_data->version; + } + } + + bool success = GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_bind_shader(shader_version, variant, specialization); if (!success) { continue; } @@ -749,7 +760,7 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou r_last_index += index; } -void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_batch_broken) { +void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_batch_broken, bool &r_sdf_used) { RenderingServer::CanvasItemTextureFilter texture_filter = p_item->texture_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? state.default_filter : p_item->texture_filter; if (texture_filter != state.canvas_instance_batches[state.current_batch_index].filter) { @@ -1145,6 +1156,7 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend } else { particles_storage->particles_set_canvas_sdf_collision(pt->particles, false, Transform2D(), Rect2(), 0); } + r_sdf_used |= particles_storage->particles_has_collision(particles); } state.canvas_instance_batches[state.current_batch_index].command = c; @@ -1214,26 +1226,15 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) { _bind_canvas_texture(state.canvas_instance_batches[p_index].tex, state.canvas_instance_batches[p_index].filter, state.canvas_instance_batches[p_index].repeat); - // Bind the region of the UBO used by this batch. - // If region exceeds the boundary of the UBO, just ignore. - uint32_t range_bytes = data.max_instances_per_batch * sizeof(InstanceData); - if (state.canvas_instance_batches[p_index].start >= (data.max_instances_per_ubo - 1) * sizeof(InstanceData)) { - return; - } else if (state.canvas_instance_batches[p_index].start >= (data.max_instances_per_ubo - data.max_instances_per_batch) * sizeof(InstanceData)) { - // If we have less than a full batch at the end, we can just draw it anyway. - // OpenGL will complain about the UBO being smaller than expected, but it should render fine. - range_bytes = (data.max_instances_per_ubo - 1) * sizeof(InstanceData) - state.canvas_instance_batches[p_index].start; - } - - uint32_t range_start = state.canvas_instance_batches[p_index].start; - glBindBufferRange(GL_UNIFORM_BUFFER, INSTANCE_UNIFORM_LOCATION, state.canvas_instance_data_buffers[state.current_buffer].ubo, range_start, range_bytes); - switch (state.canvas_instance_batches[p_index].command_type) { case Item::Command::TYPE_RECT: case Item::Command::TYPE_NINEPATCH: { glBindVertexArray(data.indexed_quad_array); - glDrawElements(GL_TRIANGLES, state.canvas_instance_batches[p_index].instance_count * 6, GL_UNSIGNED_INT, 0); - glBindBuffer(GL_UNIFORM_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_buffer].buffer); + uint32_t range_start = state.canvas_instance_batches[p_index].start * sizeof(InstanceData); + _enable_attributes(range_start, false); + + glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0, state.canvas_instance_batches[p_index].instance_count); glBindVertexArray(0); } break; @@ -1245,18 +1246,21 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) { ERR_FAIL_COND(!pb); glBindVertexArray(pb->vertex_array); + glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_buffer].buffer); + + uint32_t range_start = state.canvas_instance_batches[p_index].start * sizeof(InstanceData); + _enable_attributes(range_start, false); if (pb->color_disabled && pb->color != Color(1.0, 1.0, 1.0, 1.0)) { glVertexAttrib4f(RS::ARRAY_COLOR, pb->color.r, pb->color.g, pb->color.b, pb->color.a); } if (pb->index_buffer != 0) { - glDrawElements(prim[polygon->primitive], pb->count, GL_UNSIGNED_INT, nullptr); + glDrawElementsInstanced(prim[polygon->primitive], pb->count, GL_UNSIGNED_INT, nullptr, 1); } else { - glDrawArrays(prim[polygon->primitive], 0, pb->count); + glDrawArraysInstanced(prim[polygon->primitive], 0, pb->count, 1); } glBindVertexArray(0); - glBindBuffer(GL_UNIFORM_BUFFER, 0); if (pb->color_disabled && pb->color != Color(1.0, 1.0, 1.0, 1.0)) { // Reset so this doesn't pollute other draw calls. @@ -1266,14 +1270,16 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) { case Item::Command::TYPE_PRIMITIVE: { glBindVertexArray(data.canvas_quad_array); + glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_buffer].buffer); + uint32_t range_start = state.canvas_instance_batches[p_index].start * sizeof(InstanceData); + _enable_attributes(range_start, true); + const GLenum primitive[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLES }; int instance_count = state.canvas_instance_batches[p_index].instance_count; - if (instance_count > 1) { + ERR_FAIL_COND(instance_count <= 0); + if (instance_count >= 1) { glDrawArraysInstanced(primitive[state.canvas_instance_batches[p_index].primitive_points], 0, state.canvas_instance_batches[p_index].primitive_points, instance_count); - } else { - glDrawArrays(primitive[state.canvas_instance_batches[p_index].primitive_points], 0, state.canvas_instance_batches[p_index].primitive_points); } - glBindBuffer(GL_UNIFORM_BUFFER, 0); } break; @@ -1367,6 +1373,11 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) { index_array_gl = mesh_storage->mesh_surface_get_index_buffer(surface, 0); bool use_index_buffer = false; glBindVertexArray(vertex_array_gl); + glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_buffer].buffer); + + uint32_t range_start = state.canvas_instance_batches[p_index].start * sizeof(InstanceData); + _enable_attributes(range_start, false, instance_count); + if (index_array_gl != 0) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_gl); use_index_buffer = true; @@ -1393,20 +1404,13 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) { } GLenum primitive_gl = prim[int(primitive)]; - if (instance_count == 1) { - if (use_index_buffer) { - glDrawElements(primitive_gl, mesh_storage->mesh_surface_get_vertices_drawn_count(surface), mesh_storage->mesh_surface_get_index_type(surface), 0); - } else { - glDrawArrays(primitive_gl, 0, mesh_storage->mesh_surface_get_vertices_drawn_count(surface)); - } - } else if (instance_count > 1) { - if (use_index_buffer) { - glDrawElementsInstanced(primitive_gl, mesh_storage->mesh_surface_get_vertices_drawn_count(surface), mesh_storage->mesh_surface_get_index_type(surface), 0, instance_count); - } else { - glDrawArraysInstanced(primitive_gl, 0, mesh_storage->mesh_surface_get_vertices_drawn_count(surface), instance_count); - } - } + if (use_index_buffer) { + glDrawElementsInstanced(primitive_gl, mesh_storage->mesh_surface_get_vertices_drawn_count(surface), mesh_storage->mesh_surface_get_index_type(surface), 0, instance_count); + } else { + glDrawArraysInstanced(primitive_gl, 0, mesh_storage->mesh_surface_get_vertices_drawn_count(surface), instance_count); + } + glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); if (instance_count > 1) { glDisableVertexAttribArray(5); @@ -1426,7 +1430,7 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) { } void RasterizerCanvasGLES3::_add_to_batch(uint32_t &r_index, bool &r_batch_broken) { - if (r_index >= data.max_instances_per_ubo - 1) { + if (r_index >= data.max_instances_per_buffer - 1) { ERR_PRINT_ONCE("Trying to draw too many items. Please increase maximum number of items in the project settings 'rendering/gl_compatibility/item_buffer_size'"); return; } @@ -1454,27 +1458,25 @@ void RasterizerCanvasGLES3::_new_batch(bool &r_batch_broken, uint32_t &r_index) // Copy the properties of the current batch, we will manually update the things that changed. Batch new_batch = state.canvas_instance_batches[state.current_batch_index]; new_batch.instance_count = 0; - new_batch.start = state.canvas_instance_batches[state.current_batch_index].start + state.canvas_instance_batches[state.current_batch_index].instance_count * sizeof(InstanceData); + new_batch.start = state.canvas_instance_batches[state.current_batch_index].start + state.canvas_instance_batches[state.current_batch_index].instance_count; state.current_batch_index++; state.canvas_instance_batches.push_back(new_batch); - _align_instance_data_buffer(r_index); } -bool RasterizerCanvasGLES3::_bind_material(GLES3::CanvasMaterialData *p_material_data, CanvasShaderGLES3::ShaderVariant p_variant, uint64_t p_specialization) { - if (p_material_data) { - if (p_material_data->shader_data->version.is_valid() && p_material_data->shader_data->valid) { - // Bind uniform buffer and textures - p_material_data->bind_uniforms(); - return GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_bind_shader(p_material_data->shader_data->version, p_variant, p_specialization); - } else { - return GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_bind_shader(data.canvas_shader_default_version, p_variant, p_specialization); - } - } else { - return GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_bind_shader(data.canvas_shader_default_version, p_variant, p_specialization); +void RasterizerCanvasGLES3::_enable_attributes(uint32_t p_start, bool p_primitive, uint32_t p_rate) { + uint32_t split = p_primitive ? 11 : 12; + for (uint32_t i = 6; i < split; i++) { + glEnableVertexAttribArray(i); + glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, sizeof(InstanceData), CAST_INT_TO_UCHAR_PTR(p_start + (i - 6) * 4 * sizeof(float))); + glVertexAttribDivisor(i, p_rate); + } + for (uint32_t i = split; i <= 13; i++) { + glEnableVertexAttribArray(i); + glVertexAttribIPointer(i, 4, GL_UNSIGNED_INT, sizeof(InstanceData), CAST_INT_TO_UCHAR_PTR(p_start + (i - 6) * 4 * sizeof(float))); + glVertexAttribDivisor(i, p_rate); } } - RID RasterizerCanvasGLES3::light_create() { CanvasLight canvas_light; return canvas_light_owner.make_rid(canvas_light); @@ -2413,8 +2415,8 @@ void RasterizerCanvasGLES3::_allocate_instance_data_buffer() { GLuint new_buffers[3]; glGenBuffers(3, new_buffers); // Batch UBO. - glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[0]); - glBufferData(GL_UNIFORM_BUFFER, data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, new_buffers[0]); + glBufferData(GL_ARRAY_BUFFER, data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW); // Light uniform buffer. glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[1]); glBufferData(GL_UNIFORM_BUFFER, sizeof(LightUniform) * data.max_lights_per_render, nullptr, GL_STREAM_DRAW); @@ -2424,36 +2426,16 @@ void RasterizerCanvasGLES3::_allocate_instance_data_buffer() { state.current_buffer = (state.current_buffer + 1); DataBuffer db; - db.ubo = new_buffers[0]; + db.buffer = new_buffers[0]; db.light_ubo = new_buffers[1]; db.state_ubo = new_buffers[2]; db.last_frame_used = RSG::rasterizer->get_frame_number(); state.canvas_instance_data_buffers.insert(state.current_buffer, db); state.current_buffer = state.current_buffer % state.canvas_instance_data_buffers.size(); + glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_UNIFORM_BUFFER, 0); } -// Batch start positions need to be aligned to the device's GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT. -// This needs to be called anytime a new batch is created. -void RasterizerCanvasGLES3::_align_instance_data_buffer(uint32_t &r_index) { - if (GLES3::Config::get_singleton()->uniform_buffer_offset_alignment > int(sizeof(InstanceData))) { - uint32_t offset = state.canvas_instance_batches[state.current_batch_index].start % GLES3::Config::get_singleton()->uniform_buffer_offset_alignment; - if (offset > 0) { - // uniform_buffer_offset_alignment can be 4, 16, 32, or 256. Our instance batches are 128 bytes. - // Accordingly, this branch is only triggered if we are 128 bytes off. - uint32_t offset_bytes = GLES3::Config::get_singleton()->uniform_buffer_offset_alignment - offset; - state.canvas_instance_batches[state.current_batch_index].start += offset_bytes; - // Offset the instance array so it stays in sync with batch start points. - // This creates gaps in the instance buffer with wasted space, but we can't help it. - r_index += offset_bytes / sizeof(InstanceData); - if (r_index > 0) { - // In this case we need to copy over the basic data. - state.instance_data_array[r_index] = state.instance_data_array[r_index - 1]; - } - } - } -} - void RasterizerCanvasGLES3::set_time(double p_time) { state.time = p_time; } @@ -2598,12 +2580,12 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() { data.max_instances_per_batch = 128; } else { data.max_lights_per_render = 256; - data.max_instances_per_batch = 512; + data.max_instances_per_batch = 2048; } // Reserve 3 Uniform Buffers for instance data Frame N, N+1 and N+2 - data.max_instances_per_ubo = MAX(data.max_instances_per_batch, uint32_t(GLOBAL_GET("rendering/gl_compatibility/item_buffer_size"))); - data.max_instance_buffer_size = data.max_instances_per_ubo * sizeof(InstanceData); // 16,384 instances * 128 bytes = 2,097,152 bytes = 2,048 kb + data.max_instances_per_buffer = MAX(data.max_instances_per_batch, uint32_t(GLOBAL_GET("rendering/gl_compatibility/item_buffer_size"))); + data.max_instance_buffer_size = data.max_instances_per_buffer * sizeof(InstanceData); // 16,384 instances * 128 bytes = 2,097,152 bytes = 2,048 kb state.canvas_instance_data_buffers.resize(3); state.canvas_instance_batches.reserve(200); @@ -2611,8 +2593,8 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() { GLuint new_buffers[3]; glGenBuffers(3, new_buffers); // Batch UBO. - glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[0]); - glBufferData(GL_UNIFORM_BUFFER, data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, new_buffers[0]); + glBufferData(GL_ARRAY_BUFFER, data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW); // Light uniform buffer. glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[1]); glBufferData(GL_UNIFORM_BUFFER, sizeof(LightUniform) * data.max_lights_per_render, nullptr, GL_STREAM_DRAW); @@ -2620,41 +2602,28 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() { glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[2]); glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), nullptr, GL_STREAM_DRAW); DataBuffer db; - db.ubo = new_buffers[0]; + db.buffer = new_buffers[0]; db.light_ubo = new_buffers[1]; db.state_ubo = new_buffers[2]; db.last_frame_used = 0; db.fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); state.canvas_instance_data_buffers[i] = db; } + glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_UNIFORM_BUFFER, 0); - state.instance_data_array = memnew_arr(InstanceData, data.max_instances_per_ubo); + state.instance_data_array = memnew_arr(InstanceData, data.max_instances_per_buffer); state.light_uniforms = memnew_arr(LightUniform, data.max_lights_per_render); { - const uint32_t no_of_instances = data.max_instances_per_batch; - + const uint32_t indices[6] = { 0, 2, 1, 3, 2, 0 }; glGenVertexArrays(1, &data.indexed_quad_array); glBindVertexArray(data.indexed_quad_array); glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices); - - const uint32_t num_indices = 6; - const uint32_t quad_indices[num_indices] = { 0, 2, 1, 3, 2, 0 }; - - const uint32_t total_indices = no_of_instances * num_indices; - uint32_t *indices = new uint32_t[total_indices]; - for (uint32_t i = 0; i < total_indices; i++) { - uint32_t quad = i / num_indices; - uint32_t quad_local = i % num_indices; - indices[i] = quad_indices[quad_local] + quad * num_indices; - } - glGenBuffers(1, &data.indexed_quad_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.indexed_quad_buffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * total_indices, indices, GL_STATIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * 6, indices, GL_STATIC_DRAW); glBindVertexArray(0); - delete[] indices; } String global_defines; diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h index 0a03d43d07..d99a8414f7 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.h +++ b/drivers/gles3/rasterizer_canvas_gles3.h @@ -245,7 +245,7 @@ public: uint32_t max_lights_per_render = 256; uint32_t max_lights_per_item = 16; uint32_t max_instances_per_batch = 512; - uint32_t max_instances_per_ubo = 16384; + uint32_t max_instances_per_buffer = 16384; uint32_t max_instance_buffer_size = 16384 * 128; } data; @@ -278,7 +278,7 @@ public: // We track them and ensure that they don't get reused until at least 2 frames have passed // to avoid the GPU stalling to wait for a resource to become available. struct DataBuffer { - GLuint ubo = 0; + GLuint buffer = 0; GLuint light_ubo = 0; GLuint state_ubo = 0; uint64_t last_frame_used = -3; @@ -351,14 +351,15 @@ public: void _prepare_canvas_texture(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, uint32_t &r_index, Size2 &r_texpixel_size); void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) override; - void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, uint32_t &r_last_index, bool p_to_backbuffer = false); - void _record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_break_batch); + void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, uint32_t &r_last_index, bool &r_sdf_used, bool p_to_backbuffer = false); + void _record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_break_batch, bool &r_sdf_used); void _render_batch(Light *p_lights, uint32_t p_index); bool _bind_material(GLES3::CanvasMaterialData *p_material_data, CanvasShaderGLES3::ShaderVariant p_variant, uint64_t p_specialization); void _new_batch(bool &r_batch_broken, uint32_t &r_index); void _add_to_batch(uint32_t &r_index, bool &r_batch_broken); void _allocate_instance_data_buffer(); void _align_instance_data_buffer(uint32_t &r_index); + void _enable_attributes(uint32_t p_start, bool p_primitive, uint32_t p_rate = 1); void set_time(double p_time); diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 247b89658a..ae5515e249 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1068,10 +1068,6 @@ void RasterizerSceneGLES3::environment_glow_set_use_bicubic_upscale(bool p_enabl glow_bicubic_upscale = p_enable; } -void RasterizerSceneGLES3::environment_glow_set_use_high_quality(bool p_enable) { - glow_high_quality = p_enable; -} - void RasterizerSceneGLES3::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) { } @@ -2210,10 +2206,13 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, glBindVertexArray(vertex_array_gl); } prev_vertex_array_gl = vertex_array_gl; + + // Invalidate the previous index array + prev_index_array_gl = 0; } bool use_index_buffer = index_array_gl != 0; - if (prev_index_array_gl != index_array_gl || prev_vertex_array_gl != vertex_array_gl) { + if (prev_index_array_gl != index_array_gl) { if (index_array_gl != 0) { // Bind index each time so we can use LODs glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_gl); diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 255e62fc33..65cc8606b8 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -497,7 +497,6 @@ protected: float ssao_fadeout_to = 300.0; bool glow_bicubic_upscale = false; - bool glow_high_quality = false; RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGHNESS_QUALITY_LOW; /* Sky */ @@ -610,7 +609,6 @@ public: /* ENVIRONMENT API */ void environment_glow_set_use_bicubic_upscale(bool p_enable) override; - void environment_glow_set_use_high_quality(bool p_enable) override; void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override; diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index c1c26ed963..9a90f33674 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -11,6 +11,7 @@ mode_instanced = #define USE_ATTRIBUTES \n#define USE_INSTANCING DISABLE_LIGHTING = false USE_RGBA_SHADOWS = false +SINGLE_INSTANCE = false #[vertex] @@ -25,9 +26,74 @@ layout(location = 1) in highp vec4 instance_xform0; layout(location = 2) in highp vec4 instance_xform1; layout(location = 5) in highp uvec4 instance_color_custom_data; // Color packed into xy, custom_data packed into zw for compatibility with 3D +#endif // USE_INSTANCING + +#endif // USE_ATTRIBUTES + +#include "stdlib_inc.glsl" + +layout(location = 6) in highp vec4 attrib_A; +layout(location = 7) in highp vec4 attrib_B; +layout(location = 8) in highp vec4 attrib_C; +layout(location = 9) in highp vec4 attrib_D; +layout(location = 10) in highp vec4 attrib_E; +#ifdef USE_PRIMITIVE +layout(location = 11) in highp uvec4 attrib_F; +#else +layout(location = 11) in highp vec4 attrib_F; +#endif +layout(location = 12) in highp uvec4 attrib_G; +layout(location = 13) in highp uvec4 attrib_H; + +#define read_draw_data_world_x attrib_A.xy +#define read_draw_data_world_y attrib_A.zw +#define read_draw_data_world_ofs attrib_B.xy +#define read_draw_data_color_texture_pixel_size attrib_B.zw + +#ifdef USE_PRIMITIVE + +#define read_draw_data_point_a attrib_C.xy +#define read_draw_data_point_b attrib_C.zw +#define read_draw_data_point_c attrib_D.xy +#define read_draw_data_uv_a attrib_D.zw +#define read_draw_data_uv_b attrib_E.xy +#define read_draw_data_uv_c attrib_E.zw + +#define read_draw_data_color_a_rg attrib_F.x +#define read_draw_data_color_a_ba attrib_F.y +#define read_draw_data_color_b_rg attrib_F.z +#define read_draw_data_color_b_ba attrib_F.w +#define read_draw_data_color_c_rg attrib_G.x +#define read_draw_data_color_c_ba attrib_G.y + +#else + +#define read_draw_data_modulation attrib_C +#define read_draw_data_ninepatch_margins attrib_D +#define read_draw_data_dst_rect attrib_E +#define read_draw_data_src_rect attrib_F + #endif +#define read_draw_data_flags attrib_G.z +#define read_draw_data_specular_shininess attrib_G.w +#define read_draw_data_lights attrib_H + +// Varyings so the per-instance info can be used in the fragment shader +flat out vec4 varying_A; +flat out vec2 varying_B; +#ifndef USE_PRIMITIVE +flat out vec4 varying_C; +#ifndef USE_ATTRIBUTES +#ifdef USE_NINEPATCH + +flat out vec2 varying_D; +#endif +flat out vec4 varying_E; +#endif #endif +flat out uvec2 varying_F; +flat out uvec4 varying_G; // This needs to be outside clang-format so the ubo comment is in the right place #ifdef MATERIAL_UNIFORMS_USED @@ -39,12 +105,10 @@ layout(std140) uniform MaterialUniforms{ //ubo:4 #endif /* clang-format on */ #include "canvas_uniforms_inc.glsl" -#include "stdlib_inc.glsl" out vec2 uv_interp; out vec4 color_interp; out vec2 vertex_interp; -flat out int draw_data_instance; #ifdef USE_NINEPATCH @@ -55,35 +119,46 @@ out vec2 pixel_size_interp; #GLOBALS void main() { + varying_A = vec4(read_draw_data_world_x, read_draw_data_world_y); + varying_B = read_draw_data_color_texture_pixel_size; +#ifndef USE_PRIMITIVE + varying_C = read_draw_data_ninepatch_margins; + +#ifndef USE_ATTRIBUTES +#ifdef USE_NINEPATCH + varying_D = vec2(read_draw_data_dst_rect.z, read_draw_data_dst_rect.w); +#endif // USE_NINEPATCH + varying_E = read_draw_data_src_rect; +#endif // !USE_ATTRIBUTES +#endif // USE_PRIMITIVE + + varying_F = uvec2(read_draw_data_flags, read_draw_data_specular_shininess); + varying_G = read_draw_data_lights; + vec4 instance_custom = vec4(0.0); #ifdef USE_PRIMITIVE - draw_data_instance = gl_InstanceID; vec2 vertex; vec2 uv; vec4 color; if (gl_VertexID % 3 == 0) { - vertex = draw_data[draw_data_instance].point_a; - uv = draw_data[draw_data_instance].uv_a; - color = vec4(unpackHalf2x16(draw_data[draw_data_instance].color_a_rg), unpackHalf2x16(draw_data[draw_data_instance].color_a_ba)); + vertex = read_draw_data_point_a; + uv = read_draw_data_uv_a; + color = vec4(unpackHalf2x16(read_draw_data_color_a_rg), unpackHalf2x16(read_draw_data_color_a_ba)); } else if (gl_VertexID % 3 == 1) { - vertex = draw_data[draw_data_instance].point_b; - uv = draw_data[draw_data_instance].uv_b; - color = vec4(unpackHalf2x16(draw_data[draw_data_instance].color_b_rg), unpackHalf2x16(draw_data[draw_data_instance].color_b_ba)); + vertex = read_draw_data_point_b; + uv = read_draw_data_uv_b; + color = vec4(unpackHalf2x16(read_draw_data_color_b_rg), unpackHalf2x16(read_draw_data_color_b_ba)); } else { - vertex = draw_data[draw_data_instance].point_c; - uv = draw_data[draw_data_instance].uv_c; - color = vec4(unpackHalf2x16(draw_data[draw_data_instance].color_c_rg), unpackHalf2x16(draw_data[draw_data_instance].color_c_ba)); + vertex = read_draw_data_point_c; + uv = read_draw_data_uv_c; + color = vec4(unpackHalf2x16(read_draw_data_color_c_rg), unpackHalf2x16(read_draw_data_color_c_ba)); } #elif defined(USE_ATTRIBUTES) - draw_data_instance = gl_InstanceID; -#ifdef USE_INSTANCING - draw_data_instance = 0; -#endif vec2 vertex = vertex_attrib; - vec4 color = color_attrib * draw_data[draw_data_instance].modulation; + vec4 color = color_attrib * read_draw_data_modulation; vec2 uv = uv_attrib; #ifdef USE_INSTANCING @@ -93,30 +168,29 @@ void main() { #endif #else - draw_data_instance = gl_VertexID / 6; vec2 vertex_base_arr[6] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0), vec2(0.0, 0.0), vec2(1.0, 1.0)); vec2 vertex_base = vertex_base_arr[gl_VertexID % 6]; - vec2 uv = draw_data[draw_data_instance].src_rect.xy + abs(draw_data[draw_data_instance].src_rect.zw) * ((draw_data[draw_data_instance].flags & FLAGS_TRANSPOSE_RECT) != uint(0) ? vertex_base.yx : vertex_base.xy); - vec4 color = draw_data[draw_data_instance].modulation; - vec2 vertex = draw_data[draw_data_instance].dst_rect.xy + abs(draw_data[draw_data_instance].dst_rect.zw) * mix(vertex_base, vec2(1.0, 1.0) - vertex_base, lessThan(draw_data[draw_data_instance].src_rect.zw, vec2(0.0, 0.0))); + vec2 uv = read_draw_data_src_rect.xy + abs(read_draw_data_src_rect.zw) * ((read_draw_data_flags & FLAGS_TRANSPOSE_RECT) != uint(0) ? vertex_base.yx : vertex_base.xy); + vec4 color = read_draw_data_modulation; + vec2 vertex = read_draw_data_dst_rect.xy + abs(read_draw_data_dst_rect.zw) * mix(vertex_base, vec2(1.0, 1.0) - vertex_base, lessThan(read_draw_data_src_rect.zw, vec2(0.0, 0.0))); #endif - mat4 model_matrix = mat4(vec4(draw_data[draw_data_instance].world_x, 0.0, 0.0), vec4(draw_data[draw_data_instance].world_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(draw_data[draw_data_instance].world_ofs, 0.0, 1.0)); + mat4 model_matrix = mat4(vec4(read_draw_data_world_x, 0.0, 0.0), vec4(read_draw_data_world_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(read_draw_data_world_ofs, 0.0, 1.0)); #ifdef USE_INSTANCING model_matrix = model_matrix * transpose(mat4(instance_xform0, instance_xform1, vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))); #endif // USE_INSTANCING #if !defined(USE_ATTRIBUTES) && !defined(USE_PRIMITIVE) - if (bool(draw_data[draw_data_instance].flags & FLAGS_USING_PARTICLES)) { + if (bool(read_draw_data_flags & FLAGS_USING_PARTICLES)) { //scale by texture size - vertex /= draw_data[draw_data_instance].color_texture_pixel_size; + vertex /= read_draw_data_color_texture_pixel_size; } #endif - vec2 color_texture_pixel_size = draw_data[draw_data_instance].color_texture_pixel_size.xy; + vec2 color_texture_pixel_size = read_draw_data_color_texture_pixel_size; #ifdef USE_POINT_SIZE float point_size = 1.0; @@ -126,7 +200,7 @@ void main() { } #ifdef USE_NINEPATCH - pixel_size_interp = abs(draw_data[draw_data_instance].dst_rect.zw) * vertex_base; + pixel_size_interp = abs(read_draw_data_dst_rect.zw) * vertex_base; #endif #if !defined(SKIP_TRANSFORM_USED) @@ -159,6 +233,46 @@ void main() { #include "canvas_uniforms_inc.glsl" #include "stdlib_inc.glsl" +in vec2 uv_interp; +in vec2 vertex_interp; +in vec4 color_interp; + +#ifdef USE_NINEPATCH + +in vec2 pixel_size_interp; + +#endif + +// Can all be flat as they are the same for the whole batched instance +flat in vec4 varying_A; +flat in vec2 varying_B; +#define read_draw_data_world_x varying_A.xy +#define read_draw_data_world_y varying_A.zw +#define read_draw_data_color_texture_pixel_size varying_B + +#ifndef USE_PRIMITIVE +flat in vec4 varying_C; +#define read_draw_data_ninepatch_margins varying_C + +#ifndef USE_ATTRIBUTES +#ifdef USE_NINEPATCH + +flat in vec2 varying_D; +#define read_draw_data_dst_rect_z varying_D.x +#define read_draw_data_dst_rect_w varying_D.y +#endif + +flat in vec4 varying_E; +#define read_draw_data_src_rect varying_E +#endif // USE_ATTRIBUTES +#endif // USE_PRIMITIVE + +flat in uvec2 varying_F; +flat in uvec4 varying_G; +#define read_draw_data_flags varying_F.x +#define read_draw_data_specular_shininess varying_F.y +#define read_draw_data_lights varying_G + #ifndef DISABLE_LIGHTING uniform sampler2D atlas_texture; //texunit:-2 uniform sampler2D shadow_atlas_texture; //texunit:-3 @@ -170,17 +284,6 @@ uniform sampler2D specular_texture; //texunit:-7 uniform sampler2D color_texture; //texunit:0 -in vec2 uv_interp; -in vec4 color_interp; -in vec2 vertex_interp; -flat in int draw_data_instance; - -#ifdef USE_NINEPATCH - -in vec2 pixel_size_interp; - -#endif - layout(location = 0) out vec4 frag_color; #ifdef MATERIAL_UNIFORMS_USED @@ -366,7 +469,7 @@ float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, flo } else if (pixel >= draw_size - margin_end) { return (tex_size - (draw_size - pixel)) * tex_pixel_size; } else { - if (!bool(draw_data[draw_data_instance].flags & FLAGS_NINEPACH_DRAW_CENTER)) { + if (!bool(read_draw_data_flags & FLAGS_NINEPACH_DRAW_CENTER)) { draw_center--; } @@ -414,28 +517,26 @@ void main() { int draw_center = 2; uv = vec2( - map_ninepatch_axis(pixel_size_interp.x, abs(draw_data[draw_data_instance].dst_rect.z), draw_data[draw_data_instance].color_texture_pixel_size.x, draw_data[draw_data_instance].ninepatch_margins.x, draw_data[draw_data_instance].ninepatch_margins.z, int(draw_data[draw_data_instance].flags >> FLAGS_NINEPATCH_H_MODE_SHIFT) & 0x3, draw_center), - map_ninepatch_axis(pixel_size_interp.y, abs(draw_data[draw_data_instance].dst_rect.w), draw_data[draw_data_instance].color_texture_pixel_size.y, draw_data[draw_data_instance].ninepatch_margins.y, draw_data[draw_data_instance].ninepatch_margins.w, int(draw_data[draw_data_instance].flags >> FLAGS_NINEPATCH_V_MODE_SHIFT) & 0x3, draw_center)); + map_ninepatch_axis(pixel_size_interp.x, abs(read_draw_data_dst_rect_z), read_draw_data_color_texture_pixel_size.x, read_draw_data_ninepatch_margins.x, read_draw_data_ninepatch_margins.z, int(read_draw_data_flags >> FLAGS_NINEPATCH_H_MODE_SHIFT) & 0x3, draw_center), + map_ninepatch_axis(pixel_size_interp.y, abs(read_draw_data_dst_rect_w), read_draw_data_color_texture_pixel_size.y, read_draw_data_ninepatch_margins.y, read_draw_data_ninepatch_margins.w, int(read_draw_data_flags >> FLAGS_NINEPATCH_V_MODE_SHIFT) & 0x3, draw_center)); if (draw_center == 0) { color.a = 0.0; } - uv = uv * draw_data[draw_data_instance].src_rect.zw + draw_data[draw_data_instance].src_rect.xy; //apply region if needed + uv = uv * read_draw_data_src_rect.zw + read_draw_data_src_rect.xy; //apply region if needed #endif - if (bool(draw_data[draw_data_instance].flags & FLAGS_CLIP_RECT_UV)) { - uv = clamp(uv, draw_data[draw_data_instance].src_rect.xy, draw_data[draw_data_instance].src_rect.xy + abs(draw_data[draw_data_instance].src_rect.zw)); + if (bool(read_draw_data_flags & FLAGS_CLIP_RECT_UV)) { + uv = clamp(uv, read_draw_data_src_rect.xy, read_draw_data_src_rect.xy + abs(read_draw_data_src_rect.zw)); } #endif #ifndef USE_PRIMITIVE - if (bool(draw_data[draw_data_instance].flags & FLAGS_USE_MSDF)) { - float px_range = draw_data[draw_data_instance].ninepatch_margins.x; - float outline_thickness = draw_data[draw_data_instance].ninepatch_margins.y; - //float reserved1 = draw_data[draw_data_instance].ninepatch_margins.z; - //float reserved2 = draw_data[draw_data_instance].ninepatch_margins.w; + if (bool(read_draw_data_flags & FLAGS_USE_MSDF)) { + float px_range = read_draw_data_ninepatch_margins.x; + float outline_thickness = read_draw_data_ninepatch_margins.y; vec4 msdf_sample = texture(color_texture, uv); vec2 msdf_size = vec2(textureSize(color_texture, 0)); @@ -451,7 +552,7 @@ void main() { float a = clamp(d * px_size + 0.5, 0.0, 1.0); color.a = a * color.a; } - } else if (bool(draw_data[draw_data_instance].flags & FLAGS_USE_LCD)) { + } else if (bool(read_draw_data_flags & FLAGS_USE_LCD)) { vec4 lcd_sample = texture(color_texture, uv); if (lcd_sample.a == 1.0) { color.rgb = lcd_sample.rgb * color.a; @@ -465,7 +566,7 @@ void main() { color *= texture(color_texture, uv); } - uint light_count = (draw_data[draw_data_instance].flags >> uint(FLAGS_LIGHT_COUNT_SHIFT)) & uint(0xF); //max 16 lights + uint light_count = (read_draw_data_flags >> uint(FLAGS_LIGHT_COUNT_SHIFT)) & uint(0xF); //max 16 lights bool using_light = light_count > 0u || directional_light_count > 0u; vec3 normal; @@ -476,7 +577,7 @@ void main() { bool normal_used = false; #endif - if (normal_used || (using_light && bool(draw_data[draw_data_instance].flags & FLAGS_DEFAULT_NORMAL_MAP_USED))) { + if (normal_used || (using_light && bool(read_draw_data_flags & FLAGS_DEFAULT_NORMAL_MAP_USED))) { normal.xy = texture(normal_texture, uv).xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); normal.z = sqrt(1.0 - dot(normal.xy, normal.xy)); normal_used = true; @@ -493,9 +594,9 @@ void main() { bool specular_shininess_used = false; #endif - if (specular_shininess_used || (using_light && normal_used && bool(draw_data[draw_data_instance].flags & FLAGS_DEFAULT_SPECULAR_MAP_USED))) { + if (specular_shininess_used || (using_light && normal_used && bool(read_draw_data_flags & FLAGS_DEFAULT_SPECULAR_MAP_USED))) { specular_shininess = texture(specular_texture, uv); - specular_shininess *= godot_unpackUnorm4x8(draw_data[draw_data_instance].specular_shininess); + specular_shininess *= godot_unpackUnorm4x8(read_draw_data_specular_shininess); specular_shininess_used = true; } else { specular_shininess = vec4(1.0); @@ -507,7 +608,7 @@ void main() { vec2 screen_uv = vec2(0.0); #endif - vec2 color_texture_pixel_size = draw_data[draw_data_instance].color_texture_pixel_size.xy; + vec2 color_texture_pixel_size = read_draw_data_color_texture_pixel_size.xy; vec3 light_vertex = vec3(vertex, 0.0); vec2 shadow_vertex = vertex; @@ -529,7 +630,7 @@ void main() { if (normal_used) { //convert by item transform - normal.xy = mat2(normalize(draw_data[draw_data_instance].world_x), normalize(draw_data[draw_data_instance].world_y)) * normal.xy; + normal.xy = mat2(normalize(read_draw_data_world_x), normalize(read_draw_data_world_y)) * normal.xy; //convert by canvas transform normal = normalize((canvas_normal_transform * vec4(normal, 0.0)).xyz); } @@ -591,15 +692,15 @@ void main() { uint light_base; if (i < 8u) { if (i < 4u) { - light_base = draw_data[draw_data_instance].lights[0]; + light_base = read_draw_data_lights[0]; } else { - light_base = draw_data[draw_data_instance].lights[1]; + light_base = read_draw_data_lights[1]; } } else { if (i < 12u) { - light_base = draw_data[draw_data_instance].lights[2]; + light_base = read_draw_data_lights[2]; } else { - light_base = draw_data[draw_data_instance].lights[3]; + light_base = read_draw_data_lights[3]; } } light_base >>= (i & 3u) * 8u; diff --git a/drivers/gles3/shaders/canvas_uniforms_inc.glsl b/drivers/gles3/shaders/canvas_uniforms_inc.glsl index dd5ebecb1a..f65558f042 100644 --- a/drivers/gles3/shaders/canvas_uniforms_inc.glsl +++ b/drivers/gles3/shaders/canvas_uniforms_inc.glsl @@ -27,38 +27,6 @@ #define FLAGS_USE_MSDF uint(1 << 28) #define FLAGS_USE_LCD uint(1 << 29) -// must be always 128 bytes long -struct DrawData { - vec2 world_x; - vec2 world_y; - vec2 world_ofs; - vec2 color_texture_pixel_size; -#ifdef USE_PRIMITIVE - vec2 point_a; - vec2 point_b; - vec2 point_c; - vec2 uv_a; - vec2 uv_b; - vec2 uv_c; - uint color_a_rg; - uint color_a_ba; - uint color_b_rg; - uint color_b_ba; - uint color_c_rg; - uint color_c_ba; -#else - vec4 modulation; - vec4 ninepatch_margins; - vec4 dst_rect; //for built-in rect and UV - vec4 src_rect; - uint pad; - uint pad2; -#endif - uint flags; - uint specular_shininess; - uvec4 lights; -}; - layout(std140) uniform GlobalShaderUniformData { //ubo:1 vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; }; @@ -116,7 +84,3 @@ layout(std140) uniform LightData { //ubo:2 Light light_array[MAX_LIGHTS]; }; #endif // DISABLE_LIGHTING -layout(std140) uniform DrawDataInstances { //ubo:3 - - DrawData draw_data[MAX_DRAW_DATA_INSTANCES]; -}; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index fa68f0063f..1b922fa726 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -503,8 +503,7 @@ multiview_data; /* clang-format on */ -//directional light data - +// Directional light data. #ifndef DISABLE_LIGHT_DIRECTIONAL struct DirectionalLightData { @@ -520,11 +519,12 @@ layout(std140) uniform DirectionalLights { // ubo:7 DirectionalLightData directional_lights[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; }; -#endif +#endif // !DISABLE_LIGHT_DIRECTIONAL + +// Omni and spot light data. +#if !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) -// omni and spot -#if !defined(DISABLE_LIGHT_OMNI) && !defined(DISABLE_LIGHT_SPOT) -struct LightData { //this structure needs to be as packed as possible +struct LightData { // This structure needs to be as packed as possible. highp vec3 position; highp float inv_radius; @@ -539,9 +539,9 @@ struct LightData { //this structure needs to be as packed as possible mediump float specular_amount; mediump float shadow_opacity; }; + #ifndef DISABLE_LIGHT_OMNI layout(std140) uniform OmniLightData { // ubo:5 - LightData omni_lights[MAX_LIGHT_DATA_STRUCTS]; }; uniform uint omni_light_indices[MAX_FORWARD_LIGHTS]; @@ -549,9 +549,7 @@ uniform uint omni_light_count; #endif #ifndef DISABLE_LIGHT_SPOT - layout(std140) uniform SpotLightData { // ubo:6 - LightData spot_lights[MAX_LIGHT_DATA_STRUCTS]; }; uniform uint spot_light_indices[MAX_FORWARD_LIGHTS]; @@ -562,7 +560,7 @@ uniform uint spot_light_count; uniform highp samplerCubeShadow positional_shadow; // texunit:-4 #endif -#endif // !defined(DISABLE_LIGHT_OMNI) && !defined(DISABLE_LIGHT_SPOT) +#endif // !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) #ifdef USE_MULTIVIEW uniform highp sampler2DArray depth_buffer; // texunit:-6 @@ -585,6 +583,7 @@ vec3 F0(float metallic, float specular, vec3 albedo) { } #if !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) + float D_GGX(float cos_theta_m, float alpha) { float a = cos_theta_m * alpha; float k = alpha / (1.0 - cos_theta_m * cos_theta_m + a * a); @@ -641,7 +640,6 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte /* clang-format off */ - #CODE : LIGHT /* clang-format on */ @@ -672,11 +670,8 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte // https://web.archive.org/web/20210228210901/http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/ diffuse_brdf_NL = max(0.0, (NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))) * (1.0 / M_PI); #elif defined(DIFFUSE_TOON) - diffuse_brdf_NL = smoothstep(-roughness, max(roughness, 0.01), NdotL) * (1.0 / M_PI); - #elif defined(DIFFUSE_BURLEY) - { float FD90_minus_1 = 2.0 * cLdotH * cLdotH * roughness - 0.5; float FdV = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotV); @@ -684,7 +679,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL; } #else - // lambert + // Lambert diffuse_brdf_NL = cNdotL * (1.0 / M_PI); #endif @@ -720,7 +715,6 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte // shlick+ggx as default float alpha_ggx = roughness * roughness; #if defined(LIGHT_ANISOTROPY_USED) - float aspect = sqrt(1.0 - anisotropy * 0.9); float ax = alpha_ggx / aspect; float ay = alpha_ggx * aspect; @@ -728,7 +722,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte float YdotH = dot(B, H); float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH); float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL); -#else // LIGHT_ANISOTROPY_USED +#else float D = D_GGX(cNdotH, alpha_ggx); float G = V_GGX(cNdotL, cNdotV, alpha_ggx); #endif // LIGHT_ANISOTROPY_USED @@ -768,10 +762,10 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte alpha = min(alpha, clamp(1.0 - attenuation, 0.0, 1.0)); #endif -#endif //defined(LIGHT_CODE_USED) +#endif // LIGHT_CODE_USED } -float get_omni_attenuation(float distance, float inv_range, float decay) { +float get_omni_spot_attenuation(float distance, float inv_range, float decay) { float nd = distance * inv_range; nd *= nd; nd *= nd; // nd^4 @@ -779,6 +773,7 @@ float get_omni_attenuation(float distance, float inv_range, float decay) { nd *= nd; // nd^2 return nd * pow(max(distance, 0.0001), -decay); } + #ifndef DISABLE_LIGHT_OMNI void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, #ifdef LIGHT_BACKLIGHT_USED @@ -796,7 +791,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f inout vec3 diffuse_light, inout vec3 specular_light) { vec3 light_rel_vec = omni_lights[idx].position - vertex; float light_length = length(light_rel_vec); - float omni_attenuation = get_omni_attenuation(light_length, omni_lights[idx].inv_radius, omni_lights[idx].attenuation); + float omni_attenuation = get_omni_spot_attenuation(light_length, omni_lights[idx].inv_radius, omni_lights[idx].attenuation); vec3 color = omni_lights[idx].color; float size_A = 0.0; @@ -842,7 +837,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f vec3 light_rel_vec = spot_lights[idx].position - vertex; float light_length = length(light_rel_vec); - float spot_attenuation = get_omni_attenuation(light_length, spot_lights[idx].inv_radius, spot_lights[idx].attenuation); + float spot_attenuation = get_omni_spot_attenuation(light_length, spot_lights[idx].inv_radius, spot_lights[idx].attenuation); vec3 spot_dir = spot_lights[idx].direction; float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights[idx].cone_angle); float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights[idx].cone_angle)); @@ -872,7 +867,8 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f diffuse_light, specular_light); } #endif // !DISABLE_LIGHT_SPOT -#endif // !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) && !defined(DISABLE_LIGHT_SPOT) + +#endif // !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) #ifndef MODE_RENDER_DEPTH vec4 fog_process(vec3 vertex) { @@ -1070,15 +1066,11 @@ void main() { fog = fog_process(vertex); } #endif // !DISABLE_FOG -#endif //!CUSTOM_FOG_USED +#endif // !CUSTOM_FOG_USED uint fog_rg = packHalf2x16(fog.rg); uint fog_ba = packHalf2x16(fog.ba); -#endif //!MODE_RENDER_DEPTH - -#ifndef MODE_RENDER_DEPTH - // Convert colors to linear albedo = srgb_to_linear(albedo); emission = srgb_to_linear(emission); @@ -1199,7 +1191,7 @@ void main() { diffuse_light, specular_light); } -#endif //!DISABLE_LIGHT_DIRECTIONAL +#endif // !DISABLE_LIGHT_DIRECTIONAL #ifndef DISABLE_LIGHT_OMNI for (uint i = 0u; i < MAX_FORWARD_LIGHTS; i++) { @@ -1246,9 +1238,10 @@ void main() { #endif diffuse_light, specular_light); } - #endif // !DISABLE_LIGHT_SPOT + #endif // !MODE_UNSHADED + #endif // !MODE_RENDER_DEPTH #if defined(USE_SHADOW_TO_OPACITY) diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp index 9b496c0999..46dc2b806e 100644 --- a/drivers/gles3/storage/config.cpp +++ b/drivers/gles3/storage/config.cpp @@ -90,8 +90,6 @@ Config::Config() { glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_uniform_buffer_size); glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_viewport_size); - glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_offset_alignment); - support_anisotropic_filter = extensions.has("GL_EXT_texture_filter_anisotropic"); if (support_anisotropic_filter) { glGetFloatv(_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &anisotropic_level); diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h index 87202fde84..1a93b4b8ef 100644 --- a/drivers/gles3/storage/config.h +++ b/drivers/gles3/storage/config.h @@ -67,8 +67,6 @@ public: int max_renderable_lights = 0; int max_lights_per_object = 0; - int uniform_buffer_offset_alignment = 0; - // TODO implement wireframe in OpenGL // bool generate_wireframes; diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index 19e841f466..e7eeacf576 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -923,6 +923,104 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, } /////////////////////////////////////////////////////////////////////////// +// ShaderData + +void ShaderData::set_path_hint(const String &p_hint) { + path = p_hint; +} + +void ShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { + if (!p_texture.is_valid()) { + if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { + default_texture_params[p_name].erase(p_index); + + if (default_texture_params[p_name].is_empty()) { + default_texture_params.erase(p_name); + } + } + } else { + if (!default_texture_params.has(p_name)) { + default_texture_params[p_name] = HashMap<int, RID>(); + } + default_texture_params[p_name][p_index] = p_texture; + } +} + +Variant ShaderData::get_default_parameter(const StringName &p_parameter) const { + if (uniforms.has(p_parameter)) { + ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; + Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; + return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); + } + return Variant(); +} + +void ShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { + SortArray<Pair<StringName, int>, ShaderLanguage::UniformOrderComparator> sorter; + LocalVector<Pair<StringName, int>> filtered_uniforms; + + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { + continue; + } + if (E.value.texture_order >= 0) { + filtered_uniforms.push_back(Pair<StringName, int>(E.key, E.value.texture_order + 100000)); + } else { + filtered_uniforms.push_back(Pair<StringName, int>(E.key, E.value.order)); + } + } + int uniform_count = filtered_uniforms.size(); + sorter.sort(filtered_uniforms.ptr(), uniform_count); + + String last_group; + for (int i = 0; i < uniform_count; i++) { + const StringName &uniform_name = filtered_uniforms[i].first; + const ShaderLanguage::ShaderNode::Uniform &uniform = uniforms[uniform_name]; + + String group = uniform.group; + if (!uniform.subgroup.is_empty()) { + group += "::" + uniform.subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniform); + pi.name = uniform_name; + p_param_list->push_back(pi); + } +} + +void ShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + continue; + } + + RendererMaterialStorage::InstanceShaderParam p; + p.info = ShaderLanguage::uniform_to_property_info(E.value); + p.info.name = E.key; //supply name + p.index = E.value.instance_index; + p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); + p_param_list->push_back(p); + } +} + +bool ShaderData::is_parameter_texture(const StringName &p_param) const { + if (!uniforms.has(p_param)) { + return false; + } + + return uniforms[p_param].texture_order >= 0; +} + +/////////////////////////////////////////////////////////////////////////// // MaterialData // Look up table to translate ShaderLanguage::DataType to GL_TEXTURE_* @@ -2806,10 +2904,6 @@ void MaterialStorage::material_update_dependency(RID p_material, DependencyTrack /* Canvas Shader Data */ -void CanvasShaderData::set_path_hint(const String &p_path) { - path = p_path; -} - void CanvasShaderData::set_code(const String &p_code) { // compile the shader @@ -2890,85 +2984,6 @@ void CanvasShaderData::set_code(const String &p_code) { valid = true; } -void CanvasShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { - if (!p_texture.is_valid()) { - if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { - default_texture_params[p_name].erase(p_index); - - if (default_texture_params[p_name].is_empty()) { - default_texture_params.erase(p_name); - } - } - } else { - if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = HashMap<int, RID>(); - } - default_texture_params[p_name][p_index] = p_texture; - } -} - -void CanvasShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { - HashMap<int, StringName> order; - - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { - continue; - } - if (E.value.texture_order >= 0) { - order[E.value.texture_order + 100000] = E.key; - } else { - order[E.value.order] = E.key; - } - } - - String last_group; - for (const KeyValue<int, StringName> &E : order) { - String group = uniforms[E.value].group; - if (!uniforms[E.value].subgroup.is_empty()) { - group += "::" + uniforms[E.value].subgroup; - } - - if (group != last_group) { - PropertyInfo pi; - pi.usage = PROPERTY_USAGE_GROUP; - pi.name = group; - p_param_list->push_back(pi); - - last_group = group; - } - - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); - pi.name = E.value; - p_param_list->push_back(pi); - } -} - -void CanvasShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E.value); - p.info.name = E.key; //supply name - p.index = E.value.instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); - p_param_list->push_back(p); - } -} - -bool CanvasShaderData::is_parameter_texture(const StringName &p_param) const { - if (!uniforms.has(p_param)) { - return false; - } - - return uniforms[p_param].texture_order >= 0; -} - bool CanvasShaderData::is_animated() const { return false; } @@ -2977,15 +2992,6 @@ bool CanvasShaderData::casts_shadows() const { return false; } -Variant CanvasShaderData::get_default_parameter(const StringName &p_parameter) const { - if (uniforms.has(p_parameter)) { - ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); - } - return Variant(); -} - RS::ShaderNativeSourceCode CanvasShaderData::get_native_source_code() const { return MaterialStorage::get_singleton()->shaders.canvas_shader.version_get_native_source_code(version); } @@ -3044,10 +3050,6 @@ GLES3::MaterialData *GLES3::_create_canvas_material_func(ShaderData *p_shader) { //////////////////////////////////////////////////////////////////////////////// // SKY SHADER -void SkyShaderData::set_path_hint(const String &p_path) { - path = p_path; -} - void SkyShaderData::set_code(const String &p_code) { //compile @@ -3138,83 +3140,6 @@ void SkyShaderData::set_code(const String &p_code) { valid = true; } -void SkyShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { - if (!p_texture.is_valid()) { - if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { - default_texture_params[p_name].erase(p_index); - - if (default_texture_params[p_name].is_empty()) { - default_texture_params.erase(p_name); - } - } - } else { - if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = HashMap<int, RID>(); - } - default_texture_params[p_name][p_index] = p_texture; - } -} - -void SkyShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { - RBMap<int, StringName> order; - - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - if (E.value.texture_order >= 0) { - order[E.value.texture_order + 100000] = E.key; - } else { - order[E.value.order] = E.key; - } - } - - String last_group; - for (const KeyValue<int, StringName> &E : order) { - String group = uniforms[E.value].group; - if (!uniforms[E.value].subgroup.is_empty()) { - group += "::" + uniforms[E.value].subgroup; - } - - if (group != last_group) { - PropertyInfo pi; - pi.usage = PROPERTY_USAGE_GROUP; - pi.name = group; - p_param_list->push_back(pi); - - last_group = group; - } - - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); - pi.name = E.value; - p_param_list->push_back(pi); - } -} - -void SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E.value); - p.info.name = E.key; //supply name - p.index = E.value.instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); - p_param_list->push_back(p); - } -} - -bool SkyShaderData::is_parameter_texture(const StringName &p_param) const { - if (!uniforms.has(p_param)) { - return false; - } - - return uniforms[p_param].texture_order >= 0; -} - bool SkyShaderData::is_animated() const { return false; } @@ -3223,15 +3148,6 @@ bool SkyShaderData::casts_shadows() const { return false; } -Variant SkyShaderData::get_default_parameter(const StringName &p_parameter) const { - if (uniforms.has(p_parameter)) { - ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); - } - return Variant(); -} - RS::ShaderNativeSourceCode SkyShaderData::get_native_source_code() const { return MaterialStorage::get_singleton()->shaders.sky_shader.version_get_native_source_code(version); } @@ -3291,10 +3207,6 @@ void SkyMaterialData::bind_uniforms() { //////////////////////////////////////////////////////////////////////////////// // Scene SHADER -void SceneShaderData::set_path_hint(const String &p_path) { - path = p_path; -} - void SceneShaderData::set_code(const String &p_code) { //compile @@ -3471,86 +3383,6 @@ void SceneShaderData::set_code(const String &p_code) { valid = true; } -void SceneShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { - if (!p_texture.is_valid()) { - if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { - default_texture_params[p_name].erase(p_index); - - if (default_texture_params[p_name].is_empty()) { - default_texture_params.erase(p_name); - } - } - } else { - if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = HashMap<int, RID>(); - } - default_texture_params[p_name][p_index] = p_texture; - } -} - -void SceneShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { - RBMap<int, StringName> order; - - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { - continue; - } - - if (E.value.texture_order >= 0) { - order[E.value.texture_order + 100000] = E.key; - } else { - order[E.value.order] = E.key; - } - } - - String last_group; - for (const KeyValue<int, StringName> &E : order) { - String group = uniforms[E.value].group; - if (!uniforms[E.value].subgroup.is_empty()) { - group += "::" + uniforms[E.value].subgroup; - } - - if (group != last_group) { - PropertyInfo pi; - pi.usage = PROPERTY_USAGE_GROUP; - pi.name = group; - p_param_list->push_back(pi); - - last_group = group; - } - - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); - pi.name = E.value; - p_param_list->push_back(pi); - } -} - -void SceneShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E.value); - p.info.name = E.key; //supply name - p.index = E.value.instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); - p_param_list->push_back(p); - } -} - -bool SceneShaderData::is_parameter_texture(const StringName &p_param) const { - if (!uniforms.has(p_param)) { - return false; - } - - return uniforms[p_param].texture_order >= 0; -} - bool SceneShaderData::is_animated() const { return (uses_fragment_time && uses_discard) || (uses_vertex_time && uses_vertex); } @@ -3563,15 +3395,6 @@ bool SceneShaderData::casts_shadows() const { return !has_alpha || (uses_depth_pre_pass && !(depth_draw == DEPTH_DRAW_DISABLED || depth_test == DEPTH_TEST_DISABLED)); } -Variant SceneShaderData::get_default_parameter(const StringName &p_parameter) const { - if (uniforms.has(p_parameter)) { - ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); - } - return Variant(); -} - RS::ShaderNativeSourceCode SceneShaderData::get_native_source_code() const { return MaterialStorage::get_singleton()->shaders.scene_shader.version_get_native_source_code(version); } @@ -3636,10 +3459,6 @@ void SceneMaterialData::bind_uniforms() { /* Particles SHADER */ -void ParticlesShaderData::set_path_hint(const String &p_path) { - path = p_path; -} - void ParticlesShaderData::set_code(const String &p_code) { //compile @@ -3696,83 +3515,6 @@ void ParticlesShaderData::set_code(const String &p_code) { valid = true; } -void ParticlesShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { - if (!p_texture.is_valid()) { - if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { - default_texture_params[p_name].erase(p_index); - - if (default_texture_params[p_name].is_empty()) { - default_texture_params.erase(p_name); - } - } - } else { - if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = HashMap<int, RID>(); - } - default_texture_params[p_name][p_index] = p_texture; - } -} - -void ParticlesShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { - HashMap<int, StringName> order; - - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - if (E.value.texture_order >= 0) { - order[E.value.texture_order + 100000] = E.key; - } else { - order[E.value.order] = E.key; - } - } - - String last_group; - for (const KeyValue<int, StringName> &E : order) { - String group = uniforms[E.value].group; - if (!uniforms[E.value].subgroup.is_empty()) { - group += "::" + uniforms[E.value].subgroup; - } - - if (group != last_group) { - PropertyInfo pi; - pi.usage = PROPERTY_USAGE_GROUP; - pi.name = group; - p_param_list->push_back(pi); - - last_group = group; - } - - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); - pi.name = E.value; - p_param_list->push_back(pi); - } -} - -void ParticlesShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E.value); - p.info.name = E.key; //supply name - p.index = E.value.instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); - p_param_list->push_back(p); - } -} - -bool ParticlesShaderData::is_parameter_texture(const StringName &p_param) const { - if (!uniforms.has(p_param)) { - return false; - } - - return uniforms[p_param].texture_order >= 0; -} - bool ParticlesShaderData::is_animated() const { return false; } @@ -3781,15 +3523,6 @@ bool ParticlesShaderData::casts_shadows() const { return false; } -Variant ParticlesShaderData::get_default_parameter(const StringName &p_parameter) const { - if (uniforms.has(p_parameter)) { - ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); - } - return Variant(); -} - RS::ShaderNativeSourceCode ParticlesShaderData::get_native_source_code() const { return MaterialStorage::get_singleton()->shaders.particles_process_shader.version_get_native_source_code(version); } @@ -3827,7 +3560,7 @@ void ParticleProcessMaterialData::bind_uniforms() { ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw(); for (int ti = 0; ti < texture_cache.size(); ti++) { Texture *texture = TextureStorage::get_singleton()->get_texture(textures[ti]); - glActiveTexture(GL_TEXTURE1 + ti); // Start at GL_TEXTURE1 becuase texture slot 0 is reserved for the heightmap texture. + glActiveTexture(GL_TEXTURE1 + ti); // Start at GL_TEXTURE1 because texture slot 0 is reserved for the heightmap texture. glBindTexture(target_from_type[texture_uniforms[ti].type], texture->tex_id); // Set sampler state here as the same texture can be used in multiple places with different flags diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h index 8ae5e5eb9c..9965d23070 100644 --- a/drivers/gles3/storage/material_storage.h +++ b/drivers/gles3/storage/material_storage.h @@ -53,16 +53,20 @@ namespace GLES3 { /* Shader Structs */ struct ShaderData { - virtual void set_code(const String &p_Code) = 0; - virtual void set_path_hint(const String &p_hint) = 0; - virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) = 0; - virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const = 0; + String path; + HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; + HashMap<StringName, HashMap<int, RID>> default_texture_params; - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const = 0; - virtual bool is_parameter_texture(const StringName &p_param) const = 0; + virtual void set_path_hint(const String &p_hint); + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); + virtual Variant get_default_parameter(const StringName &p_parameter) const; + virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; + virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; + virtual bool is_parameter_texture(const StringName &p_param) const; + + virtual void set_code(const String &p_Code) = 0; virtual bool is_animated() const = 0; virtual bool casts_shadows() const = 0; - virtual Variant get_default_parameter(const StringName &p_parameter) const = 0; virtual RS::ShaderNativeSourceCode get_native_source_code() const { return RS::ShaderNativeSourceCode(); } virtual ~ShaderData() {} @@ -149,17 +153,14 @@ struct CanvasShaderData : public ShaderData { bool valid; RID version; - String path; BlendMode blend_mode = BLEND_MODE_MIX; - HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size; String code; - HashMap<StringName, HashMap<int, RID>> default_texture_params; bool uses_screen_texture = false; bool uses_screen_texture_mipmaps = false; @@ -167,15 +168,8 @@ struct CanvasShaderData : public ShaderData { bool uses_time = false; virtual void set_code(const String &p_Code); - virtual void set_path_hint(const String &p_hint); - virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); - virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - - virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; - virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; CanvasShaderData(); @@ -202,15 +196,12 @@ struct SkyShaderData : public ShaderData { bool valid; RID version; - HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size; - String path; String code; - HashMap<StringName, HashMap<int, RID>> default_texture_params; bool uses_time; bool uses_position; @@ -219,14 +210,8 @@ struct SkyShaderData : public ShaderData { bool uses_light; virtual void set_code(const String &p_Code); - virtual void set_path_hint(const String &p_hint); - virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); - virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; - virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; SkyShaderData(); virtual ~SkyShaderData(); @@ -284,16 +269,12 @@ struct SceneShaderData : public ShaderData { bool valid; RID version; - String path; - - HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size; String code; - HashMap<StringName, HashMap<int, RID>> default_texture_params; BlendMode blend_mode; AlphaAntiAliasing alpha_antialiasing_mode; @@ -343,15 +324,8 @@ struct SceneShaderData : public ShaderData { uint32_t index = 0; virtual void set_code(const String &p_Code); - virtual void set_path_hint(const String &p_hint); - virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); - virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - - virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; - virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; SceneShaderData(); @@ -386,15 +360,12 @@ struct ParticlesShaderData : public ShaderData { RID version; bool uses_collision = false; - HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size = 0; - String path; String code; - HashMap<StringName, HashMap<int, RID>> default_texture_params; bool uses_time = false; @@ -402,14 +373,8 @@ struct ParticlesShaderData : public ShaderData { uint32_t userdata_count = 0; virtual void set_code(const String &p_Code); - virtual void set_path_hint(const String &p_hint); - virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); - virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; - virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; ParticlesShaderData() {} diff --git a/drivers/gles3/storage/utilities.cpp b/drivers/gles3/storage/utilities.cpp index fe900c7cfb..02a110e3e5 100644 --- a/drivers/gles3/storage/utilities.cpp +++ b/drivers/gles3/storage/utilities.cpp @@ -156,6 +156,9 @@ bool Utilities::free(RID p_rid) { } else if (GLES3::ParticlesStorage::get_singleton()->owns_particles_collision_instance(p_rid)) { GLES3::ParticlesStorage::get_singleton()->particles_collision_instance_free(p_rid); return true; + } else if (GLES3::MeshStorage::get_singleton()->owns_skeleton(p_rid)) { + GLES3::MeshStorage::get_singleton()->skeleton_free(p_rid); + return true; } else { return false; } diff --git a/drivers/register_driver_types.cpp b/drivers/register_driver_types.cpp index 53a7f7aa4f..8362abefc9 100644 --- a/drivers/register_driver_types.cpp +++ b/drivers/register_driver_types.cpp @@ -30,7 +30,7 @@ #include "register_driver_types.h" -#include "core/extension/native_extension_manager.h" +#include "core/extension/gdextension_manager.h" #include "drivers/png/image_loader_png.h" #include "drivers/png/resource_saver_png.h" diff --git a/drivers/spirv-reflect/SCsub b/drivers/spirv-reflect/SCsub deleted file mode 100644 index 1e7b3de0e6..0000000000 --- a/drivers/spirv-reflect/SCsub +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python - -Import("env") - -# Thirdparty source files - -thirdparty_dir = "#thirdparty/spirv-reflect/" -thirdparty_sources = [ - "spirv_reflect.c", -] - -thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - -env_thirdparty = env.Clone() -env_thirdparty.disable_warnings() - -env_thirdparty.add_source_files(env.drivers_sources, thirdparty_sources) diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 7f5bac30f1..f9348311a4 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -40,7 +40,6 @@ #include "drivers/vulkan/vulkan_context.h" #include "thirdparty/misc/smolv.h" -#include "thirdparty/spirv-reflect/spirv_reflect.h" //#define FORCE_FULL_BARRIER @@ -1579,12 +1578,12 @@ Error RenderingDeviceVulkan::_buffer_update(Buffer *p_buffer, size_t p_offset, c return OK; } -void RenderingDeviceVulkan::_memory_barrier(VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_sccess, bool p_sync_with_draw) { +void RenderingDeviceVulkan::_memory_barrier(VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_access, bool p_sync_with_draw) { VkMemoryBarrier mem_barrier; mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; mem_barrier.pNext = nullptr; mem_barrier.srcAccessMask = p_src_access; - mem_barrier.dstAccessMask = p_dst_sccess; + mem_barrier.dstAccessMask = p_dst_access; if (p_src_stage_mask == 0 || p_dst_stage_mask == 0) { return; // No barrier, since this is invalid. @@ -1628,14 +1627,14 @@ void RenderingDeviceVulkan::_full_barrier(bool p_sync_with_draw) { p_sync_with_draw); } -void RenderingDeviceVulkan::_buffer_memory_barrier(VkBuffer buffer, uint64_t p_from, uint64_t p_size, VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_sccess, bool p_sync_with_draw) { +void RenderingDeviceVulkan::_buffer_memory_barrier(VkBuffer buffer, uint64_t p_from, uint64_t p_size, VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_access, bool p_sync_with_draw) { VkBufferMemoryBarrier buffer_mem_barrier; buffer_mem_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; buffer_mem_barrier.pNext = nullptr; buffer_mem_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; buffer_mem_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; buffer_mem_barrier.srcAccessMask = p_src_access; - buffer_mem_barrier.dstAccessMask = p_dst_sccess; + buffer_mem_barrier.dstAccessMask = p_dst_access; buffer_mem_barrier.buffer = buffer; buffer_mem_barrier.offset = p_from; buffer_mem_barrier.size = p_size; @@ -4524,14 +4523,6 @@ RID RenderingDeviceVulkan::index_array_create(RID p_index_buffer, uint32_t p_ind /**** SHADER ****/ /****************/ -static const char *shader_stage_names[RenderingDevice::SHADER_STAGE_MAX] = { - "Vertex", - "Fragment", - "TesselationControl", - "TesselationEvaluation", - "Compute" -}; - static const char *shader_uniform_names[RenderingDevice::UNIFORM_TYPE_MAX] = { "Sampler", "CombinedSampler", "Texture", "Image", "TextureBuffer", "SamplerTextureBuffer", "ImageBuffer", "UniformBuffer", "StorageBuffer", "InputAttachment" }; @@ -4562,198 +4553,6 @@ String RenderingDeviceVulkan::_shader_uniform_debug(RID p_shader, int p_set) { } return ret; } -#if 0 -bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLayoutBinding> > &bindings, Vector<Vector<UniformInfo> > &uniform_infos, const glslang::TObjectReflection &reflection, RenderingDevice::ShaderStage p_stage, Shader::PushConstant &push_constant, String *r_error) { - VkDescriptorSetLayoutBinding layout_binding; - UniformInfo info; - - switch (reflection.getType()->getBasicType()) { - case glslang::EbtSampler: { - //print_line("DEBUG: IsSampler"); - if (reflection.getType()->getSampler().dim == glslang::EsdBuffer) { - // Texture buffers. - if (reflection.getType()->getSampler().isCombined()) { - layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; - info.type = UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER; - //print_line("DEBUG: SAMPLER: texel combined"); - } else if (reflection.getType()->getSampler().isTexture()) { - layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; - info.type = UNIFORM_TYPE_TEXTURE_BUFFER; - //print_line("DEBUG: SAMPLER: texel alone"); - } else if (reflection.getType()->getSampler().isImage()) { - layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; - info.type = UNIFORM_TYPE_IMAGE_BUFFER; - //print_line("DEBUG: SAMPLER: texel buffer"); - } else { - if (r_error) { - *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' is of unsupported buffer type."; - } - return false; - } - } else if (reflection.getType()->getSampler().isCombined()) { - layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - info.type = UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; - //print_line("DEBUG: SAMPLER: combined"); - } else if (reflection.getType()->getSampler().isPureSampler()) { - layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; - info.type = UNIFORM_TYPE_SAMPLER; - //print_line("DEBUG: SAMPLER: sampler"); - } else if (reflection.getType()->getSampler().isTexture()) { - layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - info.type = UNIFORM_TYPE_TEXTURE; - //print_line("DEBUG: SAMPLER: image"); - } else if (reflection.getType()->getSampler().isImage()) { - layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - info.type = UNIFORM_TYPE_IMAGE; - //print_line("DEBUG: SAMPLER: storage image"); - } else { - //print_line("DEBUG: sampler unknown"); - if (r_error) { - *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' is of unsupported sampler type."; - } - return false; - } - - if (reflection.getType()->isArray()) { - layout_binding.descriptorCount = reflection.getType()->getArraySizes()->getCumulativeSize(); - //print_line("DEBUG: array of size: " + itos(layout_binding.descriptorCount)); - } else { - layout_binding.descriptorCount = 1; - } - - info.length = layout_binding.descriptorCount; - - } break; - /*case glslang::EbtStruct: { - print_line("DEBUG: Struct"); - - } break;*/ - case glslang::EbtBlock: { - //print_line("DEBUG: Block"); - if (reflection.getType()->getQualifier().storage == glslang::EvqUniform) { - if (reflection.getType()->getQualifier().layoutPushConstant) { - uint32_t len = reflection.size; - if (push_constant.push_constant_size != 0 && push_constant.push_constant_size != len) { - *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' push constants for different stages should all be the same size."; - return false; - } - push_constant.push_constant_size = len; - push_constant.push_constants_vk_stage |= shader_stage_masks[p_stage]; - return true; - } - //print_line("DEBUG: Uniform buffer"); - layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - info.type = UNIFORM_TYPE_UNIFORM_BUFFER; - } else if (reflection.getType()->getQualifier().storage == glslang::EvqBuffer) { - layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - info.type = UNIFORM_TYPE_STORAGE_BUFFER; - //print_line("DEBUG: Storage buffer"); - } else { - if (r_error) { - *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' is of unsupported block type: (" + itos(reflection.getType()->getQualifier().storage) + ")."; - } - return false; - } - - if (reflection.getType()->isArray()) { - layout_binding.descriptorCount = reflection.getType()->getArraySizes()->getCumulativeSize(); - //print_line("DEBUG: array of size: " + itos(layout_binding.descriptorCount)); - } else { - layout_binding.descriptorCount = 1; - } - - info.length = reflection.size; - - } break; - /*case glslang::EbtReference: { - } break;*/ - /*case glslang::EbtAtomicUint: { - } break;*/ - default: { - if (reflection.getType()->getQualifier().hasOffset() || reflection.name.find(".") != std::string::npos) { - // Member of uniform block? - return true; - } - - if (r_error) { - *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' unsupported uniform type."; - } - return false; - } - } - - if (!reflection.getType()->getQualifier().hasBinding()) { - if (r_error) { - *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' lacks a binding number."; - } - return false; - } - - uint32_t set = reflection.getType()->getQualifier().hasSet() ? reflection.getType()->getQualifier().layoutSet : 0; - - if (set >= MAX_UNIFORM_SETS) { - if (r_error) { - *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' uses a set (" + itos(set) + ") index larger than what is supported (" + itos(MAX_UNIFORM_SETS) + ")."; - } - return false; - } - - if (set >= limits.maxBoundDescriptorSets) { - if (r_error) { - *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' uses a set (" + itos(set) + ") index larger than what is supported by the hardware (" + itos(limits.maxBoundDescriptorSets) + ")."; - } - return false; - } - - uint32_t binding = reflection.getType()->getQualifier().layoutBinding; - - if (set < (uint32_t)bindings.size()) { - // Check if this already exists. - for (int i = 0; i < bindings[set].size(); i++) { - if (bindings[set][i].binding == binding) { - // Already exists, verify that it's the same type. - if (bindings[set][i].descriptorType != layout_binding.descriptorType) { - if (r_error) { - *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(binding) + " with different uniform type."; - } - return false; - } - - // Also, verify that it's the same size. - if (bindings[set][i].descriptorCount != layout_binding.descriptorCount || uniform_infos[set][i].length != info.length) { - if (r_error) { - *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(binding) + " with different uniform size."; - } - return false; - } - - // Just append stage mask and return. - bindings.write[set].write[i].stageFlags |= shader_stage_masks[p_stage]; - uniform_infos.write[set].write[i].stages |= 1 << p_stage; - return true; - } - } - } - layout_binding.binding = binding; - layout_binding.stageFlags = shader_stage_masks[p_stage]; - layout_binding.pImmutableSamplers = nullptr; // No support for this yet. - - info.stages = 1 << p_stage; - info.binding = binding; - - if (set >= (uint32_t)bindings.size()) { - bindings.resize(set + 1); - uniform_infos.resize(set + 1); - } -#if 0 - print_line("stage: " + String(shader_stage_names[p_stage]) + " set: " + itos(set) + " binding: " + itos(info.binding) + " type:" + shader_uniform_names[info.type] + " length: " + itos(info.length)); -#endif - bindings.write[set].push_back(layout_binding); - uniform_infos.write[set].push_back(info); - - return true; -} -#endif // Version 1: initial. // Version 2: Added shader name. @@ -4786,346 +4585,68 @@ struct RenderingDeviceVulkanShaderBinarySpecializationConstant { struct RenderingDeviceVulkanShaderBinaryData { uint32_t vertex_input_mask; - uint32_t fragment_outputs; - uint32_t specialization_constant_count; + uint32_t fragment_output_mask; + uint32_t specialization_constants_count; uint32_t is_compute; uint32_t compute_local_size[3]; uint32_t set_count; uint32_t push_constant_size; - uint32_t push_constants_vk_stage; + uint32_t push_constant_vk_stages_mask; uint32_t stage_count; uint32_t shader_name_len; }; Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Vector<ShaderStageSPIRVData> &p_spirv, const String &p_shader_name) { - RenderingDeviceVulkanShaderBinaryData binary_data; - binary_data.vertex_input_mask = 0; - binary_data.fragment_outputs = 0; - binary_data.specialization_constant_count = 0; - binary_data.is_compute = 0; - binary_data.compute_local_size[0] = 0; - binary_data.compute_local_size[1] = 0; - binary_data.compute_local_size[2] = 0; - binary_data.set_count = 0; - binary_data.push_constant_size = 0; - binary_data.push_constants_vk_stage = 0; + SpirvReflectionData spirv_data; + if (_reflect_spirv(p_spirv, spirv_data) != OK) { + return Vector<uint8_t>(); + } + + ERR_FAIL_COND_V_MSG((uint32_t)spirv_data.uniforms.size() > limits.maxBoundDescriptorSets, Vector<uint8_t>(), + "Number of uniform sets is larger than what is supported by the hardware (" + itos(limits.maxBoundDescriptorSets) + ")."); + // Collect reflection data into binary data. + RenderingDeviceVulkanShaderBinaryData binary_data; Vector<Vector<RenderingDeviceVulkanShaderBinaryDataBinding>> uniform_info; // Set bindings. Vector<RenderingDeviceVulkanShaderBinarySpecializationConstant> specialization_constants; - - uint32_t stages_processed = 0; - - for (int i = 0; i < p_spirv.size(); i++) { - if (p_spirv[i].shader_stage == SHADER_STAGE_COMPUTE) { - binary_data.is_compute = true; - ERR_FAIL_COND_V_MSG(p_spirv.size() != 1, Vector<uint8_t>(), - "Compute shaders can only receive one stage, dedicated to compute."); - } - ERR_FAIL_COND_V_MSG(stages_processed & (1 << p_spirv[i].shader_stage), Vector<uint8_t>(), - "Stage " + String(shader_stage_names[p_spirv[i].shader_stage]) + " submitted more than once."); - - { - SpvReflectShaderModule module; - const uint8_t *spirv = p_spirv[i].spir_v.ptr(); - SpvReflectResult result = spvReflectCreateShaderModule(p_spirv[i].spir_v.size(), spirv, &module); - ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(), - "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed parsing shader."); - - if (binary_data.is_compute) { - binary_data.compute_local_size[0] = module.entry_points->local_size.x; - binary_data.compute_local_size[1] = module.entry_points->local_size.y; - binary_data.compute_local_size[2] = module.entry_points->local_size.z; - } - uint32_t binding_count = 0; - result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, nullptr); - ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(), - "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating descriptor bindings."); - - uint32_t stage = p_spirv[i].shader_stage; - - if (binding_count > 0) { - // Parse bindings. - - Vector<SpvReflectDescriptorBinding *> bindings; - bindings.resize(binding_count); - result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, bindings.ptrw()); - - ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(), - "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed getting descriptor bindings."); - - for (uint32_t j = 0; j < binding_count; j++) { - const SpvReflectDescriptorBinding &binding = *bindings[j]; - - RenderingDeviceVulkanShaderBinaryDataBinding info{}; - - bool need_array_dimensions = false; - bool need_block_size = false; - bool may_be_writable = false; - - switch (binding.descriptor_type) { - case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER: { - info.type = UNIFORM_TYPE_SAMPLER; - need_array_dimensions = true; - } break; - case SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: { - info.type = UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; - need_array_dimensions = true; - } break; - case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE: { - info.type = UNIFORM_TYPE_TEXTURE; - need_array_dimensions = true; - } break; - case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE: { - info.type = UNIFORM_TYPE_IMAGE; - need_array_dimensions = true; - may_be_writable = true; - } break; - case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: { - info.type = UNIFORM_TYPE_TEXTURE_BUFFER; - need_array_dimensions = true; - } break; - case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: { - info.type = UNIFORM_TYPE_IMAGE_BUFFER; - need_array_dimensions = true; - may_be_writable = true; - } break; - case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER: { - info.type = UNIFORM_TYPE_UNIFORM_BUFFER; - need_block_size = true; - } break; - case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER: { - info.type = UNIFORM_TYPE_STORAGE_BUFFER; - need_block_size = true; - may_be_writable = true; - } break; - case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: { - ERR_PRINT("Dynamic uniform buffer not supported."); - continue; - } break; - case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: { - ERR_PRINT("Dynamic storage buffer not supported."); - continue; - } break; - case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: { - info.type = UNIFORM_TYPE_INPUT_ATTACHMENT; - need_array_dimensions = true; - } break; - case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: { - ERR_PRINT("Acceleration structure not supported."); - continue; - } break; - } - - if (need_array_dimensions) { - if (binding.array.dims_count == 0) { - info.length = 1; - } else { - for (uint32_t k = 0; k < binding.array.dims_count; k++) { - if (k == 0) { - info.length = binding.array.dims[0]; - } else { - info.length *= binding.array.dims[k]; - } - } - } - - } else if (need_block_size) { - info.length = binding.block.size; - } else { - info.length = 0; - } - - if (may_be_writable) { - info.writable = !(binding.type_description->decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE) && !(binding.block.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE); - } else { - info.writable = false; - } - - info.binding = binding.binding; - uint32_t set = binding.set; - - ERR_FAIL_COND_V_MSG(set >= MAX_UNIFORM_SETS, Vector<uint8_t>(), - "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' uses a set (" + itos(set) + ") index larger than what is supported (" + itos(MAX_UNIFORM_SETS) + ")."); - - ERR_FAIL_COND_V_MSG(set >= limits.maxBoundDescriptorSets, Vector<uint8_t>(), - "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' uses a set (" + itos(set) + ") index larger than what is supported by the hardware (" + itos(limits.maxBoundDescriptorSets) + ")."); - - if (set < (uint32_t)uniform_info.size()) { - // Check if this already exists. - bool exists = false; - for (int k = 0; k < uniform_info[set].size(); k++) { - if (uniform_info[set][k].binding == (uint32_t)info.binding) { - // Already exists, verify that it's the same type. - ERR_FAIL_COND_V_MSG(uniform_info[set][k].type != info.type, Vector<uint8_t>(), - "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(info.binding) + " with different uniform type."); - - // Also, verify that it's the same size. - ERR_FAIL_COND_V_MSG(uniform_info[set][k].length != info.length, Vector<uint8_t>(), - "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(info.binding) + " with different uniform size."); - - // Also, verify that it has the same writability. - ERR_FAIL_COND_V_MSG(uniform_info[set][k].writable != info.writable, Vector<uint8_t>(), - "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(info.binding) + " with different writability."); - - // Just append stage mask and return. - uniform_info.write[set].write[k].stages |= 1 << stage; - exists = true; - break; - } - } - - if (exists) { - continue; // Merged. - } - } - - info.stages = 1 << stage; - - if (set >= (uint32_t)uniform_info.size()) { - uniform_info.resize(set + 1); - } - - uniform_info.write[set].push_back(info); - } - } - - { - // Specialization constants. - - uint32_t sc_count = 0; - result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, nullptr); - ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(), - "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating specialization constants."); - - if (sc_count) { - Vector<SpvReflectSpecializationConstant *> spec_constants; - spec_constants.resize(sc_count); - - result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, spec_constants.ptrw()); - ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(), - "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed obtaining specialization constants."); - - for (uint32_t j = 0; j < sc_count; j++) { - int32_t existing = -1; - RenderingDeviceVulkanShaderBinarySpecializationConstant sconst{}; - SpvReflectSpecializationConstant *spc = spec_constants[j]; - - sconst.constant_id = spc->constant_id; - sconst.int_value = 0.0; // Clear previous value JIC. - switch (spc->constant_type) { - case SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL: { - sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL; - sconst.bool_value = spc->default_value.int_bool_value != 0; - } break; - case SPV_REFLECT_SPECIALIZATION_CONSTANT_INT: { - sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT; - sconst.int_value = spc->default_value.int_bool_value; - } break; - case SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT: { - sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT; - sconst.float_value = spc->default_value.float_value; - } break; - } - sconst.stage_flags = 1 << p_spirv[i].shader_stage; - - for (int k = 0; k < specialization_constants.size(); k++) { - if (specialization_constants[k].constant_id == sconst.constant_id) { - ERR_FAIL_COND_V_MSG(specialization_constants[k].type != sconst.type, Vector<uint8_t>(), "More than one specialization constant used for id (" + itos(sconst.constant_id) + "), but their types differ."); - ERR_FAIL_COND_V_MSG(specialization_constants[k].int_value != sconst.int_value, Vector<uint8_t>(), "More than one specialization constant used for id (" + itos(sconst.constant_id) + "), but their default values differ."); - existing = k; - break; - } - } - - if (existing > 0) { - specialization_constants.write[existing].stage_flags |= sconst.stage_flags; - } else { - specialization_constants.push_back(sconst); - } - } - } - } - - if (stage == SHADER_STAGE_VERTEX) { - uint32_t iv_count = 0; - result = spvReflectEnumerateInputVariables(&module, &iv_count, nullptr); - ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(), - "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating input variables."); - - if (iv_count) { - Vector<SpvReflectInterfaceVariable *> input_vars; - input_vars.resize(iv_count); - - result = spvReflectEnumerateInputVariables(&module, &iv_count, input_vars.ptrw()); - ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(), - "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed obtaining input variables."); - - for (uint32_t j = 0; j < iv_count; j++) { - if (input_vars[j] && input_vars[j]->decoration_flags == 0) { // Regular input. - binary_data.vertex_input_mask |= (1 << uint32_t(input_vars[j]->location)); - } - } - } - } - - if (stage == SHADER_STAGE_FRAGMENT) { - uint32_t ov_count = 0; - result = spvReflectEnumerateOutputVariables(&module, &ov_count, nullptr); - ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(), - "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating output variables."); - - if (ov_count) { - Vector<SpvReflectInterfaceVariable *> output_vars; - output_vars.resize(ov_count); - - result = spvReflectEnumerateOutputVariables(&module, &ov_count, output_vars.ptrw()); - ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(), - "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed obtaining output variables."); - - for (uint32_t j = 0; j < ov_count; j++) { - const SpvReflectInterfaceVariable *refvar = output_vars[j]; - if (refvar != nullptr && refvar->built_in != SpvBuiltInFragDepth) { - binary_data.fragment_outputs |= 1 << refvar->location; - } - } - } + { + binary_data.vertex_input_mask = spirv_data.vertex_input_mask; + binary_data.fragment_output_mask = spirv_data.fragment_output_mask; + binary_data.specialization_constants_count = spirv_data.specialization_constants.size(); + binary_data.is_compute = spirv_data.is_compute; + binary_data.compute_local_size[0] = spirv_data.compute_local_size[0]; + binary_data.compute_local_size[1] = spirv_data.compute_local_size[1]; + binary_data.compute_local_size[2] = spirv_data.compute_local_size[2]; + binary_data.set_count = spirv_data.uniforms.size(); + binary_data.push_constant_size = spirv_data.push_constant_size; + for (uint32_t i = 0; i < SHADER_STAGE_MAX; i++) { + if (spirv_data.push_constant_stages_mask.has_flag((ShaderStage)(1 << i))) { + binary_data.push_constant_vk_stages_mask |= shader_stage_masks[i]; } + } - uint32_t pc_count = 0; - result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, nullptr); - ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(), - "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating push constants."); - - if (pc_count) { - ERR_FAIL_COND_V_MSG(pc_count > 1, Vector<uint8_t>(), - "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "': Only one push constant is supported, which should be the same across shader stages."); - - Vector<SpvReflectBlockVariable *> pconstants; - pconstants.resize(pc_count); - result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, pconstants.ptrw()); - ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(), - "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed obtaining push constants."); -#if 0 - if (pconstants[0] == nullptr) { - Ref<FileAccess> f = FileAccess::open("res://popo.spv", FileAccess::WRITE); - f->store_buffer((const uint8_t *)&SpirV[0], SpirV.size() * sizeof(uint32_t)); - } -#endif - - ERR_FAIL_COND_V_MSG(binary_data.push_constant_size && binary_data.push_constant_size != pconstants[0]->size, Vector<uint8_t>(), - "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "': Push constant block must be the same across shader stages."); - - binary_data.push_constant_size = pconstants[0]->size; - binary_data.push_constants_vk_stage |= shader_stage_masks[stage]; - - //print_line("Stage: " + String(shader_stage_names[stage]) + " push constant of size=" + itos(push_constant.push_constant_size)); + for (const Vector<SpirvReflectionData::Uniform> &spirv_set : spirv_data.uniforms) { + Vector<RenderingDeviceVulkanShaderBinaryDataBinding> set_bindings; + for (const SpirvReflectionData::Uniform &spirv_uniform : spirv_set) { + RenderingDeviceVulkanShaderBinaryDataBinding binding{}; + binding.type = (uint32_t)spirv_uniform.type; + binding.binding = spirv_uniform.binding; + binding.stages = (uint32_t)spirv_uniform.stages_mask; + binding.length = spirv_uniform.length; + binding.writable = (uint32_t)spirv_uniform.writable; + set_bindings.push_back(binding); } - - // Destroy the reflection data when no longer required. - spvReflectDestroyShaderModule(&module); + uniform_info.push_back(set_bindings); } - stages_processed |= (1 << p_spirv[i].shader_stage); + for (const SpirvReflectionData::SpecializationConstant &spirv_sc : spirv_data.specialization_constants) { + RenderingDeviceVulkanShaderBinarySpecializationConstant spec_constant{}; + spec_constant.type = (uint32_t)spirv_sc.type; + spec_constant.constant_id = spirv_sc.constant_id; + spec_constant.int_value = spirv_sc.int_value; + spec_constant.stage_flags = (uint32_t)spirv_sc.stages_mask; + specialization_constants.push_back(spec_constant); + } } Vector<Vector<uint8_t>> compressed_stages; @@ -5167,7 +4688,7 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve stages_binary_size += s; } - binary_data.specialization_constant_count = specialization_constants.size(); + binary_data.specialization_constants_count = specialization_constants.size(); binary_data.set_count = uniform_info.size(); binary_data.stage_count = p_spirv.size(); @@ -5273,12 +4794,12 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ const RenderingDeviceVulkanShaderBinaryData &binary_data = *(reinterpret_cast<const RenderingDeviceVulkanShaderBinaryData *>(binptr + 12)); Shader::PushConstant push_constant; - push_constant.push_constant_size = binary_data.push_constant_size; - push_constant.push_constants_vk_stage = binary_data.push_constants_vk_stage; + push_constant.size = binary_data.push_constant_size; + push_constant.vk_stages_mask = binary_data.push_constant_vk_stages_mask; uint32_t vertex_input_mask = binary_data.vertex_input_mask; - uint32_t fragment_outputs = binary_data.fragment_outputs; + uint32_t fragment_output_mask = binary_data.fragment_output_mask; bool is_compute = binary_data.is_compute; @@ -5374,11 +4895,11 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ read_offset += set_size; } - ERR_FAIL_COND_V(read_offset + binary_data.specialization_constant_count * sizeof(RenderingDeviceVulkanShaderBinarySpecializationConstant) >= binsize, RID()); + ERR_FAIL_COND_V(read_offset + binary_data.specialization_constants_count * sizeof(RenderingDeviceVulkanShaderBinarySpecializationConstant) >= binsize, RID()); Vector<Shader::SpecializationConstant> specialization_constants; - for (uint32_t i = 0; i < binary_data.specialization_constant_count; i++) { + for (uint32_t i = 0; i < binary_data.specialization_constants_count; i++) { const RenderingDeviceVulkanShaderBinarySpecializationConstant &src_sc = *(reinterpret_cast<const RenderingDeviceVulkanShaderBinarySpecializationConstant *>(binptr + read_offset)); Shader::SpecializationConstant sc; sc.constant.int_value = src_sc.int_value; @@ -5444,7 +4965,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ Shader shader; shader.vertex_input_mask = vertex_input_mask; - shader.fragment_output_mask = fragment_outputs; + shader.fragment_output_mask = fragment_output_mask; shader.push_constant = push_constant; shader.is_compute = is_compute; shader.compute_local_size[0] = compute_local_size[0]; @@ -5474,19 +4995,11 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ break; } - const VkShaderStageFlagBits shader_stage_bits[SHADER_STAGE_MAX] = { - VK_SHADER_STAGE_VERTEX_BIT, - VK_SHADER_STAGE_FRAGMENT_BIT, - VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, - VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, - VK_SHADER_STAGE_COMPUTE_BIT, - }; - VkPipelineShaderStageCreateInfo shader_stage; shader_stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; shader_stage.pNext = nullptr; shader_stage.flags = 0; - shader_stage.stage = shader_stage_bits[stage_type[i]]; + shader_stage.stage = shader_stage_masks[stage_type[i]]; shader_stage.module = module; shader_stage.pName = "main"; shader_stage.pSpecializationInfo = nullptr; @@ -5558,10 +5071,10 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ // Needs to be declared in this outer scope, otherwise it may not outlive its assignment // to pipeline_layout_create_info. VkPushConstantRange push_constant_range; - if (push_constant.push_constant_size) { - push_constant_range.stageFlags = push_constant.push_constants_vk_stage; + if (push_constant.size) { + push_constant_range.stageFlags = push_constant.vk_stages_mask; push_constant_range.offset = 0; - push_constant_range.size = push_constant.push_constant_size; + push_constant_range.size = push_constant.size; pipeline_layout_create_info.pushConstantRangeCount = 1; pipeline_layout_create_info.pPushConstantRanges = &push_constant_range; @@ -5635,7 +5148,7 @@ RID RenderingDeviceVulkan::uniform_buffer_create(uint32_t p_size_bytes, const Ve return id; } -RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data, uint32_t p_usage) { +RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data, BitField<StorageBufferUsage> p_usage) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V_MSG(draw_list != nullptr && p_data.size(), RID(), "Creating buffers with data is forbidden during creation of a draw list"); @@ -5646,7 +5159,7 @@ RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Ve Buffer buffer; uint32_t flags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - if (p_usage & STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT) { + if (p_usage.has_flag(STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT)) { flags |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; } Error err = _buffer_allocate(&buffer, p_size_bytes, flags, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); @@ -5956,10 +5469,8 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, // Can also be used as storage, add to mutable sampled. mutable_sampled_textures.push_back(texture); } - if (texture->owner.is_valid()) { - texture = texture_owner.get_or_null(texture->owner); - ERR_FAIL_COND_V(!texture, RID()); // Bug, should never happen. - } + + DEV_ASSERT(!texture->owner.is_valid() || texture_owner.get_or_null(texture->owner)); img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; @@ -6010,10 +5521,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, mutable_sampled_textures.push_back(texture); } - if (texture->owner.is_valid()) { - texture = texture_owner.get_or_null(texture->owner); - ERR_FAIL_COND_V(!texture, RID()); // Bug, should never happen. - } + DEV_ASSERT(!texture->owner.is_valid() || texture_owner.get_or_null(texture->owner)); img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; @@ -6058,10 +5566,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, mutable_storage_textures.push_back(texture); } - if (texture->owner.is_valid()) { - texture = texture_owner.get_or_null(texture->owner); - ERR_FAIL_COND_V(!texture, RID()); // Bug, should never happen. - } + DEV_ASSERT(!texture->owner.is_valid() || texture_owner.get_or_null(texture->owner)); img_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; @@ -6223,10 +5728,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, img_info.sampler = VK_NULL_HANDLE; img_info.imageView = texture->view; - if (texture->owner.is_valid()) { - texture = texture_owner.get_or_null(texture->owner); - ERR_FAIL_COND_V(!texture, RID()); // Bug, should never happen. - } + DEV_ASSERT(!texture->owner.is_valid() || texture_owner.get_or_null(texture->owner)); img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; @@ -6424,7 +5926,7 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) { } // Make sure no one is using the buffer -- the "false" gets us to the same command buffer as below. - _buffer_memory_barrier(buffer->buffer, 0, buffer->size, src_stage_mask, src_access_mask, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT, false); + _buffer_memory_barrier(buffer->buffer, 0, buffer->size, src_stage_mask, VK_PIPELINE_STAGE_TRANSFER_BIT, src_access_mask, VK_ACCESS_TRANSFER_READ_BIT, false); VkCommandBuffer command_buffer = frames[frame].setup_command_buffer; @@ -6460,7 +5962,7 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) { /**** RENDER PIPELINE ****/ /*************************/ -RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass, const Vector<PipelineSpecializationConstant> &p_specialization_constants) { +RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, BitField<PipelineDynamicStateFlags> p_dynamic_state_flags, uint32_t p_for_render_pass, const Vector<PipelineSpecializationConstant> &p_specialization_constants) { _THREAD_SAFE_METHOD_ // Needs a shader. @@ -6746,31 +6248,31 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma dynamic_states.push_back(VK_DYNAMIC_STATE_VIEWPORT); // Viewport and scissor are always dynamic. dynamic_states.push_back(VK_DYNAMIC_STATE_SCISSOR); - if (p_dynamic_state_flags & DYNAMIC_STATE_LINE_WIDTH) { + if (p_dynamic_state_flags.has_flag(DYNAMIC_STATE_LINE_WIDTH)) { dynamic_states.push_back(VK_DYNAMIC_STATE_LINE_WIDTH); } - if (p_dynamic_state_flags & DYNAMIC_STATE_DEPTH_BIAS) { + if (p_dynamic_state_flags.has_flag(DYNAMIC_STATE_DEPTH_BIAS)) { dynamic_states.push_back(VK_DYNAMIC_STATE_DEPTH_BIAS); } - if (p_dynamic_state_flags & DYNAMIC_STATE_BLEND_CONSTANTS) { + if (p_dynamic_state_flags.has_flag(DYNAMIC_STATE_BLEND_CONSTANTS)) { dynamic_states.push_back(VK_DYNAMIC_STATE_BLEND_CONSTANTS); } - if (p_dynamic_state_flags & DYNAMIC_STATE_DEPTH_BOUNDS) { + if (p_dynamic_state_flags.has_flag(DYNAMIC_STATE_DEPTH_BOUNDS)) { dynamic_states.push_back(VK_DYNAMIC_STATE_DEPTH_BOUNDS); } - if (p_dynamic_state_flags & DYNAMIC_STATE_STENCIL_COMPARE_MASK) { + if (p_dynamic_state_flags.has_flag(DYNAMIC_STATE_STENCIL_COMPARE_MASK)) { dynamic_states.push_back(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK); } - if (p_dynamic_state_flags & DYNAMIC_STATE_STENCIL_WRITE_MASK) { + if (p_dynamic_state_flags.has_flag(DYNAMIC_STATE_STENCIL_WRITE_MASK)) { dynamic_states.push_back(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK); } - if (p_dynamic_state_flags & DYNAMIC_STATE_STENCIL_REFERENCE) { + if (p_dynamic_state_flags.has_flag(DYNAMIC_STATE_STENCIL_REFERENCE)) { dynamic_states.push_back(VK_DYNAMIC_STATE_STENCIL_REFERENCE); } @@ -6878,10 +6380,10 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma ERR_FAIL_COND_V_MSG(err, RID(), "vkCreateGraphicsPipelines failed with error " + itos(err) + " for shader '" + shader->name + "'."); pipeline.set_formats = shader->set_formats; - pipeline.push_constant_stages = shader->push_constant.push_constants_vk_stage; + pipeline.push_constant_stages_mask = shader->push_constant.vk_stages_mask; pipeline.pipeline_layout = shader->pipeline_layout; pipeline.shader = p_shader; - pipeline.push_constant_size = shader->push_constant.push_constant_size; + pipeline.push_constant_size = shader->push_constant.size; #ifdef DEBUG_ENABLED pipeline.validation.dynamic_state = p_dynamic_state_flags; @@ -6993,10 +6495,10 @@ RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader, const Vector<Pi ERR_FAIL_COND_V_MSG(err, RID(), "vkCreateComputePipelines failed with error " + itos(err) + "."); pipeline.set_formats = shader->set_formats; - pipeline.push_constant_stages = shader->push_constant.push_constants_vk_stage; + pipeline.push_constant_stages_mask = shader->push_constant.vk_stages_mask; pipeline.pipeline_layout = shader->pipeline_layout; pipeline.shader = p_shader; - pipeline.push_constant_size = shader->push_constant.push_constant_size; + pipeline.push_constant_size = shader->push_constant.size; pipeline.local_group_size[0] = shader->compute_local_size[0]; pipeline.local_group_size[1] = shader->compute_local_size[1]; pipeline.local_group_size[2] = shader->compute_local_size[2]; @@ -7638,7 +7140,7 @@ void RenderingDeviceVulkan::draw_list_bind_render_pipeline(DrawListID p_list, RI dl->state.set_count = pcount; // Update set count. if (pipeline->push_constant_size) { - dl->state.pipeline_push_constant_stages = pipeline->push_constant_stages; + dl->state.pipeline_push_constant_stages = pipeline->push_constant_stages_mask; #ifdef DEBUG_ENABLED dl->validation.pipeline_push_constant_supplied = false; #endif @@ -8254,7 +7756,7 @@ void RenderingDeviceVulkan::compute_list_bind_compute_pipeline(ComputeListID p_l cl->state.set_count = pcount; // Update set count. if (pipeline->push_constant_size) { - cl->state.pipeline_push_constant_stages = pipeline->push_constant_stages; + cl->state.pipeline_push_constant_stages = pipeline->push_constant_stages_mask; #ifdef DEBUG_ENABLED cl->validation.pipeline_push_constant_supplied = false; #endif diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index c6e1830e90..3ccd7bb1d9 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -226,8 +226,8 @@ class RenderingDeviceVulkan : public RenderingDevice { Error _buffer_update(Buffer *p_buffer, size_t p_offset, const uint8_t *p_data, size_t p_data_size, bool p_use_draw_command_buffer = false, uint32_t p_required_align = 32); void _full_barrier(bool p_sync_with_draw); - void _memory_barrier(VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_sccess, bool p_sync_with_draw); - void _buffer_memory_barrier(VkBuffer buffer, uint64_t p_from, uint64_t p_size, VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_sccess, bool p_sync_with_draw); + void _memory_barrier(VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_access, bool p_sync_with_draw); + void _buffer_memory_barrier(VkBuffer buffer, uint64_t p_from, uint64_t p_size, VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_access, bool p_sync_with_draw); /*********************/ /**** FRAMEBUFFER ****/ @@ -543,10 +543,6 @@ class RenderingDeviceVulkan : public RenderingDevice { // As a result, we need to figure out quickly when something is no longer "compatible". // in order to avoid costly rebinds. - enum { - MAX_UNIFORM_SETS = 16 - }; - struct UniformInfo { UniformType type = UniformType::UNIFORM_TYPE_MAX; bool writable = false; @@ -628,8 +624,8 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t fragment_output_mask = 0; struct PushConstant { - uint32_t push_constant_size = 0; - uint32_t push_constants_vk_stage = 0; + uint32_t size = 0; + uint32_t vk_stages_mask = 0; }; PushConstant push_constant; @@ -791,7 +787,7 @@ class RenderingDeviceVulkan : public RenderingDevice { VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; // Not owned, needed for push constants. VkPipeline pipeline = VK_NULL_HANDLE; uint32_t push_constant_size = 0; - uint32_t push_constant_stages = 0; + uint32_t push_constant_stages_mask = 0; }; RID_Owner<RenderPipeline, true> render_pipeline_owner; @@ -802,7 +798,7 @@ class RenderingDeviceVulkan : public RenderingDevice { VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; // Not owned, needed for push constants. VkPipeline pipeline = VK_NULL_HANDLE; uint32_t push_constant_size = 0; - uint32_t push_constant_stages = 0; + uint32_t push_constant_stages_mask = 0; uint32_t local_group_size[3] = { 0, 0, 0 }; }; @@ -1117,7 +1113,7 @@ public: /*****************/ virtual RID uniform_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>()); - virtual RID storage_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>(), uint32_t p_usage = 0); + virtual RID storage_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>(), BitField<StorageBufferUsage> p_usage = 0); virtual RID texture_buffer_create(uint32_t p_size_elements, DataFormat p_format, const Vector<uint8_t> &p_data = Vector<uint8_t>()); virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set); @@ -1132,7 +1128,7 @@ public: /**** RENDER PIPELINE ****/ /*************************/ - virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>()); + virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, BitField<PipelineDynamicStateFlags> p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>()); virtual bool render_pipeline_is_valid(RID p_pipeline); /**************************/ |