mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 04:31:35 +00:00
[vulkan] Enable synchronization validation
And clean up the resulting errors. While some were tricky, there weren't all that many: just some attachment issues and the multi-stage image copy for scraps. Fixing scraps required a barrier between copies. It might be overkill, but a transfer_dst to transfer_dst image barrier worked. Fixing attachments was a bit trickier: - depth needed early and late fragment tests to be treated as one stage - all attachments that were read later needed storeOp = none (using the extension) - and then finalLayout needed to be correct to avoid ghost transitions - as well, for some reason the deffered gbuffer subpass needed a depth dependency on the translucent pass even though neither one writes to the depth attachment (possibly a validation bug, needs more investigation).
This commit is contained in:
parent
2203e2b4fd
commit
17b00a3d05
8 changed files with 58 additions and 38 deletions
|
@ -23,6 +23,7 @@ enum {
|
|||
qfv_LT_Undefined_to_TransferDst,
|
||||
qfv_LT_Undefined_to_General,
|
||||
qfv_LT_Undefined_to_ShaderReadOnly,
|
||||
qfv_LT_TransferDst_to_TransferDst,
|
||||
qfv_LT_TransferDst_to_TransferSrc,
|
||||
qfv_LT_TransferDst_to_General,
|
||||
qfv_LT_TransferDst_to_ShaderReadOnly,
|
||||
|
|
|
@ -70,6 +70,19 @@ const qfv_imagebarrier_t imageBarriers[] = {
|
|||
{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
|
||||
},
|
||||
},
|
||||
[qfv_LT_TransferDst_to_TransferDst] = {
|
||||
.srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
.dstStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
.barrier = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, 0,
|
||||
{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
|
||||
},
|
||||
},
|
||||
[qfv_LT_TransferDst_to_TransferSrc] = {
|
||||
.srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
.dstStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
|
|
|
@ -217,6 +217,7 @@ QFV_CreateInstance (vulkan_ctx_t *ctx,
|
|||
};
|
||||
VkValidationFeatureEnableEXT valfeat_enable[] = {
|
||||
// VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT,
|
||||
VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
|
||||
};
|
||||
#define valfeat_count sizeof(valfeat_enable)/sizeof(valfeat_enable[0])
|
||||
VkValidationFeaturesEXT validation_features= {
|
||||
|
|
|
@ -191,6 +191,8 @@ QFV_RunRenderPassCmd (VkCommandBuffer cmd, vulkan_ctx_t *ctx,
|
|||
//the attachments won't be transitioned correctly.
|
||||
//However, only if not the last (or only) subpass.
|
||||
if (i < rp->subpass_count - 1) {
|
||||
//auto np = &rp->subpasses[i + 1];
|
||||
//printf ("%s -> %s\n", sp->label.name, np->label.name);
|
||||
dfunc->vkCmdNextSubpass (cmd, rp->subpassContents);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,11 +27,11 @@ properties = {
|
|||
};
|
||||
depth_dependency = {
|
||||
src = {
|
||||
stage = late_fragment_tests;
|
||||
stage = early_fragment_tests|late_fragment_tests;
|
||||
access = depth_stencil_attachment_write;
|
||||
};
|
||||
dst = {
|
||||
stage = fragment_shader|early_fragment_tests;
|
||||
stage = fragment_shader|early_fragment_tests|late_fragment_tests;
|
||||
access = input_attachment_read|depth_stencil_attachment_read;
|
||||
};
|
||||
flags = by_region;
|
||||
|
@ -83,13 +83,19 @@ properties = {
|
|||
attachment_base = {
|
||||
samples = 1;
|
||||
loadOp = dont_care;
|
||||
storeOp = dont_care;
|
||||
storeOp = none_ext;
|
||||
stencilLoadOp = dont_care;
|
||||
stencilStoreOp = dont_care;
|
||||
stencilStoreOp = none_ext;
|
||||
initialLayout = undefined;
|
||||
finalLayout = color_attachment_optimal;
|
||||
finalLayout = shader_read_only_optimal;
|
||||
clearValue = { color = "[0, 0, 0, 1]"; };
|
||||
};
|
||||
depth_base = {
|
||||
@inherit = $attachment_base;
|
||||
loadOp = clear;
|
||||
finalLayout = depth_stencil_read_only_optimal;
|
||||
clearValue = { depthStencil = { depth = 0; stencil = 0; }; };
|
||||
};
|
||||
|
||||
no_cull = {
|
||||
depthClampEnable = false;
|
||||
|
@ -1324,11 +1330,8 @@ renderpasses = {
|
|||
layers = 1;
|
||||
attachments = {
|
||||
depth = {
|
||||
@inherit = $attachment_base;
|
||||
@inherit = $depth_base;
|
||||
format = $images.depth.format;
|
||||
loadOp = clear;
|
||||
finalLayout = depth_stencil_attachment_optimal;
|
||||
clearValue = { depthStencil = { depth = 0; stencil = 0; }; };
|
||||
view = occlusion_depth;
|
||||
};
|
||||
};
|
||||
|
@ -1426,11 +1429,8 @@ renderpasses = {
|
|||
layers = 1;
|
||||
attachments = {
|
||||
depth = {
|
||||
@inherit = $attachment_base;
|
||||
@inherit = $depth_base;
|
||||
format = $images.cube_depth.format;
|
||||
loadOp = clear;
|
||||
finalLayout = depth_stencil_attachment_optimal;
|
||||
clearValue = { depthStencil = { depth = 0; stencil = 0; }; };
|
||||
view = occlusion_cube_depth;
|
||||
};
|
||||
};
|
||||
|
@ -1444,11 +1444,8 @@ renderpasses = {
|
|||
layers = 1;
|
||||
attachments = {
|
||||
depth = {
|
||||
@inherit = $attachment_base;
|
||||
@inherit = $depth_base;
|
||||
format = $images.depth.format;
|
||||
loadOp = clear;
|
||||
finalLayout = depth_stencil_attachment_optimal;
|
||||
clearValue = { depthStencil = { depth = 0; stencil = 0; }; };
|
||||
view = depth;
|
||||
};
|
||||
color = {
|
||||
|
@ -1704,6 +1701,7 @@ renderpasses = {
|
|||
color = "[ 0.3, 0.7, 0.3, 1]";
|
||||
dependencies = {
|
||||
depth = $depth_dependency;
|
||||
translucent = $depth_dependency;//FIXME why?
|
||||
};
|
||||
attachments = {
|
||||
color = {
|
||||
|
@ -2051,11 +2049,8 @@ renderpasses = {
|
|||
layers = 1;
|
||||
attachments = {
|
||||
depth = {
|
||||
@inherit = $attachment_base;
|
||||
@inherit = $depth_base;
|
||||
format = $images.cube_depth.format;
|
||||
loadOp = clear;
|
||||
finalLayout = depth_stencil_attachment_optimal;
|
||||
clearValue = { depthStencil = { depth = 0; stencil = 0; }; };
|
||||
view = cube_depth;
|
||||
};
|
||||
color = {
|
||||
|
|
|
@ -27,11 +27,11 @@ properties = {
|
|||
};
|
||||
depth_dependency = {
|
||||
src = {
|
||||
stage = late_fragment_tests;
|
||||
stage = early_fragment_tests|late_fragment_tests;
|
||||
access = depth_stencil_attachment_write;
|
||||
};
|
||||
dst = {
|
||||
stage = fragment_shader|early_fragment_tests;
|
||||
stage = fragment_shader|early_fragment_tests|late_fragment_tests;
|
||||
access = input_attachment_read|depth_stencil_attachment_read;
|
||||
};
|
||||
flags = by_region;
|
||||
|
@ -84,13 +84,19 @@ properties = {
|
|||
attachment_base = {
|
||||
samples = 1;
|
||||
loadOp = dont_care;
|
||||
storeOp = dont_care;
|
||||
storeOp = none_ext;
|
||||
stencilLoadOp = dont_care;
|
||||
stencilStoreOp = dont_care;
|
||||
stencilStoreOp = none_ext;
|
||||
initialLayout = undefined;
|
||||
finalLayout = color_attachment_optimal;
|
||||
finalLayout = shader_read_only_optimal;
|
||||
clearValue = { color = "[0, 0, 0, 1]"; };
|
||||
};
|
||||
depth_base = {
|
||||
@inherit = $attachment_base;
|
||||
loadOp = clear;
|
||||
finalLayout = depth_stencil_read_only_optimal;
|
||||
clearValue = { depthStencil = { depth = 0; stencil = 0; }; };
|
||||
};
|
||||
|
||||
no_cull = {
|
||||
depthClampEnable = false;
|
||||
|
@ -1062,19 +1068,14 @@ renderpasses = {
|
|||
layers = 1;
|
||||
attachments = {
|
||||
depth = {
|
||||
@inherit = $attachment_base;
|
||||
@inherit = $depth_base;
|
||||
format = $images.depth.format;
|
||||
loadOp = clear;
|
||||
finalLayout = depth_stencil_attachment_optimal;
|
||||
clearValue = { depthStencil = { depth = 0; stencil = 0; }; };
|
||||
view = depth;
|
||||
};
|
||||
color = {
|
||||
@inherit = $attachment_base;
|
||||
format = $images.color.format;
|
||||
loadOp = clear;
|
||||
storeOp = store;
|
||||
finalLayout = $render_output.finalLayout;
|
||||
view = color;
|
||||
};
|
||||
output = {
|
||||
|
@ -1299,11 +1300,8 @@ renderpasses = {
|
|||
layers = 1;
|
||||
attachments = {
|
||||
depth = {
|
||||
@inherit = $attachment_base;
|
||||
@inherit = $depth_base;
|
||||
format = $images.cube_depth.format;
|
||||
loadOp = clear;
|
||||
finalLayout = depth_stencil_attachment_optimal;
|
||||
clearValue = { depthStencil = { depth = 0; stencil = 0; }; };
|
||||
view = cube_depth;
|
||||
};
|
||||
color = {
|
||||
|
|
|
@ -311,11 +311,14 @@ QFV_ScrapFlush (scrap_t *scrap)
|
|||
0, 0, 0, 0, 0,
|
||||
1, &ib.barrier);
|
||||
|
||||
size_t offset = packet->offset, size;
|
||||
auto sb = imageBarriers[qfv_LT_TransferDst_to_TransferDst];
|
||||
sb.barrier.image = scrap->image;
|
||||
|
||||
size_t offset = packet->offset;
|
||||
vrect_t *batch = scrap->batch;
|
||||
while (scrap->batch_count) {
|
||||
for (i = 0; i < scrap->batch_count && i < 128; i++) {
|
||||
size = batch->width * batch->height * scrap->bpp;
|
||||
size_t size = batch->width * batch->height * scrap->bpp;
|
||||
|
||||
copy->a[i].bufferOffset = offset;
|
||||
copy->a[i].imageOffset.x = batch->x;
|
||||
|
@ -330,6 +333,12 @@ QFV_ScrapFlush (scrap_t *scrap)
|
|||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
i, copy->a);
|
||||
scrap->batch_count -= i;
|
||||
if (scrap->batch_count) {
|
||||
dfunc->vkCmdPipelineBarrier (packet->cmd,
|
||||
sb.srcStages, sb.dstStages,
|
||||
0, 0, 0, 0, 0,
|
||||
1, &sb.barrier);
|
||||
}
|
||||
}
|
||||
|
||||
ib = imageBarriers[qfv_LT_TransferDst_to_ShaderReadOnly];
|
||||
|
|
|
@ -97,6 +97,7 @@ static const char *instance_extensions[] = {
|
|||
|
||||
static const char *device_extensions[] = {
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||
VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME,
|
||||
#ifdef TRACY_ENABLE
|
||||
VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME,
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue