summaryrefslogtreecommitdiff
path: root/drivers/vulkan/rendering_device_vulkan.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vulkan/rendering_device_vulkan.cpp')
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp87
1 files changed, 58 insertions, 29 deletions
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index f2d78636d7..de29363556 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -1655,9 +1655,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_create_info.pNext = nullptr;
image_create_info.flags = 0;
-#ifndef _MSC_VER
-#warning TODO check for support via RenderingDevice to enable on mobile when possible
-#endif
+ // TODO: Check for support via RenderingDevice to enable on mobile when possible.
#ifndef ANDROID_ENABLED
@@ -1733,7 +1731,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
ERR_FAIL_INDEX_V(p_format.samples, TEXTURE_SAMPLES_MAX, RID());
- image_create_info.samples = rasterization_sample_count[p_format.samples];
+ image_create_info.samples = _ensure_supported_sample_count(p_format.samples);
image_create_info.tiling = (p_format.usage_bits & TEXTURE_USAGE_CPU_READ_BIT) ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
// Usage.
@@ -1884,6 +1882,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
texture.mipmaps = image_create_info.mipLevels;
texture.base_mipmap = 0;
texture.base_layer = 0;
+ texture.is_resolve_buffer = p_format.is_resolve_buffer;
texture.usage_flags = p_format.usage_bits;
texture.samples = p_format.samples;
texture.allowed_shared_formats = p_format.shareable_formats;
@@ -3425,7 +3424,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
description.pNext = nullptr;
description.flags = 0;
description.format = vulkan_formats[p_attachments[i].format];
- description.samples = rasterization_sample_count[p_attachments[i].samples];
+ description.samples = _ensure_supported_sample_count(p_attachments[i].samples);
bool is_sampled = p_attachments[i].usage_flags & TEXTURE_USAGE_SAMPLING_BIT;
bool is_storage = p_attachments[i].usage_flags & TEXTURE_USAGE_STORAGE_BIT;
@@ -3546,7 +3545,8 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
break;
}
}
- } else {
+ }
+ if (!used_last) {
for (int j = 0; j < p_passes[last_pass].color_attachments.size(); j++) {
if (p_passes[last_pass].color_attachments[j] == i) {
used_last = true;
@@ -4116,7 +4116,11 @@ RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attac
} else if (texture && texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) {
pass.vrs_attachment = i;
} else {
- pass.color_attachments.push_back(texture ? i : FramebufferPass::ATTACHMENT_UNUSED);
+ if (texture && texture->is_resolve_buffer) {
+ pass.resolve_attachments.push_back(i);
+ } else {
+ pass.color_attachments.push_back(texture ? i : FramebufferPass::ATTACHMENT_UNUSED);
+ }
}
}
@@ -4146,8 +4150,8 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex
size.height = texture->height;
size_set = true;
} else if (texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) {
- // If this is not the first attachement we assume this is used as the VRS attachment.
- // In this case this texture will be 1/16th the size of the color attachement.
+ // If this is not the first attachment we assume this is used as the VRS attachment.
+ // In this case this texture will be 1/16th the size of the color attachment.
// So we skip the size check.
} else {
ERR_FAIL_COND_V_MSG((uint32_t)size.width != texture->width || (uint32_t)size.height != texture->height, RID(),
@@ -4822,7 +4826,7 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
for (uint32_t j = 0; j < binding_count; j++) {
const SpvReflectDescriptorBinding &binding = *bindings[j];
- RenderingDeviceVulkanShaderBinaryDataBinding info;
+ RenderingDeviceVulkanShaderBinaryDataBinding info{};
bool need_array_dimensions = false;
bool need_block_size = false;
@@ -4973,7 +4977,7 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
for (uint32_t j = 0; j < sc_count; j++) {
int32_t existing = -1;
- RenderingDeviceVulkanShaderBinarySpecializationConstant sconst;
+ RenderingDeviceVulkanShaderBinarySpecializationConstant sconst{};
SpvReflectSpecializationConstant *spc = spec_constants[j];
sconst.constant_id = spc->constant_id;
@@ -5166,9 +5170,9 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
uint32_t offset = 0;
uint8_t *binptr = ret.ptrw();
binptr[0] = 'G';
- binptr[1] = 'V';
+ binptr[1] = 'S';
binptr[2] = 'B';
- binptr[3] = 'D'; // Godot vulkan binary data.
+ binptr[3] = 'D'; // Godot Shader Binary Data.
offset += 4;
encode_uint32(SHADER_BINARY_VERSION, binptr + offset);
offset += sizeof(uint32_t);
@@ -5229,7 +5233,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_
uint32_t read_offset = 0;
// Consistency check.
ERR_FAIL_COND_V(binsize < sizeof(uint32_t) * 3 + sizeof(RenderingDeviceVulkanShaderBinaryData), RID());
- ERR_FAIL_COND_V(binptr[0] != 'G' || binptr[1] != 'V' || binptr[2] != 'B' || binptr[3] != 'D', RID());
+ ERR_FAIL_COND_V(binptr[0] != 'G' || binptr[1] != 'S' || binptr[2] != 'B' || binptr[3] != 'D', RID());
uint32_t bin_version = decode_uint32(binptr + 4);
ERR_FAIL_COND_V(bin_version != SHADER_BINARY_VERSION, RID());
@@ -6555,7 +6559,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
ERR_FAIL_INDEX_V(p_rasterization_state.cull_mode, 3, RID());
rasterization_state_create_info.cullMode = cull_mode[p_rasterization_state.cull_mode];
rasterization_state_create_info.frontFace = (p_rasterization_state.front_face == POLYGON_FRONT_FACE_CLOCKWISE ? VK_FRONT_FACE_CLOCKWISE : VK_FRONT_FACE_COUNTER_CLOCKWISE);
- rasterization_state_create_info.depthBiasEnable = p_rasterization_state.depth_bias_enable;
+ rasterization_state_create_info.depthBiasEnable = p_rasterization_state.depth_bias_enabled;
rasterization_state_create_info.depthBiasConstantFactor = p_rasterization_state.depth_bias_constant_factor;
rasterization_state_create_info.depthBiasClamp = p_rasterization_state.depth_bias_clamp;
rasterization_state_create_info.depthBiasSlopeFactor = p_rasterization_state.depth_bias_slope_factor;
@@ -6567,7 +6571,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
multisample_state_create_info.pNext = nullptr;
multisample_state_create_info.flags = 0;
- multisample_state_create_info.rasterizationSamples = rasterization_sample_count[p_multisample_state.sample_count];
+ multisample_state_create_info.rasterizationSamples = _ensure_supported_sample_count(p_multisample_state.sample_count);
multisample_state_create_info.sampleShadingEnable = p_multisample_state.enable_sample_shading;
multisample_state_create_info.minSampleShading = p_multisample_state.min_sample_shading;
Vector<VkSampleMask> sample_mask;
@@ -7256,12 +7260,12 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
return OK;
}
-void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list, Framebuffer *framebuffer, Point2i viewport_offset, Point2i viewport_size, bool p_clear_color, const Vector<Color> &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil) {
+void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *p_draw_list, Framebuffer *p_framebuffer, Point2i p_viewport_offset, Point2i p_viewport_size, bool p_clear_color, const Vector<Color> &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil) {
Vector<VkClearAttachment> clear_attachments;
int color_index = 0;
int texture_index = 0;
- for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
- Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
+ for (int i = 0; i < p_framebuffer->texture_ids.size(); i++) {
+ Texture *texture = texture_owner.get_or_null(p_framebuffer->texture_ids[i]);
if (!texture) {
texture_index++;
@@ -7294,12 +7298,12 @@ void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list,
VkClearRect cr;
cr.baseArrayLayer = 0;
cr.layerCount = 1;
- cr.rect.offset.x = viewport_offset.x;
- cr.rect.offset.y = viewport_offset.y;
- cr.rect.extent.width = viewport_size.width;
- cr.rect.extent.height = viewport_size.height;
+ cr.rect.offset.x = p_viewport_offset.x;
+ cr.rect.offset.y = p_viewport_offset.y;
+ cr.rect.extent.width = p_viewport_size.width;
+ cr.rect.extent.height = p_viewport_size.height;
- vkCmdClearAttachments(draw_list->command_buffer, clear_attachments.size(), clear_attachments.ptr(), 1, &cr);
+ vkCmdClearAttachments(p_draw_list->command_buffer, clear_attachments.size(), clear_attachments.ptr(), 1, &cr);
}
RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const Vector<RID> &p_storage_textures) {
@@ -7353,7 +7357,9 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
// If it is the first we're likely populating our VRS texture.
// Bit dirty but...
if (!texture || (!(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && !(i != 0 && texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT))) {
- color_count++;
+ if (!texture || !texture->is_resolve_buffer) {
+ color_count++;
+ }
}
}
ERR_FAIL_COND_V_MSG(p_clear_color_values.size() != color_count, INVALID_ID, "Clear color values supplied (" + itos(p_clear_color_values.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(color_count) + ").");
@@ -8993,6 +8999,25 @@ void RenderingDeviceVulkan::_begin_frame() {
frames[frame].index = Engine::get_singleton()->get_frames_drawn();
}
+VkSampleCountFlagBits RenderingDeviceVulkan::_ensure_supported_sample_count(TextureSamples p_requested_sample_count) const {
+ VkSampleCountFlags sample_count_flags = limits.framebufferColorSampleCounts & limits.framebufferDepthSampleCounts;
+
+ if (sample_count_flags & rasterization_sample_count[p_requested_sample_count]) {
+ // The requested sample count is supported.
+ return rasterization_sample_count[p_requested_sample_count];
+ } else {
+ // Find the closest lower supported sample count.
+ VkSampleCountFlagBits sample_count = rasterization_sample_count[p_requested_sample_count];
+ while (sample_count > VK_SAMPLE_COUNT_1_BIT) {
+ if (sample_count_flags & sample_count) {
+ return sample_count;
+ }
+ sample_count = (VkSampleCountFlagBits)(sample_count >> 1);
+ }
+ }
+ return VK_SAMPLE_COUNT_1_BIT;
+}
+
void RenderingDeviceVulkan::swap_buffers() {
ERR_FAIL_COND_MSG(local_device.is_valid(), "Local devices can't swap buffers.");
_THREAD_SAFE_METHOD_
@@ -9340,10 +9365,10 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de
// NOTE: If adding new project settings here, also duplicate their definition in
// rendering_server.cpp for headless doctool.
- staging_buffer_block_size = GLOBAL_DEF("rendering/vulkan/staging_buffer/block_size_kb", 256);
+ staging_buffer_block_size = GLOBAL_DEF("rendering/rendering_device/staging_buffer/block_size_kb", 256);
staging_buffer_block_size = MAX(4u, staging_buffer_block_size);
staging_buffer_block_size *= 1024; // Kb -> bytes.
- staging_buffer_max_size = GLOBAL_DEF("rendering/vulkan/staging_buffer/max_size_mb", 128);
+ staging_buffer_max_size = GLOBAL_DEF("rendering/rendering_device/staging_buffer/max_size_mb", 128);
staging_buffer_max_size = MAX(1u, staging_buffer_max_size);
staging_buffer_max_size *= 1024 * 1024;
@@ -9351,7 +9376,7 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de
// Validate enough blocks.
staging_buffer_max_size = staging_buffer_block_size * 4;
}
- texture_upload_region_size_px = GLOBAL_DEF("rendering/vulkan/staging_buffer/texture_upload_region_size_px", 64);
+ texture_upload_region_size_px = GLOBAL_DEF("rendering/rendering_device/staging_buffer/texture_upload_region_size_px", 64);
texture_upload_region_size_px = nearest_power_of_2_templated(texture_upload_region_size_px);
frames_drawn = frame_count; // Start from frame count, so everything else is immediately old.
@@ -9366,7 +9391,7 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de
ERR_CONTINUE(err != OK);
}
- max_descriptors_per_pool = GLOBAL_DEF("rendering/vulkan/descriptor_pools/max_descriptors_per_pool", 64);
+ max_descriptors_per_pool = GLOBAL_DEF("rendering/rendering_device/vulkan/max_descriptors_per_pool", 64);
// Check to make sure DescriptorPoolKey is good.
static_assert(sizeof(uint64_t) * 3 >= UNIFORM_TYPE_MAX * sizeof(uint16_t));
@@ -9661,6 +9686,10 @@ uint64_t RenderingDeviceVulkan::limit_get(Limit p_limit) const {
return limits.maxComputeWorkGroupSize[1];
case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z:
return limits.maxComputeWorkGroupSize[2];
+ case LIMIT_MAX_VIEWPORT_DIMENSIONS_X:
+ return limits.maxViewportDimensions[0];
+ case LIMIT_MAX_VIEWPORT_DIMENSIONS_Y:
+ return limits.maxViewportDimensions[1];
case LIMIT_SUBGROUP_SIZE: {
VulkanContext::SubgroupCapabilities subgroup_capabilities = context->get_subgroup_capabilities();
return subgroup_capabilities.size;