Factor out window-specific and related resources separately in tests

* This will let us run multiple windows (and multiple threads) relatively
  easily.
* The hammer is fairly big, we move some things into the window that don't need
  to be there necessarily if we have multiple windows on a single thread, but it
  keeps things simple.
This commit is contained in:
baldurk committed 2019-05-24 19:57:13 +01:00
1 parent 42f074187c
commit 3c4dbaca30
19 files changed
+453 -335

No files matched your search

+4 -4
View File
@@ -283,7 +283,7 @@ void main()
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = swapRenderPass;
pipeCreateInfo.renderPass = mainWindow->rp;
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
@@ -377,13 +377,13 @@ void main()
vkh::ImageSubresourceRange());
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor,
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor,
{vkh::ClearValue(0.0f, 0.0f, 0.0f, 1.0f)}),
VK_SUBPASS_CONTENTS_INLINE);
vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, {descset}, {});
vkCmdSetViewport(cmd, 0, 1, &viewport);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
+4 -4
View File
@@ -148,7 +148,7 @@ void main()
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = swapRenderPass;
pipeCreateInfo.renderPass = mainWindow->rp;
pipeCreateInfo.stages = {
CompileShaderModule(common + vertex, ShaderLang::glsl, ShaderStage::vert, "main"),
@@ -237,12 +237,12 @@ void main()
vkh::ImageSubresourceRange());
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
vkCmdSetViewport(cmd, 0, 1, &viewport);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
// look ma, no binds
DrawData *bindptr = drawsgpu;
+10 -9
View File
@@ -501,10 +501,11 @@ float4 main() : SV_Target0
VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo({setlayout}));
AllocatedImage img(allocator, vkh::ImageCreateInfo(scissor.extent.width, scissor.extent.height,
0, VK_FORMAT_R32G32B32A32_SFLOAT,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
AllocatedImage img(
allocator,
vkh::ImageCreateInfo(mainWindow->scissor.extent.width, mainWindow->scissor.extent.height, 0,
VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
VkImageView imgview = createImageView(
vkh::ImageViewCreateInfo(img.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R32G32B32A32_SFLOAT));
@@ -519,8 +520,8 @@ float4 main() : SV_Target0
VkRenderPass renderPass = createRenderPass(renderPassCreateInfo);
VkFramebuffer framebuffer =
createFramebuffer(vkh::FramebufferCreateInfo(renderPass, {imgview}, scissor.extent));
VkFramebuffer framebuffer = createFramebuffer(
vkh::FramebufferCreateInfo(renderPass, {imgview}, mainWindow->scissor.extent));
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
@@ -603,13 +604,13 @@ float4 main() : SV_Target0
vkh::ClearColorValue(0.4f, 0.5f, 0.6f, 1.0f), 1,
vkh::ImageSubresourceRange());
vkCmdBeginRenderPass(cmd, vkh::RenderPassBeginInfo(renderPass, framebuffer, scissor,
vkCmdBeginRenderPass(cmd, vkh::RenderPassBeginInfo(renderPass, framebuffer, mainWindow->scissor,
{vkh::ClearValue(0.0f, 0.0f, 0.0f, 1.0f)}),
VK_SUBPASS_CONTENTS_INLINE);
vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, {descset}, {});
vkCmdSetViewport(cmd, 0, 1, &viewport);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, glslpipe);
+4 -4
View File
@@ -293,7 +293,7 @@ void main()
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = swapRenderPass;
pipeCreateInfo.renderPass = mainWindow->rp;
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
@@ -544,7 +544,7 @@ void main()
ssbo.buffer)});
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
@@ -557,8 +557,8 @@ void main()
// bind the actual one
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, 1, &descset[0], 0,
NULL);
vkCmdSetViewport(cmd, 0, 1, &viewport);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
idx = {BUFIDX, 0, 0, 0};
vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT, 0,
+6 -6
View File
@@ -92,8 +92,8 @@ void main()
vkGetPhysicalDeviceProperties2KHR(phys, vkh::PhysicalDeviceProperties2KHR().next(&discardProps));
const int32_t w = (int32_t)scissor.extent.width;
const int32_t h = (int32_t)scissor.extent.height;
const int32_t w = (int32_t)mainWindow->scissor.extent.width;
const int32_t h = (int32_t)mainWindow->scissor.extent.height;
VkRect2D discardRects[] = {
// TL eye
@@ -118,7 +118,7 @@ void main()
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = swapRenderPass;
pipeCreateInfo.renderPass = mainWindow->rp;
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
@@ -176,16 +176,16 @@ void main()
vkh::ImageSubresourceRange());
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
VK_SUBPASS_CONTENTS_INLINE);
VkViewport view = viewport;
VkViewport view = mainWindow->viewport;
view.width /= 2.0f;
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
vkCmdSetDiscardRectangleEXT(cmd, 0, ARRAY_COUNT(discardRects), discardRects);
vkCmdSetViewport(cmd, 0, 1, &view);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdDraw(cmd, 3000, 1, 0, 0);
+4 -4
View File
@@ -92,7 +92,7 @@ void main()
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = swapRenderPass;
pipeCreateInfo.renderPass = mainWindow->rp;
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
@@ -319,12 +319,12 @@ void main()
vkh::ImageSubresourceRange());
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
VkViewport vp = viewport;
VkViewport vp = mainWindow->viewport;
vp.width = 48.0f;
vp.height = 48.0f;
+14 -12
View File
@@ -174,7 +174,7 @@ void main()
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = drawlayout;
pipeCreateInfo.renderPass = swapRenderPass;
pipeCreateInfo.renderPass = mainWindow->rp;
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
@@ -278,6 +278,8 @@ void main()
VkImage swapimg =
StartUsingBackbuffer(primary, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
setMarker(primary, "Do Clear");
vkCmdClearColorImage(primary, swapimg, VK_IMAGE_LAYOUT_GENERAL,
vkh::ClearColorValue(0.4f, 0.5f, 0.6f, 1.0f), 1,
vkh::ImageSubresourceRange());
@@ -323,16 +325,16 @@ void main()
VK_ACCESS_INDIRECT_COMMAND_READ_BIT, ssbo.buffer)});
}
vkCmdBeginRenderPass(
primary, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBeginRenderPass(primary, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(),
mainWindow->scissor),
VK_SUBPASS_CONTENTS_INLINE);
{
VkCommandBuffer cmd = primary;
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, drawpipe);
vkCmdSetViewport(cmd, 0, 1, &viewport);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdBindIndexBuffer(cmd, ib.buffer, 0, VK_INDEX_TYPE_UINT32);
@@ -454,22 +456,22 @@ void main()
vkCmdExecuteCommands(primary, 1, &dispatch_secondary);
vkCmdBeginRenderPass(
primary, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
vkCmdBeginRenderPass(primary, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(),
mainWindow->scissor),
VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
VkCommandBuffer draw_secondary = GetCommandBuffer(VK_COMMAND_BUFFER_LEVEL_SECONDARY);
vkBeginCommandBuffer(draw_secondary, vkh::CommandBufferBeginInfo(
VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
vkh::CommandBufferInheritanceInfo(swapRenderPass, 0)));
vkh::CommandBufferInheritanceInfo(mainWindow->rp, 0)));
{
VkCommandBuffer cmd = draw_secondary;
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, drawpipe);
vkCmdSetViewport(cmd, 0, 1, &viewport);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdBindIndexBuffer(cmd, ib.buffer, 0, VK_INDEX_TYPE_UINT32);
+17 -17
View File
@@ -150,11 +150,11 @@ void main()
vb.upload(VBData);
// create depth-stencil image
AllocatedImage depthimg(allocator,
vkh::ImageCreateInfo(scissor.extent.width, scissor.extent.height, 0,
VK_FORMAT_D32_SFLOAT_S8_UINT,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
AllocatedImage depthimg(
allocator, vkh::ImageCreateInfo(
mainWindow->scissor.extent.width, mainWindow->scissor.extent.height, 0,
VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
VkImageView dsvview = createImageView(vkh::ImageViewCreateInfo(
depthimg.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D32_SFLOAT_S8_UINT, {},
@@ -163,8 +163,8 @@ void main()
// create renderpass using the DS image
vkh::RenderPassCreator renderPassCreateInfo;
renderPassCreateInfo.attachments.push_back(
vkh::AttachmentDescription(swapFormat, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
renderPassCreateInfo.attachments.push_back(vkh::AttachmentDescription(
mainWindow->format, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
renderPassCreateInfo.attachments.push_back(vkh::AttachmentDescription(
VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_SAMPLE_COUNT_1_BIT,
@@ -177,11 +177,11 @@ void main()
// create framebuffers using swapchain images and DS image
std::vector<VkFramebuffer> fbs;
fbs.resize(swapImageViews.size());
fbs.resize(mainWindow->GetCount());
for(size_t i = 0; i < swapImageViews.size(); i++)
fbs[i] = createFramebuffer(
vkh::FramebufferCreateInfo(renderPass, {swapImageViews[i], dsvview}, scissor.extent));
for(size_t i = 0; i < mainWindow->GetCount(); i++)
fbs[i] = createFramebuffer(vkh::FramebufferCreateInfo(
renderPass, {mainWindow->GetView(i), dsvview}, mainWindow->scissor.extent));
// create PSO
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
@@ -236,23 +236,23 @@ void main()
VkImage swapimg =
StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
VkViewport v = viewport;
VkViewport v = mainWindow->viewport;
v.x += 10.0f;
v.y += 10.0f;
v.width -= 20.0f;
v.height -= 20.0f;
vkCmdSetViewport(cmd, 0, 1, &v);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
vkh::ClearColorValue(0.4f, 0.5f, 0.6f, 1.0f), 1,
vkh::ImageSubresourceRange());
vkCmdBeginRenderPass(cmd,
vkh::RenderPassBeginInfo(renderPass, fbs[swapIndex], scissor,
{vkh::ClearValue(), vkh::ClearValue(1.0f, 0)}),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(renderPass, fbs[mainWindow->imgIndex], mainWindow->scissor,
{vkh::ClearValue(), vkh::ClearValue(1.0f, 0)}),
VK_SUBPASS_CONTENTS_INLINE);
// draw the setup triangles
+7 -5
View File
@@ -112,7 +112,7 @@ void main()
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = swapRenderPass;
pipeCreateInfo.renderPass = mainWindow->rp;
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
@@ -465,7 +465,7 @@ void main()
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
@@ -473,7 +473,7 @@ void main()
NULL);
VkViewport view = {0, 0, 128, 128, 0, 1};
vkCmdSetViewport(cmd, 0, 1, &view);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdDraw(cmd, 3, 1, 0, 0);
@@ -506,7 +506,7 @@ void main()
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
@@ -514,7 +514,7 @@ void main()
NULL);
VkViewport view = {128, 0, 128, 128, 0, 1};
vkCmdSetViewport(cmd, 0, 1, &view);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdDraw(cmd, 3, 1, 0, 0);
@@ -555,6 +555,8 @@ void main()
Present();
}
vkDeviceWaitIdle(device);
// destroy resources
TrashBuffer(cb, cbmem);
TrashImage(img, imgmem, imgview);
+23 -19
View File
@@ -99,23 +99,25 @@ void main()
// create multi-sampled image
AllocatedImage msaaimg(
allocator,
vkh::ImageCreateInfo(scissor.extent.width, scissor.extent.height, 0, swapFormat,
vkh::ImageCreateInfo(mainWindow->scissor.extent.width, mainWindow->scissor.extent.height, 0,
mainWindow->format,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT,
1, 1, VK_SAMPLE_COUNT_4_BIT),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
VkImageView msview =
createImageView(vkh::ImageViewCreateInfo(msaaimg.image, VK_IMAGE_VIEW_TYPE_2D, swapFormat));
VkImageView msview = createImageView(
vkh::ImageViewCreateInfo(msaaimg.image, VK_IMAGE_VIEW_TYPE_2D, mainWindow->format));
// create renderpass using the DS image
vkh::RenderPassCreator renderPassCreateInfo;
renderPassCreateInfo.attachments.push_back(vkh::AttachmentDescription(
swapFormat, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE, VK_SAMPLE_COUNT_4_BIT));
renderPassCreateInfo.attachments.push_back(
vkh::AttachmentDescription(swapFormat, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
mainWindow->format, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ATTACHMENT_LOAD_OP_CLEAR,
VK_ATTACHMENT_STORE_OP_STORE, VK_SAMPLE_COUNT_4_BIT));
renderPassCreateInfo.attachments.push_back(vkh::AttachmentDescription(
mainWindow->format, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
renderPassCreateInfo.addSubpass(
{VkAttachmentReference({0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL})}, VK_ATTACHMENT_UNUSED,
@@ -125,11 +127,11 @@ void main()
// create framebuffers using swapchain images and DS image
std::vector<VkFramebuffer> fbs;
fbs.resize(swapImageViews.size());
fbs.resize(mainWindow->GetCount());
for(size_t i = 0; i < swapImageViews.size(); i++)
fbs[i] = createFramebuffer(
vkh::FramebufferCreateInfo(renderPass, {msview, swapImageViews[i]}, scissor.extent));
for(size_t i = 0; i < mainWindow->GetCount(); i++)
fbs[i] = createFramebuffer(vkh::FramebufferCreateInfo(
renderPass, {msview, mainWindow->GetView(i)}, mainWindow->scissor.extent));
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
@@ -199,10 +201,10 @@ void main()
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, msaaimg.image),
});
VkRect2D region = scissor;
VkRect2D region = mainWindow->scissor;
region.extent.width /= 2;
VkViewport view = viewport;
VkViewport view = mainWindow->viewport;
view.width /= 2.0f;
VkRenderPassSampleLocationsBeginInfoEXT sampleBegin = {
@@ -254,9 +256,10 @@ void main()
sampleBegin.postSubpassSampleLocationsCount = 1;
sampleBegin.pPostSubpassSampleLocations = &subpassSamples;
vkCmdBeginRenderPass(cmd, vkh::RenderPassBeginInfo(renderPass, fbs[swapIndex], region,
{vkh::ClearValue(0.0f, 0.0f, 0.0f, 1.0f)})
.next(&sampleBegin),
vkCmdBeginRenderPass(cmd,
vkh::RenderPassBeginInfo(renderPass, fbs[mainWindow->imgIndex], region,
{vkh::ClearValue(0.0f, 0.0f, 0.0f, 1.0f)})
.next(&sampleBegin),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
@@ -274,9 +277,10 @@ void main()
subpassSamples.sampleLocationsInfo.pSampleLocations = locations2;
vkCmdBeginRenderPass(cmd, vkh::RenderPassBeginInfo(renderPass, fbs[swapIndex], region,
{vkh::ClearValue(0.0f, 0.0f, 0.0f, 1.0f)})
.next(&sampleBegin),
vkCmdBeginRenderPass(cmd,
vkh::RenderPassBeginInfo(renderPass, fbs[mainWindow->imgIndex], region,
{vkh::ClearValue(0.0f, 0.0f, 0.0f, 1.0f)})
.next(&sampleBegin),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
+5 -5
View File
@@ -80,7 +80,7 @@ void main()
VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo());
VkRect2D size = scissor;
VkRect2D size = mainWindow->scissor;
AllocatedImage img(
allocator,
@@ -162,7 +162,7 @@ void main()
vkh::CommandBufferInheritanceInfo(renderPass, 1)));
vkCmdBindPipeline(cmd2, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe1);
vkCmdSetViewport(cmd2, 0, 1, &viewport);
vkCmdSetViewport(cmd2, 0, 1, &mainWindow->viewport);
vkCmdSetScissor(cmd2, 0, 1, &size);
vkh::cmdBindVertexBuffers(cmd2, 0, {vb.buffer}, {sizeof(DefaultA2V) * 3});
@@ -188,7 +188,7 @@ void main()
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe0);
vkCmdSetViewport(cmd, 0, 1, &viewport);
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
vkCmdSetScissor(cmd, 0, 1, &size);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
@@ -218,8 +218,8 @@ void main()
region.srcOffsets[1].x = size.extent.width;
region.srcOffsets[1].y = size.extent.height;
region.srcOffsets[1].z = 1;
region.dstOffsets[1].x = scissor.extent.width;
region.dstOffsets[1].y = scissor.extent.height;
region.dstOffsets[1].x = mainWindow->scissor.extent.width;
region.dstOffsets[1].y = mainWindow->scissor.extent.height;
region.dstOffsets[1].z = 1;
vkCmdBlitImage(cmd, img.image, VK_IMAGE_LAYOUT_GENERAL, swapimg, VK_IMAGE_LAYOUT_GENERAL, 1,
+4 -4
View File
@@ -85,7 +85,7 @@ void main()
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = swapRenderPass;
pipeCreateInfo.renderPass = mainWindow->rp;
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
@@ -121,12 +121,12 @@ void main()
vkh::ImageSubresourceRange());
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
vkCmdSetViewport(cmd, 0, 1, &viewport);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdDraw(cmd, 3, 1, 0, 0);
@@ -207,7 +207,7 @@ float4 main() : SV_Target0
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = swapRenderPass;
pipeCreateInfo.renderPass = mainWindow->rp;
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
@@ -299,13 +299,13 @@ float4 main() : SV_Target0
});
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, glslpipe);
vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, {descset}, {});
vkCmdSetViewport(cmd, 0, 1, &viewport);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdDraw(cmd, 3, 1, 0, 0);
@@ -320,7 +320,7 @@ float4 main() : SV_Target0
});
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, hlslpipe);
+252 -186
View File
@@ -381,13 +381,18 @@ bool VulkanGraphicsTest::Init()
VkQueueFlags required = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
for(uint32_t q = 0; q < queueProps.size(); q++)
// if no queue has been selected, find it now
if(queueFamilyIndex == ~0U)
{
VkQueueFlags flags = queueProps[q].queueFlags;
if((flags & required) == required)
for(uint32_t q = 0; q < queueProps.size(); q++)
{
queueFamilyIndex = q;
break;
VkQueueFlags flags = queueProps[q].queueFlags;
if((flags & required) == required)
{
queueFamilyIndex = q;
queueCount = 1;
break;
}
}
}
@@ -397,16 +402,6 @@ bool VulkanGraphicsTest::Init()
return false;
}
mainWindow = MakeWindow(screenWidth, screenHeight, "Autotesting");
VkResult vkr = (VkResult)CreateSurface(mainWindow, &surface);
if(vkr != VK_SUCCESS)
{
TEST_ERROR("Error creating surface: %s", vkh::result_str(vkr));
return false;
};
std::vector<VkExtensionProperties> supportedExts;
CHECK_VKR(vkh::enumerateDeviceExtensionProperties(supportedExts, phys, NULL));
@@ -427,26 +422,22 @@ bool VulkanGraphicsTest::Init()
devExts.push_back(search);
}
CHECK_VKR(vkCreateDevice(phys,
vkh::DeviceCreateInfo({vkh::DeviceQueueCreateInfo(queueFamilyIndex, 1)},
enabledLayers, devExts, features)
.next(devInfoNext),
NULL, &device));
CHECK_VKR(vkCreateDevice(
phys, vkh::DeviceCreateInfo({vkh::DeviceQueueCreateInfo(queueFamilyIndex, queueCount)},
enabledLayers, devExts, features)
.next(devInfoNext),
NULL, &device));
volkLoadDevice(device);
vkGetDeviceQueue(device, queueFamilyIndex, 0, &queue);
mainWindow = MakeWindow(screenWidth, screenHeight, "Autotesting");
CHECK_VKR(vkCreateSemaphore(device, vkh::SemaphoreCreateInfo(), NULL, &renderStartSemaphore));
CHECK_VKR(vkCreateSemaphore(device, vkh::SemaphoreCreateInfo(), NULL, &renderEndSemaphore));
CHECK_VKR(vkCreateCommandPool(
device, vkh::CommandPoolCreateInfo(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT), NULL,
&cmdPool));
createSwap();
acquireImage();
if(!mainWindow->Initialised())
{
TEST_ERROR("Error creating surface");
return false;
};
VmaVulkanFunctions funcs = {
vkGetPhysicalDeviceProperties,
@@ -472,7 +463,7 @@ bool VulkanGraphicsTest::Init()
VmaAllocatorCreateInfo allocInfo = {};
allocInfo.physicalDevice = phys;
allocInfo.device = device;
allocInfo.frameInUseCount = uint32_t(swapImages.size() - 1);
allocInfo.frameInUseCount = 4;
allocInfo.pVulkanFunctions = &funcs;
vmaCreateAllocator(&allocInfo, &allocator);
@@ -485,13 +476,15 @@ bool VulkanGraphicsTest::Init()
return true;
}
GraphicsWindow *VulkanGraphicsTest::MakeWindow(int width, int height, const char *title)
VulkanWindow *VulkanGraphicsTest::MakeWindow(int width, int height, const char *title)
{
#if defined(WIN32)
return new Win32Window(width, height, title);
GraphicsWindow *platWin = new Win32Window(width, height, title);
#else
return new X11Window(width, height, title);
GraphicsWindow *platWin = new X11Window(width, height, title);
#endif
return new VulkanWindow(this, platWin);
}
void VulkanGraphicsTest::Shutdown()
@@ -502,9 +495,6 @@ void VulkanGraphicsTest::Shutdown()
{
vkDeviceWaitIdle(device);
for(VkFence fence : fences)
vkDestroyFence(device, fence, NULL);
for(VkShaderModule shader : shaders)
vkDestroyShaderModule(device, shader, NULL);
@@ -532,24 +522,16 @@ void VulkanGraphicsTest::Shutdown()
for(VkDescriptorSetLayout layout : setlayouts)
vkDestroyDescriptorSetLayout(device, layout, NULL);
vkDestroyCommandPool(device, cmdPool, NULL);
vkDestroySemaphore(device, renderStartSemaphore, NULL);
vkDestroySemaphore(device, renderEndSemaphore, NULL);
destroySwap();
delete mainWindow;
vkDestroyDevice(device, NULL);
}
if(debugUtilsMessenger)
vkDestroyDebugUtilsMessengerEXT(instance, debugUtilsMessenger, NULL);
if(surface)
vkDestroySurfaceKHR(instance, surface, NULL);
if(instance)
vkDestroyInstance(instance, NULL);
delete mainWindow;
}
bool VulkanGraphicsTest::Running()
@@ -561,9 +543,12 @@ bool VulkanGraphicsTest::Running()
}
VkImage VulkanGraphicsTest::StartUsingBackbuffer(VkCommandBuffer cmd, VkAccessFlags nextUse,
VkImageLayout layout)
VkImageLayout layout, VulkanWindow *window)
{
VkImage img = swapImages[swapIndex];
if(window == NULL)
window = mainWindow;
VkImage img = window->GetImage();
vkh::cmdPipelineBarrier(
cmd, {
@@ -574,9 +559,12 @@ VkImage VulkanGraphicsTest::StartUsingBackbuffer(VkCommandBuffer cmd, VkAccessFl
}
void VulkanGraphicsTest::FinishUsingBackbuffer(VkCommandBuffer cmd, VkAccessFlags prevUse,
VkImageLayout layout)
VkImageLayout layout, VulkanWindow *window)
{
VkImage img = swapImages[swapIndex];
if(window == NULL)
window = mainWindow;
VkImage img = window->GetImage();
vkh::cmdPipelineBarrier(cmd, {
vkh::ImageMemoryBarrier(prevUse, VK_ACCESS_MEMORY_READ_BIT, layout,
@@ -585,74 +573,27 @@ void VulkanGraphicsTest::FinishUsingBackbuffer(VkCommandBuffer cmd, VkAccessFlag
}
void VulkanGraphicsTest::Submit(int index, int totalSubmits, const std::vector<VkCommandBuffer> &cmds,
const std::vector<VkCommandBuffer> &seccmds)
const std::vector<VkCommandBuffer> &seccmds, VulkanWindow *window,
VkQueue q)
{
VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
if(window == NULL)
window = mainWindow;
VkSubmitInfo submit = vkh::SubmitInfo(cmds);
if(q == VK_NULL_HANDLE)
q = queue;
if(index == 0)
{
submit.waitSemaphoreCount = 1;
submit.pWaitDstStageMask = &waitStage;
submit.pWaitSemaphores = &renderStartSemaphore;
}
if(index == totalSubmits - 1)
{
submit.signalSemaphoreCount = 1;
submit.pSignalSemaphores = &renderEndSemaphore;
}
VkFence fence;
CHECK_VKR(vkCreateFence(device, vkh::FenceCreateInfo(), NULL, &fence));
fences.insert(fence);
for(const VkCommandBuffer &cmd : cmds)
pendingCommandBuffers[0].push_back(std::make_pair(cmd, fence));
for(const VkCommandBuffer &cmd : seccmds)
pendingCommandBuffers[1].push_back(std::make_pair(cmd, fence));
vkQueueSubmit(queue, 1, &submit, fence);
window->Submit(index, totalSubmits, cmds, seccmds, q);
}
void VulkanGraphicsTest::Present()
void VulkanGraphicsTest::Present(VulkanWindow *window, VkQueue q)
{
VkResult vkr = vkQueuePresentKHR(queue, vkh::PresentInfoKHR(swap, swapIndex, &renderEndSemaphore));
if(!window)
window = mainWindow;
if(vkr == VK_SUBOPTIMAL_KHR || vkr == VK_ERROR_OUT_OF_DATE_KHR)
resize();
if(q == VK_NULL_HANDLE)
q = queue;
vkQueueWaitIdle(queue);
std::set<VkFence> doneFences;
for(int level = 0; level < VK_COMMAND_BUFFER_LEVEL_RANGE_SIZE; level++)
{
for(auto it = pendingCommandBuffers[level].begin(); it != pendingCommandBuffers[level].end();)
{
if(vkGetFenceStatus(device, it->second) == VK_SUCCESS)
{
freeCommandBuffers[level].push_back(it->first);
doneFences.insert(it->second);
it = pendingCommandBuffers[level].erase(it);
}
else
{
++it;
}
}
}
for(auto it = doneFences.begin(); it != doneFences.end(); ++it)
{
vkDestroyFence(device, *it, NULL);
fences.erase(*it);
}
acquireImage();
window->Present(q);
}
VkPipelineShaderStageCreateInfo VulkanGraphicsTest::CompileShaderModule(
@@ -682,15 +623,24 @@ VkPipelineShaderStageCreateInfo VulkanGraphicsTest::CompileShaderModule(
return vkh::PipelineShaderStageCreateInfo(ret, vkstage[(int)stage], entry_point);
}
VkCommandBuffer VulkanGraphicsTest::GetCommandBuffer(VkCommandBufferLevel level)
VkCommandBuffer VulkanGraphicsTest::GetCommandBuffer(VkCommandBufferLevel level, VulkanWindow *window)
{
if(window == NULL)
window = mainWindow;
return window->GetCommandBuffer(level);
}
VkCommandBuffer VulkanWindow::GetCommandBuffer(VkCommandBufferLevel level)
{
std::vector<VkCommandBuffer> &buflist = freeCommandBuffers[level];
if(buflist.empty())
{
buflist.resize(4);
CHECK_VKR(vkAllocateCommandBuffers(device, vkh::CommandBufferAllocateInfo(cmdPool, 4, level),
&buflist[0]));
CHECK_VKR(vkAllocateCommandBuffers(
m_Test->device, vkh::CommandBufferAllocateInfo(cmdPool, 4, level), &buflist[0]));
}
VkCommandBuffer ret = buflist.back();
@@ -866,27 +816,88 @@ VkDescriptorSetLayout VulkanGraphicsTest::createDescriptorSetLayout(
return ret;
}
void VulkanGraphicsTest::resize()
VulkanWindow::VulkanWindow(VulkanGraphicsTest *test, GraphicsWindow *win)
{
destroySwap();
m_Test = test;
m_Win = win;
createSwap();
{
std::lock_guard<std::mutex> lock(m_Test->mutex);
for(const std::function<void()> &cb : resizeCallbacks)
cb();
CHECK_VKR(vkCreateCommandPool(
m_Test->device, vkh::CommandPoolCreateInfo(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT),
NULL, &cmdPool));
CHECK_VKR(
vkCreateSemaphore(m_Test->device, vkh::SemaphoreCreateInfo(), NULL, &renderStartSemaphore));
CHECK_VKR(
vkCreateSemaphore(m_Test->device, vkh::SemaphoreCreateInfo(), NULL, &renderEndSemaphore));
#if defined(WIN32)
VkWin32SurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = NULL;
createInfo.flags = 0;
createInfo.hwnd = ((Win32Window *)win)->wnd;
createInfo.hinstance = GetModuleHandleA(NULL);
vkCreateWin32SurfaceKHR(m_Test->instance, &createInfo, NULL, &surface);
#else
VkXcbSurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = NULL;
createInfo.flags = 0;
createInfo.connection = ((X11Window *)win)->xcb.connection;
createInfo.window = ((X11Window *)win)->xcb.window;
vkCreateXcbSurfaceKHR(m_Test->instance, &createInfo, NULL, &surface);
#endif
}
CreateSwapchain();
Acquire();
}
bool VulkanGraphicsTest::createSwap()
VulkanWindow::~VulkanWindow()
{
DestroySwapchain();
{
vkDestroySemaphore(m_Test->device, renderStartSemaphore, NULL);
vkDestroySemaphore(m_Test->device, renderEndSemaphore, NULL);
vkDestroyCommandPool(m_Test->device, cmdPool, NULL);
for(VkFence fence : fences)
vkDestroyFence(m_Test->device, fence, NULL);
if(surface)
vkDestroySurfaceKHR(m_Test->instance, surface, NULL);
}
delete m_Win;
}
bool VulkanWindow::CreateSwapchain()
{
std::lock_guard<std::mutex> lock(m_Test->mutex);
if(surface == VK_NULL_HANDLE)
return false;
VkResult vkr = VK_SUCCESS;
VkSurfaceFormatKHR format = {};
VkSurfaceFormatKHR surfaceFormat = {};
std::vector<VkSurfaceFormatKHR> formats;
CHECK_VKR(vkh::getSurfaceFormatsKHR(formats, phys, surface));
CHECK_VKR(vkh::getSurfaceFormatsKHR(formats, m_Test->phys, surface));
VkBool32 support = VK_FALSE;
CHECK_VKR(vkGetPhysicalDeviceSurfaceSupportKHR(phys, queueFamilyIndex, surface, &support));
CHECK_VKR(vkGetPhysicalDeviceSurfaceSupportKHR(m_Test->phys, m_Test->queueFamilyIndex, surface,
&support));
TEST_ASSERT(support, "Presentation is not supported on surface");
if(vkr != VK_SUCCESS || formats.empty())
@@ -895,27 +906,27 @@ bool VulkanGraphicsTest::createSwap()
return false;
}
format = formats[0];
surfaceFormat = formats[0];
for(const VkSurfaceFormatKHR &f : formats)
{
if(f.format == VK_FORMAT_B8G8R8A8_SRGB && f.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
{
format = f;
surfaceFormat = f;
break;
}
}
if(format.format == VK_FORMAT_UNDEFINED)
if(surfaceFormat.format == VK_FORMAT_UNDEFINED)
{
format.format = VK_FORMAT_B8G8R8A8_SRGB;
format.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
surfaceFormat.format = VK_FORMAT_B8G8R8A8_SRGB;
surfaceFormat.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
}
swapFormat = format.format;
format = surfaceFormat.format;
std::vector<VkPresentModeKHR> modes;
CHECK_VKR(vkh::getSurfacePresentModesKHR(modes, phys, surface));
CHECK_VKR(vkh::getSurfacePresentModesKHR(modes, m_Test->phys, surface));
VkPresentModeKHR mode = VK_PRESENT_MODE_IMMEDIATE_KHR;
@@ -925,7 +936,7 @@ bool VulkanGraphicsTest::createSwap()
uint32_t width = 1, height = 1;
VkSurfaceCapabilitiesKHR capabilities;
CHECK_VKR(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(phys, surface, &capabilities));
CHECK_VKR(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(m_Test->phys, surface, &capabilities));
width = capabilities.currentExtent.width;
@@ -941,64 +952,144 @@ bool VulkanGraphicsTest::createSwap()
scissor = vkh::Rect2D({0, 0}, {width, height});
CHECK_VKR(vkCreateSwapchainKHR(
device, vkh::SwapchainCreateInfoKHR(
surface, mode, format, {width, height},
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
m_Test->device, vkh::SwapchainCreateInfoKHR(
surface, mode, surfaceFormat, {width, height},
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
NULL, &swap));
CHECK_VKR(vkh::getSwapchainImagesKHR(swapImages, device, swap));
CHECK_VKR(vkh::getSwapchainImagesKHR(imgs, m_Test->device, swap));
if(swapRenderPass == VK_NULL_HANDLE)
if(rp == VK_NULL_HANDLE)
{
vkh::RenderPassCreator renderPassCreateInfo;
renderPassCreateInfo.attachments.push_back(
vkh::AttachmentDescription(swapFormat, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
vkh::AttachmentDescription(format, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
renderPassCreateInfo.addSubpass({VkAttachmentReference({0, VK_IMAGE_LAYOUT_GENERAL})});
swapRenderPass = createRenderPass(renderPassCreateInfo);
rp = m_Test->createRenderPass(renderPassCreateInfo);
}
swapImageViews.resize(swapImages.size());
for(size_t i = 0; i < swapImages.size(); i++)
imgviews.resize(imgs.size());
for(size_t i = 0; i < imgs.size(); i++)
{
CHECK_VKR(vkCreateImageView(
device, vkh::ImageViewCreateInfo(swapImages[i], VK_IMAGE_VIEW_TYPE_2D, format.format), NULL,
&swapImageViews[i]));
CHECK_VKR(vkCreateImageView(m_Test->device,
vkh::ImageViewCreateInfo(imgs[i], VK_IMAGE_VIEW_TYPE_2D, format),
NULL, &imgviews[i]));
}
swapFramebuffers.resize(swapImages.size());
for(size_t i = 0; i < swapImageViews.size(); i++)
swapFramebuffers[i] = createFramebuffer(
vkh::FramebufferCreateInfo(swapRenderPass, {swapImageViews[i]}, scissor.extent));
fbs.resize(imgs.size());
for(size_t i = 0; i < imgviews.size(); i++)
fbs[i] = m_Test->createFramebuffer(vkh::FramebufferCreateInfo(rp, {imgviews[i]}, scissor.extent));
return true;
}
void VulkanGraphicsTest::destroySwap()
void VulkanWindow::Acquire()
{
vkDeviceWaitIdle(device);
if(swap == VK_NULL_HANDLE)
return;
for(size_t i = 0; i < swapImages.size(); i++)
vkDestroyImageView(device, swapImageViews[i], NULL);
vkDestroySwapchainKHR(device, swap, NULL);
}
void VulkanGraphicsTest::acquireImage()
{
VkResult vkr = vkAcquireNextImageKHR(device, swap, UINT64_MAX, renderStartSemaphore,
VK_NULL_HANDLE, &swapIndex);
VkResult vkr = vkAcquireNextImageKHR(m_Test->device, swap, UINT64_MAX, renderStartSemaphore,
VK_NULL_HANDLE, &imgIndex);
if(vkr == VK_SUBOPTIMAL_KHR || vkr == VK_ERROR_OUT_OF_DATE_KHR)
{
resize();
DestroySwapchain();
CreateSwapchain();
vkr = vkAcquireNextImageKHR(device, swap, UINT64_MAX, renderStartSemaphore, VK_NULL_HANDLE,
&swapIndex);
vkr = vkAcquireNextImageKHR(m_Test->device, swap, UINT64_MAX, renderStartSemaphore,
VK_NULL_HANDLE, &imgIndex);
}
}
void VulkanWindow::Submit(int index, int totalSubmits, const std::vector<VkCommandBuffer> &cmds,
const std::vector<VkCommandBuffer> &seccmds, VkQueue q)
{
VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
VkSubmitInfo submit = vkh::SubmitInfo(cmds);
if(index == 0)
{
submit.waitSemaphoreCount = 1;
submit.pWaitDstStageMask = &waitStage;
submit.pWaitSemaphores = &renderStartSemaphore;
}
if(index == totalSubmits - 1)
{
submit.signalSemaphoreCount = 1;
submit.pSignalSemaphores = &renderEndSemaphore;
}
VkFence fence;
CHECK_VKR(vkCreateFence(m_Test->device, vkh::FenceCreateInfo(), NULL, &fence));
fences.insert(fence);
for(const VkCommandBuffer &cmd : cmds)
pendingCommandBuffers[0].push_back(std::make_pair(cmd, fence));
for(const VkCommandBuffer &cmd : seccmds)
pendingCommandBuffers[1].push_back(std::make_pair(cmd, fence));
vkQueueSubmit(q, 1, &submit, fence);
}
void VulkanWindow::Present(VkQueue queue)
{
if(swap == VK_NULL_HANDLE)
return;
VkResult vkr = vkQueuePresentKHR(queue, vkh::PresentInfoKHR(swap, imgIndex, &renderEndSemaphore));
if(vkr == VK_SUBOPTIMAL_KHR || vkr == VK_ERROR_OUT_OF_DATE_KHR)
{
DestroySwapchain();
CreateSwapchain();
}
std::set<VkFence> doneFences;
for(int level = 0; level < VK_COMMAND_BUFFER_LEVEL_RANGE_SIZE; level++)
{
for(auto it = pendingCommandBuffers[level].begin(); it != pendingCommandBuffers[level].end();)
{
if(vkGetFenceStatus(m_Test->device, it->second) == VK_SUCCESS)
{
freeCommandBuffers[level].push_back(it->first);
doneFences.insert(it->second);
it = pendingCommandBuffers[level].erase(it);
}
else
{
++it;
}
}
}
for(auto it = doneFences.begin(); it != doneFences.end(); ++it)
{
vkDestroyFence(m_Test->device, *it, NULL);
fences.erase(*it);
}
Acquire();
}
void VulkanWindow::DestroySwapchain()
{
std::lock_guard<std::mutex> lock(m_Test->mutex);
vkDeviceWaitIdle(m_Test->device);
for(size_t i = 0; i < imgs.size(); i++)
vkDestroyImageView(m_Test->device, imgviews[i], NULL);
vkDestroySwapchainKHR(m_Test->device, swap, NULL);
}
void VulkanGraphicsTest::getPhysFeatures2(void *nextStruct)
{
for(const char *ext : enabledInstExts)
@@ -1011,31 +1102,6 @@ void VulkanGraphicsTest::getPhysFeatures2(void *nextStruct)
}
}
VkResult VulkanGraphicsTest::CreateSurface(GraphicsWindow *win, VkSurfaceKHR *outSurf)
{
#if defined(WIN32)
VkWin32SurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = NULL;
createInfo.flags = 0;
createInfo.hwnd = ((Win32Window *)win)->wnd;
createInfo.hinstance = GetModuleHandleA(NULL);
return vkCreateWin32SurfaceKHR(instance, &createInfo, NULL, outSurf);
#else
VkXcbSurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = NULL;
createInfo.flags = 0;
createInfo.connection = ((X11Window *)win)->xcb.connection;
createInfo.window = ((X11Window *)win)->xcb.window;
return vkCreateXcbSurfaceKHR(instance, &createInfo, NULL, outSurf);
#endif
}
template <>
VkFormat vkh::_FormatFromObj<Vec4f>()
{
+83 -38
View File
@@ -25,6 +25,7 @@
#pragma once
#include <functional>
#include <mutex>
#include <set>
#include <vector>
#include "../test_common.h"
@@ -134,6 +135,71 @@ struct AllocatedImage
} \
} while(0);
struct VulkanGraphicsTest;
struct VulkanWindow : public GraphicsWindow
{
VkFormat format;
uint32_t imgIndex = 0;
VkRenderPass rp = VK_NULL_HANDLE;
VkViewport viewport;
VkRect2D scissor;
VulkanWindow(VulkanGraphicsTest *test, GraphicsWindow *win);
virtual ~VulkanWindow();
void Shutdown();
size_t GetCount() { return imgs.size(); }
VkImage GetImage(size_t idx = ~0U)
{
if(idx == ~0U)
idx = imgIndex;
return imgs[idx];
}
VkImageView GetView(size_t idx = ~0U)
{
if(idx == ~0U)
idx = imgIndex;
return imgviews[idx];
}
VkFramebuffer GetFB(size_t idx = ~0U)
{
if(idx == ~0U)
idx = imgIndex;
return fbs[idx];
}
bool Initialised() { return swap != VK_NULL_HANDLE; }
VkCommandBuffer GetCommandBuffer(VkCommandBufferLevel level);
void Submit(int index, int totalSubmits, const std::vector<VkCommandBuffer> &cmds,
const std::vector<VkCommandBuffer> &seccmds, VkQueue q);
void Present(VkQueue q);
void Acquire();
// forward GraphicsWindow functions to internal window
void Resize(int width, int height) { m_Win->Resize(width, height); }
bool Update() { return m_Win->Update(); }
private:
bool CreateSwapchain();
void DestroySwapchain();
VkSurfaceKHR surface = VK_NULL_HANDLE;
VkSwapchainKHR swap = VK_NULL_HANDLE;
std::vector<VkImage> imgs;
std::vector<VkImageView> imgviews;
VkSemaphore renderStartSemaphore = VK_NULL_HANDLE, renderEndSemaphore = VK_NULL_HANDLE;
std::vector<VkFramebuffer> fbs;
VkCommandPool cmdPool;
std::set<VkFence> fences;
std::vector<VkCommandBuffer> freeCommandBuffers[VK_COMMAND_BUFFER_LEVEL_RANGE_SIZE];
std::vector<std::pair<VkCommandBuffer, VkFence>>
pendingCommandBuffers[VK_COMMAND_BUFFER_LEVEL_RANGE_SIZE];
GraphicsWindow *m_Win;
VulkanGraphicsTest *m_Test;
};
struct VulkanGraphicsTest : public GraphicsTest
{
static const TestAPI API = TestAPI::Vulkan;
@@ -143,20 +209,23 @@ struct VulkanGraphicsTest : public GraphicsTest
void Prepare(int argc, char **argv);
bool Init();
void Shutdown();
GraphicsWindow *MakeWindow(int width, int height, const char *title);
VkResult CreateSurface(GraphicsWindow *win, VkSurfaceKHR *outSurf);
VulkanWindow *MakeWindow(int width, int height, const char *title);
bool Running();
VkImage StartUsingBackbuffer(VkCommandBuffer cmd, VkAccessFlags nextUse, VkImageLayout layout);
void FinishUsingBackbuffer(VkCommandBuffer cmd, VkAccessFlags prevUse, VkImageLayout layout);
VkImage StartUsingBackbuffer(VkCommandBuffer cmd, VkAccessFlags nextUse, VkImageLayout layout,
VulkanWindow *window = NULL);
void FinishUsingBackbuffer(VkCommandBuffer cmd, VkAccessFlags prevUse, VkImageLayout layout,
VulkanWindow *window = NULL);
void Submit(int index, int totalSubmits, const std::vector<VkCommandBuffer> &cmds,
const std::vector<VkCommandBuffer> &seccmds = {});
void Present();
const std::vector<VkCommandBuffer> &seccmds = {}, VulkanWindow *window = NULL,
VkQueue q = VK_NULL_HANDLE);
void Present(VulkanWindow *window = NULL, VkQueue q = VK_NULL_HANDLE);
VkPipelineShaderStageCreateInfo CompileShaderModule(const std::string &source_text,
ShaderLang lang, ShaderStage stage,
const char *entry_point = "main");
VkCommandBuffer GetCommandBuffer(VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY);
VkCommandBuffer GetCommandBuffer(VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
VulkanWindow *window = NULL);
void setName(VkObjectType objType, uint64_t obj, const std::string &name);
void pushMarker(VkCommandBuffer cmd, const std::string &name);
@@ -176,14 +245,10 @@ struct VulkanGraphicsTest : public GraphicsTest
VkPipelineLayout createPipelineLayout(const VkPipelineLayoutCreateInfo *info);
VkDescriptorSetLayout createDescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo *info);
void resize();
void onResize(std::function<void()> callback) { resizeCallbacks.push_back(callback); }
bool createSwap();
void destroySwap();
void acquireImage();
void getPhysFeatures2(void *nextStruct);
std::mutex mutex;
// requested features
VkPhysicalDeviceFeatures features = {};
@@ -203,24 +268,12 @@ struct VulkanGraphicsTest : public GraphicsTest
VkInstance instance;
VkPhysicalDevice phys;
VkDevice device;
uint32_t queueFamilyIndex;
uint32_t queueFamilyIndex = ~0U;
uint32_t queueCount;
VkQueue queue;
// swapchain stuff
VkSurfaceKHR surface = VK_NULL_HANDLE;
VkSwapchainKHR swap;
VkFormat swapFormat;
std::vector<VkImage> swapImages;
std::vector<VkImageView> swapImageViews;
uint32_t swapIndex = 0;
VkSemaphore renderStartSemaphore, renderEndSemaphore;
std::vector<std::function<void()>> resizeCallbacks;
VkRenderPass swapRenderPass;
std::vector<VkFramebuffer> swapFramebuffers;
// utilities
VkDebugUtilsMessengerEXT debugUtilsMessenger;
VkCommandPool cmdPool;
// tracking object lifetimes
std::vector<VkShaderModule> shaders;
@@ -233,21 +286,13 @@ struct VulkanGraphicsTest : public GraphicsTest
std::vector<VkPipelineLayout> pipelayouts;
std::vector<VkDescriptorSetLayout> setlayouts;
VkViewport viewport;
VkRect2D scissor;
GraphicsWindow *mainWindow = NULL;
// internal bookkeeping
std::set<VkFence> fences;
std::vector<VkCommandBuffer> freeCommandBuffers[VK_COMMAND_BUFFER_LEVEL_RANGE_SIZE];
std::vector<std::pair<VkCommandBuffer, VkFence>>
pendingCommandBuffers[VK_COMMAND_BUFFER_LEVEL_RANGE_SIZE];
VulkanWindow *mainWindow = NULL;
// VMA
VmaAllocator allocator = VK_NULL_HANDLE;
private:
static bool prepared_vk;
GraphicsWindow *MakePlatformWindow(int width, int height, const char *title);
};
+4 -4
View File
@@ -185,7 +185,7 @@ void main()
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = swapRenderPass;
pipeCreateInfo.renderPass = mainWindow->rp;
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, vertin)};
@@ -264,12 +264,12 @@ void main()
vkh::ImageSubresourceRange());
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
vkCmdSetViewport(cmd, 0, 1, &viewport);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdDraw(cmd, 3, 1, 0, 0);
+3 -3
View File
@@ -249,7 +249,7 @@ void main()
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = swapRenderPass;
pipeCreateInfo.renderPass = mainWindow->rp;
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
@@ -914,11 +914,11 @@ void main()
vkh::ImageSubresourceRange());
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
float x = 1.0f, y = 1.0f;
+4 -4
View File
@@ -105,7 +105,7 @@ void main()
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = swapRenderPass;
pipeCreateInfo.renderPass = mainWindow->rp;
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
@@ -233,15 +233,15 @@ void main()
vkh::ImageSubresourceRange());
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor,
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor,
{vkh::ClearValue(0.0f, 0.0f, 0.0f, 1.0f)}),
VK_SUBPASS_CONTENTS_INLINE);
std::vector<VkDescriptorSet> descsets(limits.maxBoundDescriptorSets, imgdescset);
descsets.back() = ubodescset;
vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descsets, {});
vkCmdSetViewport(cmd, 0, 1, &viewport);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
-2
View File
@@ -124,7 +124,5 @@ bool Win32Window::Update()
if(msg.message == WM_CHAR && msg.wParam == VK_ESCAPE)
return false;
Sleep(20);
return true;
}