vk_blit_screen: Make use of designated initializers where applicable

Now that we make use of C++20, we can use designated initializers to
make things a little nicer to read.
This commit is contained in:
Lioncash 2020-07-12 18:51:44 -04:00
parent f1d8c83e1c
commit db6fbd5894

View file

@ -141,24 +141,28 @@ struct ScreenRectVertex {
std::array<f32, 2> tex_coord; std::array<f32, 2> tex_coord;
static VkVertexInputBindingDescription GetDescription() { static VkVertexInputBindingDescription GetDescription() {
VkVertexInputBindingDescription description; return {
description.binding = 0; .binding = 0,
description.stride = sizeof(ScreenRectVertex); .stride = sizeof(ScreenRectVertex),
description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; .inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
return description; };
} }
static std::array<VkVertexInputAttributeDescription, 2> GetAttributes() { static std::array<VkVertexInputAttributeDescription, 2> GetAttributes() {
std::array<VkVertexInputAttributeDescription, 2> attributes; return {{
attributes[0].location = 0; {
attributes[0].binding = 0; .location = 0,
attributes[0].format = VK_FORMAT_R32G32_SFLOAT; .binding = 0,
attributes[0].offset = offsetof(ScreenRectVertex, position); .format = VK_FORMAT_R32G32_SFLOAT,
attributes[1].location = 1; .offset = offsetof(ScreenRectVertex, position),
attributes[1].binding = 0; },
attributes[1].format = VK_FORMAT_R32G32_SFLOAT; {
attributes[1].offset = offsetof(ScreenRectVertex, tex_coord); .location = 1,
return attributes; .binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = offsetof(ScreenRectVertex, tex_coord),
},
}};
} }
}; };
@ -267,20 +271,25 @@ std::tuple<VKFence&, VkSemaphore> VKBlitScreen::Draw(const Tegra::FramebufferCon
blit_image->Transition(0, 1, 0, 1, VK_PIPELINE_STAGE_TRANSFER_BIT, blit_image->Transition(0, 1, 0, 1, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkBufferImageCopy copy; const VkBufferImageCopy copy{
copy.bufferOffset = image_offset; .bufferOffset = image_offset,
copy.bufferRowLength = 0; .bufferRowLength = 0,
copy.bufferImageHeight = 0; .bufferImageHeight = 0,
copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; .imageSubresource =
copy.imageSubresource.mipLevel = 0; {
copy.imageSubresource.baseArrayLayer = 0; .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
copy.imageSubresource.layerCount = 1; .mipLevel = 0,
copy.imageOffset.x = 0; .baseArrayLayer = 0,
copy.imageOffset.y = 0; .layerCount = 1,
copy.imageOffset.z = 0; },
copy.imageExtent.width = framebuffer.width; .imageOffset = {.x = 0, .y = 0, .z = 0},
copy.imageExtent.height = framebuffer.height; .imageExtent =
copy.imageExtent.depth = 1; {
.width = framebuffer.width,
.height = framebuffer.height,
.depth = 1,
},
};
scheduler.Record( scheduler.Record(
[buffer = *buffer, image = *blit_image->GetHandle(), copy](vk::CommandBuffer cmdbuf) { [buffer = *buffer, image = *blit_image->GetHandle(), copy](vk::CommandBuffer cmdbuf) {
cmdbuf.CopyBufferToImage(buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, copy); cmdbuf.CopyBufferToImage(buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, copy);
@ -295,11 +304,9 @@ std::tuple<VKFence&, VkSemaphore> VKBlitScreen::Draw(const Tegra::FramebufferCon
descriptor_set = descriptor_sets[image_index], buffer = *buffer, descriptor_set = descriptor_sets[image_index], buffer = *buffer,
size = swapchain.GetSize(), pipeline = *pipeline, size = swapchain.GetSize(), pipeline = *pipeline,
layout = *pipeline_layout](vk::CommandBuffer cmdbuf) { layout = *pipeline_layout](vk::CommandBuffer cmdbuf) {
VkClearValue clear_color; const VkClearValue clear_color{
clear_color.color.float32[0] = 0.0f; .color = {.float32 = {0.0f, 0.0f, 0.0f, 0.0f}},
clear_color.color.float32[1] = 0.0f; };
clear_color.color.float32[2] = 0.0f;
clear_color.color.float32[3] = 0.0f;
VkRenderPassBeginInfo renderpass_bi; VkRenderPassBeginInfo renderpass_bi;
renderpass_bi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderpass_bi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
@ -379,93 +386,109 @@ void VKBlitScreen::CreateSemaphores() {
} }
void VKBlitScreen::CreateDescriptorPool() { void VKBlitScreen::CreateDescriptorPool() {
std::array<VkDescriptorPoolSize, 2> pool_sizes; const std::array<VkDescriptorPoolSize, 2> pool_sizes{{
pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; {
pool_sizes[0].descriptorCount = static_cast<u32>(image_count); .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
pool_sizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; .descriptorCount = static_cast<u32>(image_count),
pool_sizes[1].descriptorCount = static_cast<u32>(image_count); },
{
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = static_cast<u32>(image_count),
},
}};
VkDescriptorPoolCreateInfo ci; const VkDescriptorPoolCreateInfo ci{
ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
ci.maxSets = static_cast<u32>(image_count); .maxSets = static_cast<u32>(image_count),
ci.poolSizeCount = static_cast<u32>(pool_sizes.size()); .poolSizeCount = static_cast<u32>(pool_sizes.size()),
ci.pPoolSizes = pool_sizes.data(); .pPoolSizes = pool_sizes.data(),
};
descriptor_pool = device.GetLogical().CreateDescriptorPool(ci); descriptor_pool = device.GetLogical().CreateDescriptorPool(ci);
} }
void VKBlitScreen::CreateRenderPass() { void VKBlitScreen::CreateRenderPass() {
VkAttachmentDescription color_attachment; const VkAttachmentDescription color_attachment{
color_attachment.flags = 0; .flags = 0,
color_attachment.format = swapchain.GetImageFormat(); .format = swapchain.GetImageFormat(),
color_attachment.samples = VK_SAMPLE_COUNT_1_BIT; .samples = VK_SAMPLE_COUNT_1_BIT,
color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
color_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
color_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
};
VkAttachmentReference color_attachment_ref; const VkAttachmentReference color_attachment_ref{
color_attachment_ref.attachment = 0; .attachment = 0,
color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};
VkSubpassDescription subpass_description; const VkSubpassDescription subpass_description{
subpass_description.flags = 0; .flags = 0,
subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
subpass_description.inputAttachmentCount = 0; .inputAttachmentCount = 0,
subpass_description.pInputAttachments = nullptr; .pInputAttachments = nullptr,
subpass_description.colorAttachmentCount = 1; .colorAttachmentCount = 1,
subpass_description.pColorAttachments = &color_attachment_ref; .pColorAttachments = &color_attachment_ref,
subpass_description.pResolveAttachments = nullptr; .pResolveAttachments = nullptr,
subpass_description.pDepthStencilAttachment = nullptr; .pDepthStencilAttachment = nullptr,
subpass_description.preserveAttachmentCount = 0; .preserveAttachmentCount = 0,
subpass_description.pPreserveAttachments = nullptr; .pPreserveAttachments = nullptr,
};
VkSubpassDependency dependency; const VkSubpassDependency dependency{
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; .srcSubpass = VK_SUBPASS_EXTERNAL,
dependency.dstSubpass = 0; .dstSubpass = 0,
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
dependency.srcAccessMask = 0; .srcAccessMask = 0,
dependency.dstAccessMask = .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; .dependencyFlags = 0,
dependency.dependencyFlags = 0; };
VkRenderPassCreateInfo renderpass_ci; const VkRenderPassCreateInfo renderpass_ci{
renderpass_ci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
renderpass_ci.pNext = nullptr; .pNext = nullptr,
renderpass_ci.flags = 0; .flags = 0,
renderpass_ci.attachmentCount = 1; .attachmentCount = 1,
renderpass_ci.pAttachments = &color_attachment; .pAttachments = &color_attachment,
renderpass_ci.subpassCount = 1; .subpassCount = 1,
renderpass_ci.pSubpasses = &subpass_description; .pSubpasses = &subpass_description,
renderpass_ci.dependencyCount = 1; .dependencyCount = 1,
renderpass_ci.pDependencies = &dependency; .pDependencies = &dependency,
};
renderpass = device.GetLogical().CreateRenderPass(renderpass_ci); renderpass = device.GetLogical().CreateRenderPass(renderpass_ci);
} }
void VKBlitScreen::CreateDescriptorSetLayout() { void VKBlitScreen::CreateDescriptorSetLayout() {
std::array<VkDescriptorSetLayoutBinding, 2> layout_bindings; const std::array<VkDescriptorSetLayoutBinding, 2> layout_bindings{{
layout_bindings[0].binding = 0; {
layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; .binding = 0,
layout_bindings[0].descriptorCount = 1; .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; .descriptorCount = 1,
layout_bindings[0].pImmutableSamplers = nullptr; .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
layout_bindings[1].binding = 1; .pImmutableSamplers = nullptr,
layout_bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; },
layout_bindings[1].descriptorCount = 1; {
layout_bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; .binding = 1,
layout_bindings[1].pImmutableSamplers = nullptr; .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
.pImmutableSamplers = nullptr,
},
}};
VkDescriptorSetLayoutCreateInfo ci; const VkDescriptorSetLayoutCreateInfo ci{
ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.bindingCount = static_cast<u32>(layout_bindings.size()); .bindingCount = static_cast<u32>(layout_bindings.size()),
ci.pBindings = layout_bindings.data(); .pBindings = layout_bindings.data(),
};
descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout(ci); descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout(ci);
} }
@ -473,175 +496,192 @@ void VKBlitScreen::CreateDescriptorSetLayout() {
void VKBlitScreen::CreateDescriptorSets() { void VKBlitScreen::CreateDescriptorSets() {
const std::vector layouts(image_count, *descriptor_set_layout); const std::vector layouts(image_count, *descriptor_set_layout);
VkDescriptorSetAllocateInfo ai; const VkDescriptorSetAllocateInfo ai{
ai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
ai.pNext = nullptr; .pNext = nullptr,
ai.descriptorPool = *descriptor_pool; .descriptorPool = *descriptor_pool,
ai.descriptorSetCount = static_cast<u32>(image_count); .descriptorSetCount = static_cast<u32>(image_count),
ai.pSetLayouts = layouts.data(); .pSetLayouts = layouts.data(),
};
descriptor_sets = descriptor_pool.Allocate(ai); descriptor_sets = descriptor_pool.Allocate(ai);
} }
void VKBlitScreen::CreatePipelineLayout() { void VKBlitScreen::CreatePipelineLayout() {
VkPipelineLayoutCreateInfo ci; const VkPipelineLayoutCreateInfo ci{
ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.setLayoutCount = 1; .setLayoutCount = 1,
ci.pSetLayouts = descriptor_set_layout.address(); .pSetLayouts = descriptor_set_layout.address(),
ci.pushConstantRangeCount = 0; .pushConstantRangeCount = 0,
ci.pPushConstantRanges = nullptr; .pPushConstantRanges = nullptr,
};
pipeline_layout = device.GetLogical().CreatePipelineLayout(ci); pipeline_layout = device.GetLogical().CreatePipelineLayout(ci);
} }
void VKBlitScreen::CreateGraphicsPipeline() { void VKBlitScreen::CreateGraphicsPipeline() {
std::array<VkPipelineShaderStageCreateInfo, 2> shader_stages; const std::array<VkPipelineShaderStageCreateInfo, 2> shader_stages{{
shader_stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; {
shader_stages[0].pNext = nullptr; .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
shader_stages[0].flags = 0; .pNext = nullptr,
shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; .flags = 0,
shader_stages[0].module = *vertex_shader; .stage = VK_SHADER_STAGE_VERTEX_BIT,
shader_stages[0].pName = "main"; .module = *vertex_shader,
shader_stages[0].pSpecializationInfo = nullptr; .pName = "main",
shader_stages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; .pSpecializationInfo = nullptr,
shader_stages[1].pNext = nullptr; },
shader_stages[1].flags = 0; {
shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
shader_stages[1].module = *fragment_shader; .pNext = nullptr,
shader_stages[1].pName = "main"; .flags = 0,
shader_stages[1].pSpecializationInfo = nullptr; .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
.module = *fragment_shader,
.pName = "main",
.pSpecializationInfo = nullptr,
},
}};
const auto vertex_binding_description = ScreenRectVertex::GetDescription(); const auto vertex_binding_description = ScreenRectVertex::GetDescription();
const auto vertex_attrs_description = ScreenRectVertex::GetAttributes(); const auto vertex_attrs_description = ScreenRectVertex::GetAttributes();
VkPipelineVertexInputStateCreateInfo vertex_input_ci; const VkPipelineVertexInputStateCreateInfo vertex_input_ci{
vertex_input_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
vertex_input_ci.pNext = nullptr; .pNext = nullptr,
vertex_input_ci.flags = 0; .flags = 0,
vertex_input_ci.vertexBindingDescriptionCount = 1; .vertexBindingDescriptionCount = 1,
vertex_input_ci.pVertexBindingDescriptions = &vertex_binding_description; .pVertexBindingDescriptions = &vertex_binding_description,
vertex_input_ci.vertexAttributeDescriptionCount = u32{vertex_attrs_description.size()}; .vertexAttributeDescriptionCount = u32{vertex_attrs_description.size()},
vertex_input_ci.pVertexAttributeDescriptions = vertex_attrs_description.data(); .pVertexAttributeDescriptions = vertex_attrs_description.data(),
};
VkPipelineInputAssemblyStateCreateInfo input_assembly_ci; const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci{
input_assembly_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
input_assembly_ci.pNext = nullptr; .pNext = nullptr,
input_assembly_ci.flags = 0; .flags = 0,
input_assembly_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
input_assembly_ci.primitiveRestartEnable = VK_FALSE; .primitiveRestartEnable = VK_FALSE,
};
VkPipelineViewportStateCreateInfo viewport_state_ci; const VkPipelineViewportStateCreateInfo viewport_state_ci{
viewport_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
viewport_state_ci.pNext = nullptr; .pNext = nullptr,
viewport_state_ci.flags = 0; .flags = 0,
viewport_state_ci.viewportCount = 1; .viewportCount = 1,
viewport_state_ci.pViewports = nullptr; .pViewports = nullptr,
viewport_state_ci.scissorCount = 1; .scissorCount = 1,
viewport_state_ci.pScissors = nullptr; .pScissors = nullptr,
};
VkPipelineRasterizationStateCreateInfo rasterization_ci; const VkPipelineRasterizationStateCreateInfo rasterization_ci{
rasterization_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
rasterization_ci.pNext = nullptr; .pNext = nullptr,
rasterization_ci.flags = 0; .flags = 0,
rasterization_ci.depthClampEnable = VK_FALSE; .depthClampEnable = VK_FALSE,
rasterization_ci.rasterizerDiscardEnable = VK_FALSE; .rasterizerDiscardEnable = VK_FALSE,
rasterization_ci.polygonMode = VK_POLYGON_MODE_FILL; .polygonMode = VK_POLYGON_MODE_FILL,
rasterization_ci.cullMode = VK_CULL_MODE_NONE; .cullMode = VK_CULL_MODE_NONE,
rasterization_ci.frontFace = VK_FRONT_FACE_CLOCKWISE; .frontFace = VK_FRONT_FACE_CLOCKWISE,
rasterization_ci.depthBiasEnable = VK_FALSE; .depthBiasEnable = VK_FALSE,
rasterization_ci.depthBiasConstantFactor = 0.0f; .depthBiasConstantFactor = 0.0f,
rasterization_ci.depthBiasClamp = 0.0f; .depthBiasClamp = 0.0f,
rasterization_ci.depthBiasSlopeFactor = 0.0f; .depthBiasSlopeFactor = 0.0f,
rasterization_ci.lineWidth = 1.0f; .lineWidth = 1.0f,
};
VkPipelineMultisampleStateCreateInfo multisampling_ci; const VkPipelineMultisampleStateCreateInfo multisampling_ci{
multisampling_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
multisampling_ci.pNext = nullptr; .pNext = nullptr,
multisampling_ci.flags = 0; .flags = 0,
multisampling_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
multisampling_ci.sampleShadingEnable = VK_FALSE; .sampleShadingEnable = VK_FALSE,
multisampling_ci.minSampleShading = 0.0f; .minSampleShading = 0.0f,
multisampling_ci.pSampleMask = nullptr; .pSampleMask = nullptr,
multisampling_ci.alphaToCoverageEnable = VK_FALSE; .alphaToCoverageEnable = VK_FALSE,
multisampling_ci.alphaToOneEnable = VK_FALSE; .alphaToOneEnable = VK_FALSE,
};
VkPipelineColorBlendAttachmentState color_blend_attachment; const VkPipelineColorBlendAttachmentState color_blend_attachment{
color_blend_attachment.blendEnable = VK_FALSE; .blendEnable = VK_FALSE,
color_blend_attachment.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO; .srcColorBlendFactor = VK_BLEND_FACTOR_ZERO,
color_blend_attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; .dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
color_blend_attachment.colorBlendOp = VK_BLEND_OP_ADD; .colorBlendOp = VK_BLEND_OP_ADD,
color_blend_attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; .srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
color_blend_attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
color_blend_attachment.alphaBlendOp = VK_BLEND_OP_ADD; .alphaBlendOp = VK_BLEND_OP_ADD,
color_blend_attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
};
VkPipelineColorBlendStateCreateInfo color_blend_ci; const VkPipelineColorBlendStateCreateInfo color_blend_ci{
color_blend_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
color_blend_ci.flags = 0; .pNext = nullptr,
color_blend_ci.pNext = nullptr; .flags = 0,
color_blend_ci.logicOpEnable = VK_FALSE; .logicOpEnable = VK_FALSE,
color_blend_ci.logicOp = VK_LOGIC_OP_COPY; .logicOp = VK_LOGIC_OP_COPY,
color_blend_ci.attachmentCount = 1; .attachmentCount = 1,
color_blend_ci.pAttachments = &color_blend_attachment; .pAttachments = &color_blend_attachment,
color_blend_ci.blendConstants[0] = 0.0f; .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},
color_blend_ci.blendConstants[1] = 0.0f; };
color_blend_ci.blendConstants[2] = 0.0f;
color_blend_ci.blendConstants[3] = 0.0f;
static constexpr std::array dynamic_states = {VK_DYNAMIC_STATE_VIEWPORT, static constexpr std::array dynamic_states{
VK_DYNAMIC_STATE_SCISSOR}; VK_DYNAMIC_STATE_VIEWPORT,
VkPipelineDynamicStateCreateInfo dynamic_state_ci; VK_DYNAMIC_STATE_SCISSOR,
dynamic_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; };
dynamic_state_ci.pNext = nullptr; const VkPipelineDynamicStateCreateInfo dynamic_state_ci{
dynamic_state_ci.flags = 0; .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
dynamic_state_ci.dynamicStateCount = static_cast<u32>(dynamic_states.size()); .pNext = nullptr,
dynamic_state_ci.pDynamicStates = dynamic_states.data(); .flags = 0,
.dynamicStateCount = static_cast<u32>(dynamic_states.size()),
.pDynamicStates = dynamic_states.data(),
};
VkGraphicsPipelineCreateInfo pipeline_ci; const VkGraphicsPipelineCreateInfo pipeline_ci{
pipeline_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
pipeline_ci.pNext = nullptr; .pNext = nullptr,
pipeline_ci.flags = 0; .flags = 0,
pipeline_ci.stageCount = static_cast<u32>(shader_stages.size()); .stageCount = static_cast<u32>(shader_stages.size()),
pipeline_ci.pStages = shader_stages.data(); .pStages = shader_stages.data(),
pipeline_ci.pVertexInputState = &vertex_input_ci; .pVertexInputState = &vertex_input_ci,
pipeline_ci.pInputAssemblyState = &input_assembly_ci; .pInputAssemblyState = &input_assembly_ci,
pipeline_ci.pTessellationState = nullptr; .pTessellationState = nullptr,
pipeline_ci.pViewportState = &viewport_state_ci; .pViewportState = &viewport_state_ci,
pipeline_ci.pRasterizationState = &rasterization_ci; .pRasterizationState = &rasterization_ci,
pipeline_ci.pMultisampleState = &multisampling_ci; .pMultisampleState = &multisampling_ci,
pipeline_ci.pDepthStencilState = nullptr; .pDepthStencilState = nullptr,
pipeline_ci.pColorBlendState = &color_blend_ci; .pColorBlendState = &color_blend_ci,
pipeline_ci.pDynamicState = &dynamic_state_ci; .pDynamicState = &dynamic_state_ci,
pipeline_ci.layout = *pipeline_layout; .layout = *pipeline_layout,
pipeline_ci.renderPass = *renderpass; .renderPass = *renderpass,
pipeline_ci.subpass = 0; .subpass = 0,
pipeline_ci.basePipelineHandle = 0; .basePipelineHandle = 0,
pipeline_ci.basePipelineIndex = 0; .basePipelineIndex = 0,
};
pipeline = device.GetLogical().CreateGraphicsPipeline(pipeline_ci); pipeline = device.GetLogical().CreateGraphicsPipeline(pipeline_ci);
} }
void VKBlitScreen::CreateSampler() { void VKBlitScreen::CreateSampler() {
VkSamplerCreateInfo ci; const VkSamplerCreateInfo ci{
ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.magFilter = VK_FILTER_LINEAR; .magFilter = VK_FILTER_LINEAR,
ci.minFilter = VK_FILTER_NEAREST; .minFilter = VK_FILTER_NEAREST,
ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; .mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR,
ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; .addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
ci.mipLodBias = 0.0f; .mipLodBias = 0.0f,
ci.anisotropyEnable = VK_FALSE; .anisotropyEnable = VK_FALSE,
ci.maxAnisotropy = 0.0f; .maxAnisotropy = 0.0f,
ci.compareEnable = VK_FALSE; .compareEnable = VK_FALSE,
ci.compareOp = VK_COMPARE_OP_NEVER; .compareOp = VK_COMPARE_OP_NEVER,
ci.minLod = 0.0f; .minLod = 0.0f,
ci.maxLod = 0.0f; .maxLod = 0.0f,
ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK; .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK,
ci.unnormalizedCoordinates = VK_FALSE; .unnormalizedCoordinates = VK_FALSE,
};
sampler = device.GetLogical().CreateSampler(ci); sampler = device.GetLogical().CreateSampler(ci);
} }
@ -650,15 +690,16 @@ void VKBlitScreen::CreateFramebuffers() {
const VkExtent2D size{swapchain.GetSize()}; const VkExtent2D size{swapchain.GetSize()};
framebuffers.resize(image_count); framebuffers.resize(image_count);
VkFramebufferCreateInfo ci; VkFramebufferCreateInfo ci{
ci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.renderPass = *renderpass; .renderPass = *renderpass,
ci.attachmentCount = 1; .attachmentCount = 1,
ci.width = size.width; .width = size.width,
ci.height = size.height; .height = size.height,
ci.layers = 1; .layers = 1,
};
for (std::size_t i = 0; i < image_count; ++i) { for (std::size_t i = 0; i < image_count; ++i) {
const VkImageView image_view{swapchain.GetImageViewIndex(i)}; const VkImageView image_view{swapchain.GetImageViewIndex(i)};
@ -678,16 +719,17 @@ void VKBlitScreen::ReleaseRawImages() {
} }
void VKBlitScreen::CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer) { void VKBlitScreen::CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer) {
VkBufferCreateInfo ci; const VkBufferCreateInfo ci{
ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.size = CalculateBufferSize(framebuffer); .size = CalculateBufferSize(framebuffer),
ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
ci.queueFamilyIndexCount = 0; .queueFamilyIndexCount = 0,
ci.pQueueFamilyIndices = nullptr; .pQueueFamilyIndices = nullptr,
};
buffer = device.GetLogical().CreateBuffer(ci); buffer = device.GetLogical().CreateBuffer(ci);
buffer_commit = memory_manager.Commit(buffer, true); buffer_commit = memory_manager.Commit(buffer, true);
@ -697,24 +739,28 @@ void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer)
raw_images.resize(image_count); raw_images.resize(image_count);
raw_buffer_commits.resize(image_count); raw_buffer_commits.resize(image_count);
VkImageCreateInfo ci; const VkImageCreateInfo ci{
ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.imageType = VK_IMAGE_TYPE_2D; .imageType = VK_IMAGE_TYPE_2D,
ci.format = GetFormat(framebuffer); .format = GetFormat(framebuffer),
ci.extent.width = framebuffer.width; .extent =
ci.extent.height = framebuffer.height; {
ci.extent.depth = 1; .width = framebuffer.width,
ci.mipLevels = 1; .height = framebuffer.height,
ci.arrayLayers = 1; .depth = 1,
ci.samples = VK_SAMPLE_COUNT_1_BIT; },
ci.tiling = VK_IMAGE_TILING_LINEAR; .mipLevels = 1,
ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; .arrayLayers = 1,
ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; .samples = VK_SAMPLE_COUNT_1_BIT,
ci.queueFamilyIndexCount = 0; .tiling = VK_IMAGE_TILING_LINEAR,
ci.pQueueFamilyIndices = nullptr; .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
};
for (std::size_t i = 0; i < image_count; ++i) { for (std::size_t i = 0; i < image_count; ++i) {
raw_images[i] = std::make_unique<VKImage>(device, scheduler, ci, VK_IMAGE_ASPECT_COLOR_BIT); raw_images[i] = std::make_unique<VKImage>(device, scheduler, ci, VK_IMAGE_ASPECT_COLOR_BIT);
@ -723,39 +769,43 @@ void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer)
} }
void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView image_view) const { void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView image_view) const {
VkDescriptorBufferInfo buffer_info; const VkDescriptorBufferInfo buffer_info{
buffer_info.buffer = *buffer; .buffer = *buffer,
buffer_info.offset = offsetof(BufferData, uniform); .offset = offsetof(BufferData, uniform),
buffer_info.range = sizeof(BufferData::uniform); .range = sizeof(BufferData::uniform),
};
VkWriteDescriptorSet ubo_write; const VkWriteDescriptorSet ubo_write{
ubo_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
ubo_write.pNext = nullptr; .pNext = nullptr,
ubo_write.dstSet = descriptor_sets[image_index]; .dstSet = descriptor_sets[image_index],
ubo_write.dstBinding = 0; .dstBinding = 0,
ubo_write.dstArrayElement = 0; .dstArrayElement = 0,
ubo_write.descriptorCount = 1; .descriptorCount = 1,
ubo_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
ubo_write.pImageInfo = nullptr; .pImageInfo = nullptr,
ubo_write.pBufferInfo = &buffer_info; .pBufferInfo = &buffer_info,
ubo_write.pTexelBufferView = nullptr; .pTexelBufferView = nullptr,
};
VkDescriptorImageInfo image_info; const VkDescriptorImageInfo image_info{
image_info.sampler = *sampler; .sampler = *sampler,
image_info.imageView = image_view; .imageView = image_view,
image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
};
VkWriteDescriptorSet sampler_write; const VkWriteDescriptorSet sampler_write{
sampler_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
sampler_write.pNext = nullptr; .pNext = nullptr,
sampler_write.dstSet = descriptor_sets[image_index]; .dstSet = descriptor_sets[image_index],
sampler_write.dstBinding = 1; .dstBinding = 1,
sampler_write.dstArrayElement = 0; .dstArrayElement = 0,
sampler_write.descriptorCount = 1; .descriptorCount = 1,
sampler_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
sampler_write.pImageInfo = &image_info; .pImageInfo = &image_info,
sampler_write.pBufferInfo = nullptr; .pBufferInfo = nullptr,
sampler_write.pTexelBufferView = nullptr; .pTexelBufferView = nullptr,
};
device.GetLogical().UpdateDescriptorSets(std::array{ubo_write, sampler_write}, {}); device.GetLogical().UpdateDescriptorSets(std::array{ubo_write, sampler_write}, {});
} }