summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp179
1 files changed, 106 insertions, 73 deletions
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 84ca7dbfc2..f7c2fcb88a 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -3364,8 +3364,14 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
attachment_last_pass.resize(p_attachments.size());
Vector<VkAttachmentDescription> attachments;
+ Vector<int> attachment_remap;
for (int i = 0; i < p_attachments.size(); i++) {
+ if (p_attachments[i].usage_flags == AttachmentFormat::UNUSED_ATTACHMENT) {
+ attachment_remap.push_back(VK_ATTACHMENT_UNUSED);
+ continue;
+ }
+
ERR_FAIL_INDEX_V(p_attachments[i].format, DATA_FORMAT_MAX, VK_NULL_HANDLE);
ERR_FAIL_INDEX_V(p_attachments[i].samples, TEXTURE_SAMPLES_MAX, VK_NULL_HANDLE);
ERR_FAIL_COND_V_MSG(!(p_attachments[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)),
@@ -3567,7 +3573,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
}
attachment_last_pass[i] = -1;
-
+ attachment_remap.push_back(attachments.size());
attachments.push_back(description);
}
@@ -3612,7 +3618,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
} else {
ERR_FAIL_COND_V_MSG(texture_samples != p_attachments[attachment].samples, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), if an attachment is marked as multisample, all of them should be multisample and use the same number of samples.");
}
- reference.attachment = attachment;
+ reference.attachment = attachment_remap[attachment];
reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachment_last_pass[attachment] = i;
}
@@ -3631,7 +3637,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), input attachment (" + itos(j) + ").");
ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it isn't marked as an input texture.");
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
- reference.attachment = attachment;
+ reference.attachment = attachment_remap[attachment];
reference.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
attachment_last_pass[attachment] = i;
}
@@ -3657,7 +3663,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
bool multisample = p_attachments[attachment].samples > TEXTURE_SAMPLES_1;
ERR_FAIL_COND_V_MSG(multisample, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), resolve attachments can't be multisample.");
- reference.attachment = attachment;
+ reference.attachment = attachment_remap[attachment];
reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
attachment_last_pass[attachment] = i;
}
@@ -3671,7 +3677,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), depth attachment.");
ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it's marked as depth, but it's not a depth attachment.");
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
- depth_stencil_reference.attachment = attachment;
+ depth_stencil_reference.attachment = attachment_remap[attachment];
depth_stencil_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachment_last_pass[attachment] = i;
@@ -3958,14 +3964,13 @@ RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attac
for (int i = 0; i < p_texture_attachments.size(); i++) {
Texture *texture = texture_owner.get_or_null(p_texture_attachments[i]);
- ERR_FAIL_COND_V_MSG(!texture, RID(), "Texture index supplied for framebuffer (" + itos(i) + ") is not a valid texture.");
- ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer");
+ ERR_FAIL_COND_V_MSG(texture && texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer");
- if (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ if (texture && texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
pass.depth_attachment = i;
} else {
- pass.color_attachments.push_back(i);
+ pass.color_attachments.push_back(texture ? i : FramebufferPass::ATTACHMENT_UNUSED);
}
}
@@ -3979,29 +3984,35 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex
_THREAD_SAFE_METHOD_
Vector<AttachmentFormat> attachments;
+ attachments.resize(p_texture_attachments.size());
Size2i size;
-
+ bool size_set = false;
for (int i = 0; i < p_texture_attachments.size(); i++) {
+ AttachmentFormat af;
Texture *texture = texture_owner.get_or_null(p_texture_attachments[i]);
- ERR_FAIL_COND_V_MSG(!texture, RID(), "Texture index supplied for framebuffer (" + itos(i) + ") is not a valid texture.");
+ if (!texture) {
+ af.usage_flags = AttachmentFormat::UNUSED_ATTACHMENT;
+ } else {
+ ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer");
- ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer");
+ if (!size_set) {
+ size.width = texture->width;
+ size.height = texture->height;
+ size_set = true;
+ } else {
+ ERR_FAIL_COND_V_MSG((uint32_t)size.width != texture->width || (uint32_t)size.height != texture->height, RID(),
+ "All textures in a framebuffer should be the same size.");
+ }
- if (i == 0) {
- size.width = texture->width;
- size.height = texture->height;
- } else {
- ERR_FAIL_COND_V_MSG((uint32_t)size.width != texture->width || (uint32_t)size.height != texture->height, RID(),
- "All textures in a framebuffer should be the same size.");
+ af.format = texture->format;
+ af.samples = texture->samples;
+ af.usage_flags = texture->usage_flags;
}
-
- AttachmentFormat af;
- af.format = texture->format;
- af.samples = texture->samples;
- af.usage_flags = texture->usage_flags;
- attachments.push_back(af);
+ attachments.write[i] = af;
}
+ ERR_FAIL_COND_V_MSG(!size_set, RID(), "All attachments unused.");
+
FramebufferFormatID format_id = framebuffer_format_create_multipass(attachments, p_passes, p_view_count);
if (format_id == INVALID_ID) {
return RID();
@@ -4019,7 +4030,9 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex
RID id = framebuffer_owner.make_rid(framebuffer);
for (int i = 0; i < p_texture_attachments.size(); i++) {
- _add_dependency(id, p_texture_attachments[i]);
+ if (p_texture_attachments[i].is_valid()) {
+ _add_dependency(id, p_texture_attachments[i]);
+ }
}
return id;
@@ -6417,49 +6430,55 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
Vector<VkPipelineColorBlendAttachmentState> attachment_states;
{
const FramebufferPass &pass = fb_format.E->key().passes[p_for_render_pass];
-
+ attachment_states.resize(pass.color_attachments.size());
+ ERR_FAIL_COND_V(p_blend_state.attachments.size() < pass.color_attachments.size(), RID());
for (int i = 0; i < pass.color_attachments.size(); i++) {
- if (pass.color_attachments[i] != FramebufferPass::ATTACHMENT_UNUSED) {
- int idx = attachment_states.size();
-
- ERR_FAIL_INDEX_V(idx, p_blend_state.attachments.size(), RID());
- VkPipelineColorBlendAttachmentState state;
- state.blendEnable = p_blend_state.attachments[idx].enable_blend;
-
- ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].src_color_blend_factor, BLEND_FACTOR_MAX, RID());
- state.srcColorBlendFactor = blend_factors[p_blend_state.attachments[idx].src_color_blend_factor];
- ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].dst_color_blend_factor, BLEND_FACTOR_MAX, RID());
- state.dstColorBlendFactor = blend_factors[p_blend_state.attachments[idx].dst_color_blend_factor];
- ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].color_blend_op, BLEND_OP_MAX, RID());
- state.colorBlendOp = blend_operations[p_blend_state.attachments[idx].color_blend_op];
-
- ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].src_alpha_blend_factor, BLEND_FACTOR_MAX, RID());
- state.srcAlphaBlendFactor = blend_factors[p_blend_state.attachments[idx].src_alpha_blend_factor];
- ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].dst_alpha_blend_factor, BLEND_FACTOR_MAX, RID());
- state.dstAlphaBlendFactor = blend_factors[p_blend_state.attachments[idx].dst_alpha_blend_factor];
- ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].alpha_blend_op, BLEND_OP_MAX, RID());
- state.alphaBlendOp = blend_operations[p_blend_state.attachments[idx].alpha_blend_op];
+ VkPipelineColorBlendAttachmentState state;
+ if (pass.color_attachments[i] == FramebufferPass::ATTACHMENT_UNUSED) {
+ state.blendEnable = false;
+
+ state.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
+ state.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
+ state.colorBlendOp = VK_BLEND_OP_ADD;
+
+ state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
+ state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
+ state.alphaBlendOp = VK_BLEND_OP_ADD;
+
+ state.colorWriteMask = 0;
+ } else {
+ state.blendEnable = p_blend_state.attachments[i].enable_blend;
+
+ ERR_FAIL_INDEX_V(p_blend_state.attachments[i].src_color_blend_factor, BLEND_FACTOR_MAX, RID());
+ state.srcColorBlendFactor = blend_factors[p_blend_state.attachments[i].src_color_blend_factor];
+ ERR_FAIL_INDEX_V(p_blend_state.attachments[i].dst_color_blend_factor, BLEND_FACTOR_MAX, RID());
+ state.dstColorBlendFactor = blend_factors[p_blend_state.attachments[i].dst_color_blend_factor];
+ ERR_FAIL_INDEX_V(p_blend_state.attachments[i].color_blend_op, BLEND_OP_MAX, RID());
+ state.colorBlendOp = blend_operations[p_blend_state.attachments[i].color_blend_op];
+
+ ERR_FAIL_INDEX_V(p_blend_state.attachments[i].src_alpha_blend_factor, BLEND_FACTOR_MAX, RID());
+ state.srcAlphaBlendFactor = blend_factors[p_blend_state.attachments[i].src_alpha_blend_factor];
+ ERR_FAIL_INDEX_V(p_blend_state.attachments[i].dst_alpha_blend_factor, BLEND_FACTOR_MAX, RID());
+ state.dstAlphaBlendFactor = blend_factors[p_blend_state.attachments[i].dst_alpha_blend_factor];
+ ERR_FAIL_INDEX_V(p_blend_state.attachments[i].alpha_blend_op, BLEND_OP_MAX, RID());
+ state.alphaBlendOp = blend_operations[p_blend_state.attachments[i].alpha_blend_op];
state.colorWriteMask = 0;
- if (p_blend_state.attachments[idx].write_r) {
+ if (p_blend_state.attachments[i].write_r) {
state.colorWriteMask |= VK_COLOR_COMPONENT_R_BIT;
}
- if (p_blend_state.attachments[idx].write_g) {
+ if (p_blend_state.attachments[i].write_g) {
state.colorWriteMask |= VK_COLOR_COMPONENT_G_BIT;
}
- if (p_blend_state.attachments[idx].write_b) {
+ if (p_blend_state.attachments[i].write_b) {
state.colorWriteMask |= VK_COLOR_COMPONENT_B_BIT;
}
- if (p_blend_state.attachments[idx].write_a) {
+ if (p_blend_state.attachments[i].write_a) {
state.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT;
}
-
- attachment_states.push_back(state);
- idx++;
}
+ attachment_states.write[i] = state;
}
-
- ERR_FAIL_COND_V(attachment_states.size() != p_blend_state.attachments.size(), RID());
}
color_blend_state_create_info.attachmentCount = attachment_states.size();
@@ -6863,10 +6882,11 @@ Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebu
Vector<VkImageView> attachments;
for (int i = 0; i < p_framebuffer->texture_ids.size(); i++) {
Texture *texture = texture_owner.get_or_null(p_framebuffer->texture_ids[i]);
- ERR_FAIL_COND_V(!texture, ERR_BUG);
- attachments.push_back(texture->view);
- ERR_FAIL_COND_V(texture->width != p_framebuffer->size.width, ERR_BUG);
- ERR_FAIL_COND_V(texture->height != p_framebuffer->size.height, ERR_BUG);
+ if (texture) {
+ attachments.push_back(texture->view);
+ ERR_FAIL_COND_V(texture->width != p_framebuffer->size.width, ERR_BUG);
+ ERR_FAIL_COND_V(texture->height != p_framebuffer->size.height, ERR_BUG);
+ }
}
framebuffer_create_info.attachmentCount = attachments.size();
framebuffer_create_info.pAttachments = attachments.ptr();
@@ -6910,13 +6930,18 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
Vector<VkClearValue> clear_values;
clear_values.resize(framebuffer->texture_ids.size());
-
+ int clear_values_count = 0;
{
int color_index = 0;
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
- Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
VkClearValue clear_value;
+ Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
+ if (!texture) {
+ color_index++;
+ continue;
+ }
+
if (color_index < p_clear_colors.size() && texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
ERR_FAIL_INDEX_V(color_index, p_clear_colors.size(), ERR_BUG); //a bug
Color clear_color = p_clear_colors[color_index];
@@ -6934,15 +6959,18 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
clear_value.color.float32[2] = 0;
clear_value.color.float32[3] = 0;
}
- clear_values.write[i] = clear_value;
+ clear_values.write[clear_values_count++] = clear_value;
}
}
- render_pass_begin.clearValueCount = clear_values.size();
+ render_pass_begin.clearValueCount = clear_values_count;
render_pass_begin.pClearValues = clear_values.ptr();
for (int i = 0; i < p_storage_textures.size(); i++) {
Texture *texture = texture_owner.get_or_null(p_storage_textures[i]);
+ if (!texture) {
+ continue;
+ }
ERR_CONTINUE_MSG(!(texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT), "Supplied storage texture " + itos(i) + " for draw list is not set to be used for storage.");
if (texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT) {
@@ -6981,6 +7009,9 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
+ if (!texture) {
+ continue;
+ }
texture->bound = true;
draw_list_bound_textures.push_back(framebuffer->texture_ids[i]);
}
@@ -6989,15 +7020,21 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
}
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) {
+ ERR_FAIL_COND_MSG(p_clear_color && p_clear_colors.size() != framebuffer->texture_ids.size(), "Clear color values supplied (" + itos(p_clear_colors.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(framebuffer->texture_ids.size()) + ").");
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]);
- VkClearAttachment clear_at = {};
+ if (!texture) {
+ texture_index++;
+ continue;
+ }
+
+ VkClearAttachment clear_at = {};
if (p_clear_color && texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- ERR_FAIL_INDEX(color_index, p_clear_colors.size()); //a bug
- Color clear_color = p_clear_colors[color_index];
+ Color clear_color = p_clear_colors[texture_index++];
clear_at.clearValue.color.float32[0] = clear_color.r;
clear_at.clearValue.color.float32[1] = clear_color.g;
clear_at.clearValue.color.float32[2] = clear_color.b;
@@ -7073,18 +7110,14 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
}
if (p_initial_color_action == INITIAL_ACTION_CLEAR) { //check clear values
-
int color_count = 0;
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
-
- if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ if (!texture || !(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
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) + ").");
+ 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) + ").");
}
VkFramebuffer vkframebuffer;
@@ -7176,7 +7209,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
- if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ if (!texture || !(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
color_count++;
}
}