diff options
Diffstat (limited to 'drivers/vulkan/rendering_device_vulkan.cpp')
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.cpp | 120 |
1 files changed, 91 insertions, 29 deletions
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index d521f675fb..a55abe6a82 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -5043,17 +5043,24 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ _THREAD_SAFE_METHOD_ - Shader shader; + RID id; + if (p_placeholder.is_null()) { + id = shader_owner.make_rid(); + } else { + id = p_placeholder; + } + + Shader *shader = shader_owner.get_or_null(id); - shader.vertex_input_mask = vertex_input_mask; - 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]; - shader.compute_local_size[1] = compute_local_size[1]; - shader.compute_local_size[2] = compute_local_size[2]; - shader.specialization_constants = specialization_constants; - shader.name = name; + shader->vertex_input_mask = vertex_input_mask; + 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]; + shader->compute_local_size[1] = compute_local_size[1]; + shader->compute_local_size[2] = compute_local_size[2]; + shader->specialization_constants = specialization_constants; + shader->name = name; String error_text; @@ -5085,7 +5092,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ shader_stage.pName = "main"; shader_stage.pSpecializationInfo = nullptr; - shader.pipeline_stages.push_back(shader_stage); + shader->pipeline_stages.push_back(shader_stage); } // Proceed to create descriptor sets. @@ -5128,8 +5135,8 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ } } - shader.sets.push_back(set); - shader.set_formats.push_back(format); + shader->sets.push_back(set); + shader->set_formats.push_back(format); } } @@ -5139,13 +5146,13 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipeline_layout_create_info.pNext = nullptr; pipeline_layout_create_info.flags = 0; - pipeline_layout_create_info.setLayoutCount = shader.sets.size(); + pipeline_layout_create_info.setLayoutCount = shader->sets.size(); Vector<VkDescriptorSetLayout> layouts; - layouts.resize(shader.sets.size()); + layouts.resize(shader->sets.size()); for (int i = 0; i < layouts.size(); i++) { - layouts.write[i] = shader.sets[i].descriptor_set_layout; + layouts.write[i] = shader->sets[i].descriptor_set_layout; } pipeline_layout_create_info.pSetLayouts = layouts.ptr(); @@ -5164,7 +5171,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ pipeline_layout_create_info.pPushConstantRanges = nullptr; } - VkResult err = vkCreatePipelineLayout(device, &pipeline_layout_create_info, nullptr, &shader.pipeline_layout); + VkResult err = vkCreatePipelineLayout(device, &pipeline_layout_create_info, nullptr, &shader->pipeline_layout); if (err) { error_text = "Error (" + itos(err) + ") creating pipeline layout."; @@ -5174,23 +5181,19 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ if (!success) { // Clean up if failed. - for (int i = 0; i < shader.pipeline_stages.size(); i++) { - vkDestroyShaderModule(device, shader.pipeline_stages[i].module, nullptr); + for (int i = 0; i < shader->pipeline_stages.size(); i++) { + vkDestroyShaderModule(device, shader->pipeline_stages[i].module, nullptr); } - for (int i = 0; i < shader.sets.size(); i++) { - vkDestroyDescriptorSetLayout(device, shader.sets[i].descriptor_set_layout, nullptr); + for (int i = 0; i < shader->sets.size(); i++) { + vkDestroyDescriptorSetLayout(device, shader->sets[i].descriptor_set_layout, nullptr); } + shader_owner.free(id); + ERR_FAIL_V_MSG(RID(), error_text); } - RID id; - if (p_placeholder.is_null()) { - id = shader_owner.make_rid(shader); - } else { - shader_owner.initialize_rid(p_placeholder, shader); - id = p_placeholder; - } + #ifdef DEV_ENABLED set_resource_name(id, "RID:" + itos(id.get_id())); #endif @@ -5198,7 +5201,8 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ } RID RenderingDeviceVulkan::shader_create_placeholder() { - return shader_owner.allocate_rid(); + Shader shader; + return shader_owner.make_rid(shader); } uint32_t RenderingDeviceVulkan::shader_get_vertex_input_attribute_mask(RID p_shader) { @@ -5901,6 +5905,64 @@ void RenderingDeviceVulkan::uniform_set_set_invalidation_callback(RID p_uniform_ us->invalidated_callback_userdata = p_userdata; } +Error RenderingDeviceVulkan::buffer_copy(RID p_src_buffer, RID p_dst_buffer, uint32_t p_src_offset, uint32_t p_dst_offset, uint32_t p_size, BitField<BarrierMask> p_post_barrier) { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND_V_MSG(draw_list, ERR_INVALID_PARAMETER, + "Copying buffers is forbidden during creation of a draw list"); + ERR_FAIL_COND_V_MSG(compute_list, ERR_INVALID_PARAMETER, + "Copying buffers is forbidden during creation of a compute list"); + + // This method assumes the barriers have been pushed prior to being called, therefore no barriers are pushed + // for the source or destination buffers before performing the copy. These masks are effectively ignored. + VkPipelineShaderStageCreateFlags src_stage_mask = 0; + VkAccessFlags src_access_mask = 0; + Buffer *src_buffer = _get_buffer_from_owner(p_src_buffer, src_stage_mask, src_access_mask, BARRIER_MASK_NO_BARRIER); + if (!src_buffer) { + ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Source buffer argument is not a valid buffer of any type."); + } + + VkPipelineStageFlags dst_stage_mask = 0; + VkAccessFlags dst_access = 0; + if (p_post_barrier.has_flag(BARRIER_MASK_TRANSFER)) { + // If the post barrier mask defines it, we indicate the destination buffer will require a barrier with these flags set + // after the copy command is queued. + dst_stage_mask = VK_PIPELINE_STAGE_TRANSFER_BIT; + dst_access = VK_ACCESS_TRANSFER_WRITE_BIT; + } + + Buffer *dst_buffer = _get_buffer_from_owner(p_dst_buffer, dst_stage_mask, dst_access, p_post_barrier); + if (!dst_buffer) { + ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Destination buffer argument is not a valid buffer of any type."); + } + + // Validate the copy's dimensions for both buffers. + ERR_FAIL_COND_V_MSG((p_size + p_src_offset) > src_buffer->size, ERR_INVALID_PARAMETER, "Size is larger than the source buffer."); + ERR_FAIL_COND_V_MSG((p_size + p_dst_offset) > dst_buffer->size, ERR_INVALID_PARAMETER, "Size is larger than the destination buffer."); + + // Perform the copy. + VkBufferCopy region; + region.srcOffset = p_src_offset; + region.dstOffset = p_dst_offset; + region.size = p_size; + vkCmdCopyBuffer(frames[frame].draw_command_buffer, src_buffer->buffer, dst_buffer->buffer, 1, ®ion); + +#ifdef FORCE_FULL_BARRIER + _full_barrier(true); +#else + if (dst_stage_mask == 0) { + dst_stage_mask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + + // As indicated by the post barrier mask, push a new barrier. + if (p_post_barrier != RD::BARRIER_MASK_NO_BARRIER) { + _buffer_memory_barrier(dst_buffer->buffer, p_dst_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, true); + } +#endif + + return OK; +} + Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, BitField<BarrierMask> p_post_barrier) { _THREAD_SAFE_METHOD_ |