Merge pull request #4364 from lioncash/desig5

vulkan: Make use of designated initializers where applicable
merge-requests/60/head
bunnei 2020-07-18 00:12:43 +07:00 committed by GitHub
commit 821d295f24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 758 additions and 659 deletions

@ -39,16 +39,17 @@ std::unique_ptr<VKStreamBuffer> CreateStreamBuffer(const VKDevice& device, VKSch
Buffer::Buffer(const VKDevice& device, VKMemoryManager& memory_manager, VKScheduler& scheduler_, Buffer::Buffer(const VKDevice& device, VKMemoryManager& memory_manager, VKScheduler& scheduler_,
VKStagingBufferPool& staging_pool_, VAddr cpu_addr, std::size_t size) VKStagingBufferPool& staging_pool_, VAddr cpu_addr, std::size_t size)
: VideoCommon::BufferBlock{cpu_addr, size}, scheduler{scheduler_}, staging_pool{staging_pool_} { : BufferBlock{cpu_addr, size}, scheduler{scheduler_}, staging_pool{staging_pool_} {
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 = static_cast<VkDeviceSize>(size); .size = static_cast<VkDeviceSize>(size),
ci.usage = BUFFER_USAGE | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; .usage = BUFFER_USAGE | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
ci.queueFamilyIndexCount = 0; .queueFamilyIndexCount = 0,
ci.pQueueFamilyIndices = nullptr; .pQueueFamilyIndices = nullptr,
};
buffer.handle = device.GetLogical().CreateBuffer(ci); buffer.handle = device.GetLogical().CreateBuffer(ci);
buffer.commit = memory_manager.Commit(buffer.handle, false); buffer.commit = memory_manager.Commit(buffer.handle, false);
@ -66,16 +67,17 @@ void Buffer::Upload(std::size_t offset, std::size_t size, const u8* data) {
scheduler.Record([staging = *staging.handle, handle, offset, size](vk::CommandBuffer cmdbuf) { scheduler.Record([staging = *staging.handle, handle, offset, size](vk::CommandBuffer cmdbuf) {
cmdbuf.CopyBuffer(staging, handle, VkBufferCopy{0, offset, size}); cmdbuf.CopyBuffer(staging, handle, VkBufferCopy{0, offset, size});
VkBufferMemoryBarrier barrier; const VkBufferMemoryBarrier barrier{
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
barrier.pNext = nullptr; .pNext = nullptr,
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
barrier.dstAccessMask = UPLOAD_ACCESS_BARRIERS; .dstAccessMask = UPLOAD_ACCESS_BARRIERS,
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
barrier.buffer = handle; .buffer = handle,
barrier.offset = offset; .offset = offset,
barrier.size = size; .size = size,
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, UPLOAD_PIPELINE_STAGE, 0, {}, cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, UPLOAD_PIPELINE_STAGE, 0, {},
barrier, {}); barrier, {});
}); });
@ -87,16 +89,17 @@ void Buffer::Download(std::size_t offset, std::size_t size, u8* data) {
const VkBuffer handle = Handle(); const VkBuffer handle = Handle();
scheduler.Record([staging = *staging.handle, handle, offset, size](vk::CommandBuffer cmdbuf) { scheduler.Record([staging = *staging.handle, handle, offset, size](vk::CommandBuffer cmdbuf) {
VkBufferMemoryBarrier barrier; const VkBufferMemoryBarrier barrier{
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
barrier.pNext = nullptr; .pNext = nullptr,
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
barrier.buffer = handle; .buffer = handle,
barrier.offset = offset; .offset = offset,
barrier.size = size; .size = size,
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |

@ -115,32 +115,32 @@ constexpr u8 quad_array[] = {
0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00}; 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00};
VkDescriptorSetLayoutBinding BuildQuadArrayPassDescriptorSetLayoutBinding() { VkDescriptorSetLayoutBinding BuildQuadArrayPassDescriptorSetLayoutBinding() {
VkDescriptorSetLayoutBinding binding; return {
binding.binding = 0; .binding = 0,
binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
binding.descriptorCount = 1; .descriptorCount = 1,
binding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
binding.pImmutableSamplers = nullptr; .pImmutableSamplers = nullptr,
return binding; };
} }
VkDescriptorUpdateTemplateEntryKHR BuildQuadArrayPassDescriptorUpdateTemplateEntry() { VkDescriptorUpdateTemplateEntryKHR BuildQuadArrayPassDescriptorUpdateTemplateEntry() {
VkDescriptorUpdateTemplateEntryKHR entry; return {
entry.dstBinding = 0; .dstBinding = 0,
entry.dstArrayElement = 0; .dstArrayElement = 0,
entry.descriptorCount = 1; .descriptorCount = 1,
entry.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
entry.offset = 0; .offset = 0,
entry.stride = sizeof(DescriptorUpdateEntry); .stride = sizeof(DescriptorUpdateEntry),
return entry; };
} }
VkPushConstantRange BuildComputePushConstantRange(std::size_t size) { VkPushConstantRange BuildComputePushConstantRange(std::size_t size) {
VkPushConstantRange range; return {
range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
range.offset = 0; .offset = 0,
range.size = static_cast<u32>(size); .size = static_cast<u32>(size),
return range; };
} }
// Uint8 SPIR-V module. Generated from the "shaders/" directory. // Uint8 SPIR-V module. Generated from the "shaders/" directory.
@ -344,29 +344,33 @@ constexpr u8 QUAD_INDEXED_SPV[] = {
0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00}; 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00};
std::array<VkDescriptorSetLayoutBinding, 2> BuildInputOutputDescriptorSetBindings() { std::array<VkDescriptorSetLayoutBinding, 2> BuildInputOutputDescriptorSetBindings() {
std::array<VkDescriptorSetLayoutBinding, 2> bindings; return {{
bindings[0].binding = 0; {
bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; .binding = 0,
bindings[0].descriptorCount = 1; .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
bindings[0].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; .descriptorCount = 1,
bindings[0].pImmutableSamplers = nullptr; .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
bindings[1].binding = 1; .pImmutableSamplers = nullptr,
bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; },
bindings[1].descriptorCount = 1; {
bindings[1].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; .binding = 1,
bindings[1].pImmutableSamplers = nullptr; .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
return bindings; .descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
.pImmutableSamplers = nullptr,
},
}};
} }
VkDescriptorUpdateTemplateEntryKHR BuildInputOutputDescriptorUpdateTemplate() { VkDescriptorUpdateTemplateEntryKHR BuildInputOutputDescriptorUpdateTemplate() {
VkDescriptorUpdateTemplateEntryKHR entry; return {
entry.dstBinding = 0; .dstBinding = 0,
entry.dstArrayElement = 0; .dstArrayElement = 0,
entry.descriptorCount = 2; .descriptorCount = 2,
entry.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
entry.offset = 0; .offset = 0,
entry.stride = sizeof(DescriptorUpdateEntry); .stride = sizeof(DescriptorUpdateEntry),
return entry; };
} }
} // Anonymous namespace } // Anonymous namespace
@ -376,37 +380,37 @@ VKComputePass::VKComputePass(const VKDevice& device, VKDescriptorPool& descripto
vk::Span<VkDescriptorUpdateTemplateEntryKHR> templates, vk::Span<VkDescriptorUpdateTemplateEntryKHR> templates,
vk::Span<VkPushConstantRange> push_constants, std::size_t code_size, vk::Span<VkPushConstantRange> push_constants, std::size_t code_size,
const u8* code) { const u8* code) {
VkDescriptorSetLayoutCreateInfo descriptor_layout_ci; descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout({
descriptor_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
descriptor_layout_ci.pNext = nullptr; .pNext = nullptr,
descriptor_layout_ci.flags = 0; .flags = 0,
descriptor_layout_ci.bindingCount = bindings.size(); .bindingCount = bindings.size(),
descriptor_layout_ci.pBindings = bindings.data(); .pBindings = bindings.data(),
descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout(descriptor_layout_ci); });
VkPipelineLayoutCreateInfo pipeline_layout_ci; layout = device.GetLogical().CreatePipelineLayout({
pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
pipeline_layout_ci.pNext = nullptr; .pNext = nullptr,
pipeline_layout_ci.flags = 0; .flags = 0,
pipeline_layout_ci.setLayoutCount = 1; .setLayoutCount = 1,
pipeline_layout_ci.pSetLayouts = descriptor_set_layout.address(); .pSetLayouts = descriptor_set_layout.address(),
pipeline_layout_ci.pushConstantRangeCount = push_constants.size(); .pushConstantRangeCount = push_constants.size(),
pipeline_layout_ci.pPushConstantRanges = push_constants.data(); .pPushConstantRanges = push_constants.data(),
layout = device.GetLogical().CreatePipelineLayout(pipeline_layout_ci); });
if (!templates.empty()) { if (!templates.empty()) {
VkDescriptorUpdateTemplateCreateInfoKHR template_ci; descriptor_template = device.GetLogical().CreateDescriptorUpdateTemplateKHR({
template_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR; .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
template_ci.pNext = nullptr; .pNext = nullptr,
template_ci.flags = 0; .flags = 0,
template_ci.descriptorUpdateEntryCount = templates.size(); .descriptorUpdateEntryCount = templates.size(),
template_ci.pDescriptorUpdateEntries = templates.data(); .pDescriptorUpdateEntries = templates.data(),
template_ci.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR; .templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
template_ci.descriptorSetLayout = *descriptor_set_layout; .descriptorSetLayout = *descriptor_set_layout,
template_ci.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
template_ci.pipelineLayout = *layout; .pipelineLayout = *layout,
template_ci.set = 0; .set = 0,
descriptor_template = device.GetLogical().CreateDescriptorUpdateTemplateKHR(template_ci); });
descriptor_allocator.emplace(descriptor_pool, *descriptor_set_layout); descriptor_allocator.emplace(descriptor_pool, *descriptor_set_layout);
} }
@ -414,32 +418,32 @@ VKComputePass::VKComputePass(const VKDevice& device, VKDescriptorPool& descripto
auto code_copy = std::make_unique<u32[]>(code_size / sizeof(u32) + 1); auto code_copy = std::make_unique<u32[]>(code_size / sizeof(u32) + 1);
std::memcpy(code_copy.get(), code, code_size); std::memcpy(code_copy.get(), code, code_size);
VkShaderModuleCreateInfo module_ci; module = device.GetLogical().CreateShaderModule({
module_ci.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
module_ci.pNext = nullptr; .pNext = nullptr,
module_ci.flags = 0; .flags = 0,
module_ci.codeSize = code_size; .codeSize = code_size,
module_ci.pCode = code_copy.get(); .pCode = code_copy.get(),
module = device.GetLogical().CreateShaderModule(module_ci); });
VkComputePipelineCreateInfo pipeline_ci; pipeline = device.GetLogical().CreateComputePipeline({
pipeline_ci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
pipeline_ci.pNext = nullptr; .pNext = nullptr,
pipeline_ci.flags = 0; .flags = 0,
pipeline_ci.layout = *layout; .stage =
pipeline_ci.basePipelineHandle = nullptr; {
pipeline_ci.basePipelineIndex = 0; .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.pNext = nullptr,
VkPipelineShaderStageCreateInfo& stage_ci = pipeline_ci.stage; .flags = 0,
stage_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; .stage = VK_SHADER_STAGE_COMPUTE_BIT,
stage_ci.pNext = nullptr; .module = *module,
stage_ci.flags = 0; .pName = "main",
stage_ci.stage = VK_SHADER_STAGE_COMPUTE_BIT; .pSpecializationInfo = nullptr,
stage_ci.module = *module; },
stage_ci.pName = "main"; .layout = *layout,
stage_ci.pSpecializationInfo = nullptr; .basePipelineHandle = nullptr,
.basePipelineIndex = 0,
pipeline = device.GetLogical().CreateComputePipeline(pipeline_ci); });
} }
VKComputePass::~VKComputePass() = default; VKComputePass::~VKComputePass() = default;

@ -43,12 +43,13 @@ vk::DescriptorSetLayout VKComputePipeline::CreateDescriptorSetLayout() const {
const auto add_bindings = [&](VkDescriptorType descriptor_type, std::size_t num_entries) { const auto add_bindings = [&](VkDescriptorType descriptor_type, std::size_t num_entries) {
// TODO(Rodrigo): Maybe make individual bindings here? // TODO(Rodrigo): Maybe make individual bindings here?
for (u32 bindpoint = 0; bindpoint < static_cast<u32>(num_entries); ++bindpoint) { for (u32 bindpoint = 0; bindpoint < static_cast<u32>(num_entries); ++bindpoint) {
VkDescriptorSetLayoutBinding& entry = bindings.emplace_back(); bindings.push_back({
entry.binding = binding++; .binding = binding++,
entry.descriptorType = descriptor_type; .descriptorType = descriptor_type,
entry.descriptorCount = 1; .descriptorCount = 1,
entry.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
entry.pImmutableSamplers = nullptr; .pImmutableSamplers = nullptr,
});
} }
}; };
add_bindings(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, entries.const_buffers.size()); add_bindings(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, entries.const_buffers.size());
@ -58,25 +59,25 @@ vk::DescriptorSetLayout VKComputePipeline::CreateDescriptorSetLayout() const {
add_bindings(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, entries.storage_texels.size()); add_bindings(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, entries.storage_texels.size());
add_bindings(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, entries.images.size()); add_bindings(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, entries.images.size());
VkDescriptorSetLayoutCreateInfo ci; return device.GetLogical().CreateDescriptorSetLayout({
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>(bindings.size()); .bindingCount = static_cast<u32>(bindings.size()),
ci.pBindings = bindings.data(); .pBindings = bindings.data(),
return device.GetLogical().CreateDescriptorSetLayout(ci); });
} }
vk::PipelineLayout VKComputePipeline::CreatePipelineLayout() const { vk::PipelineLayout VKComputePipeline::CreatePipelineLayout() const {
VkPipelineLayoutCreateInfo ci; return device.GetLogical().CreatePipelineLayout({
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,
return device.GetLogical().CreatePipelineLayout(ci); });
} }
vk::DescriptorUpdateTemplateKHR VKComputePipeline::CreateDescriptorUpdateTemplate() const { vk::DescriptorUpdateTemplateKHR VKComputePipeline::CreateDescriptorUpdateTemplate() const {
@ -89,59 +90,63 @@ vk::DescriptorUpdateTemplateKHR VKComputePipeline::CreateDescriptorUpdateTemplat
return {}; return {};
} }
VkDescriptorUpdateTemplateCreateInfoKHR ci; return device.GetLogical().CreateDescriptorUpdateTemplateKHR({
ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR; .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.descriptorUpdateEntryCount = static_cast<u32>(template_entries.size()); .descriptorUpdateEntryCount = static_cast<u32>(template_entries.size()),
ci.pDescriptorUpdateEntries = template_entries.data(); .pDescriptorUpdateEntries = template_entries.data(),
ci.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR; .templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
ci.descriptorSetLayout = *descriptor_set_layout; .descriptorSetLayout = *descriptor_set_layout,
ci.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
ci.pipelineLayout = *layout; .pipelineLayout = *layout,
ci.set = DESCRIPTOR_SET; .set = DESCRIPTOR_SET,
return device.GetLogical().CreateDescriptorUpdateTemplateKHR(ci); });
} }
vk::ShaderModule VKComputePipeline::CreateShaderModule(const std::vector<u32>& code) const { vk::ShaderModule VKComputePipeline::CreateShaderModule(const std::vector<u32>& code) const {
device.SaveShader(code); device.SaveShader(code);
VkShaderModuleCreateInfo ci; return device.GetLogical().CreateShaderModule({
ci.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.codeSize = code.size() * sizeof(u32); .codeSize = code.size() * sizeof(u32),
ci.pCode = code.data(); .pCode = code.data(),
return device.GetLogical().CreateShaderModule(ci); });
} }
vk::Pipeline VKComputePipeline::CreatePipeline() const { vk::Pipeline VKComputePipeline::CreatePipeline() const {
VkComputePipelineCreateInfo ci;
VkPipelineShaderStageCreateInfo& stage_ci = ci.stage;
stage_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
stage_ci.pNext = nullptr;
stage_ci.flags = 0;
stage_ci.stage = VK_SHADER_STAGE_COMPUTE_BIT;
stage_ci.module = *shader_module;
stage_ci.pName = "main";
stage_ci.pSpecializationInfo = nullptr;
VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT subgroup_size_ci; VkComputePipelineCreateInfo ci{
subgroup_size_ci.sType = .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT; .pNext = nullptr,
subgroup_size_ci.pNext = nullptr; .flags = 0,
subgroup_size_ci.requiredSubgroupSize = GuestWarpSize; .stage =
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
.module = *shader_module,
.pName = "main",
.pSpecializationInfo = nullptr,
},
.layout = *layout,
.basePipelineHandle = nullptr,
.basePipelineIndex = 0,
};
const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT subgroup_size_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT,
.pNext = nullptr,
.requiredSubgroupSize = GuestWarpSize,
};
if (entries.uses_warps && device.IsGuestWarpSizeSupported(VK_SHADER_STAGE_COMPUTE_BIT)) { if (entries.uses_warps && device.IsGuestWarpSizeSupported(VK_SHADER_STAGE_COMPUTE_BIT)) {
stage_ci.pNext = &subgroup_size_ci; ci.stage.pNext = &subgroup_size_ci;
} }
ci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
ci.pNext = nullptr;
ci.flags = 0;
ci.layout = *layout;
ci.basePipelineHandle = nullptr;
ci.basePipelineIndex = 0;
return device.GetLogical().CreateComputePipeline(ci); return device.GetLogical().CreateComputePipeline(ci);
} }

@ -43,27 +43,30 @@ vk::DescriptorPool* VKDescriptorPool::AllocateNewPool() {
{VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, num_sets * 64}, {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, num_sets * 64},
{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, num_sets * 64}, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, num_sets * 64},
{VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, num_sets * 64}, {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, num_sets * 64},
{VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, num_sets * 40}}; {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, num_sets * 40},
};
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 = num_sets; .maxSets = num_sets,
ci.poolSizeCount = static_cast<u32>(std::size(pool_sizes)); .poolSizeCount = static_cast<u32>(std::size(pool_sizes)),
ci.pPoolSizes = std::data(pool_sizes); .pPoolSizes = std::data(pool_sizes),
};
return &pools.emplace_back(device.GetLogical().CreateDescriptorPool(ci)); return &pools.emplace_back(device.GetLogical().CreateDescriptorPool(ci));
} }
vk::DescriptorSets VKDescriptorPool::AllocateDescriptors(VkDescriptorSetLayout layout, vk::DescriptorSets VKDescriptorPool::AllocateDescriptors(VkDescriptorSetLayout layout,
std::size_t count) { std::size_t count) {
const std::vector layout_copies(count, layout); const std::vector layout_copies(count, layout);
VkDescriptorSetAllocateInfo ai; 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 = **active_pool; .descriptorPool = **active_pool,
ai.descriptorSetCount = static_cast<u32>(count); .descriptorSetCount = static_cast<u32>(count),
ai.pSetLayouts = layout_copies.data(); .pSetLayouts = layout_copies.data(),
};
vk::DescriptorSets sets = active_pool->Allocate(ai); vk::DescriptorSets sets = active_pool->Allocate(ai);
if (!sets.IsOutOfPoolMemory()) { if (!sets.IsOutOfPoolMemory()) {

@ -102,21 +102,29 @@ bool VKImage::HasChanged(u32 base_layer, u32 num_layers, u32 base_level, u32 num
void VKImage::CreatePresentView() { void VKImage::CreatePresentView() {
// Image type has to be 2D to be presented. // Image type has to be 2D to be presented.
VkImageViewCreateInfo image_view_ci; present_view = device.GetLogical().CreateImageView({
image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
image_view_ci.pNext = nullptr; .pNext = nullptr,
image_view_ci.flags = 0; .flags = 0,
image_view_ci.image = *image; .image = *image,
image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D; .viewType = VK_IMAGE_VIEW_TYPE_2D,
image_view_ci.format = format; .format = format,
image_view_ci.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, .components =
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}; {
image_view_ci.subresourceRange.aspectMask = aspect_mask; .r = VK_COMPONENT_SWIZZLE_IDENTITY,
image_view_ci.subresourceRange.baseMipLevel = 0; .g = VK_COMPONENT_SWIZZLE_IDENTITY,
image_view_ci.subresourceRange.levelCount = 1; .b = VK_COMPONENT_SWIZZLE_IDENTITY,
image_view_ci.subresourceRange.baseArrayLayer = 0; .a = VK_COMPONENT_SWIZZLE_IDENTITY,
image_view_ci.subresourceRange.layerCount = 1; },
present_view = device.GetLogical().CreateImageView(image_view_ci); .subresourceRange =
{
.aspectMask = aspect_mask,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
});
} }
VKImage::SubrangeState& VKImage::GetSubrangeState(u32 layer, u32 level) noexcept { VKImage::SubrangeState& VKImage::GetSubrangeState(u32 layer, u32 level) noexcept {

@ -178,13 +178,12 @@ bool VKMemoryManager::AllocMemory(VkMemoryPropertyFlags wanted_properties, u32 t
}(); }();
// Try to allocate found type. // Try to allocate found type.
VkMemoryAllocateInfo memory_ai; vk::DeviceMemory memory = device.GetLogical().TryAllocateMemory({
memory_ai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
memory_ai.pNext = nullptr; .pNext = nullptr,
memory_ai.allocationSize = size; .allocationSize = size,
memory_ai.memoryTypeIndex = type; .memoryTypeIndex = type,
});
vk::DeviceMemory memory = device.GetLogical().TryAllocateMemory(memory_ai);
if (!memory) { if (!memory) {
LOG_CRITICAL(Render_Vulkan, "Device allocation failed!"); LOG_CRITICAL(Render_Vulkan, "Device allocation failed!");
return false; return false;

@ -88,12 +88,13 @@ void AddBindings(std::vector<VkDescriptorSetLayoutBinding>& bindings, u32& bindi
// Combined image samplers can be arrayed. // Combined image samplers can be arrayed.
count = container[i].size; count = container[i].size;
} }
VkDescriptorSetLayoutBinding& entry = bindings.emplace_back(); bindings.push_back({
entry.binding = binding++; .binding = binding++,
entry.descriptorType = descriptor_type; .descriptorType = descriptor_type,
entry.descriptorCount = count; .descriptorCount = count,
entry.stageFlags = stage_flags; .stageFlags = stage_flags,
entry.pImmutableSamplers = nullptr; .pImmutableSamplers = nullptr,
});
} }
} }
@ -259,10 +260,10 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach
} }
} }
Specialization specialization; const Specialization specialization{
specialization.workgroup_size = key.workgroup_size; .workgroup_size = key.workgroup_size,
specialization.shared_memory_size = key.shared_memory_size; .shared_memory_size = key.shared_memory_size,
};
const SPIRVShader spirv_shader{Decompile(device, shader->GetIR(), ShaderType::Compute, const SPIRVShader spirv_shader{Decompile(device, shader->GetIR(), ShaderType::Compute,
shader->GetRegistry(), specialization), shader->GetRegistry(), specialization),
shader->GetEntries()}; shader->GetEntries()};
@ -370,13 +371,14 @@ void AddEntry(std::vector<VkDescriptorUpdateTemplateEntry>& template_entries, u3
if constexpr (descriptor_type == COMBINED_IMAGE_SAMPLER) { if constexpr (descriptor_type == COMBINED_IMAGE_SAMPLER) {
for (u32 i = 0; i < count; ++i) { for (u32 i = 0; i < count; ++i) {
const u32 num_samplers = container[i].size; const u32 num_samplers = container[i].size;
VkDescriptorUpdateTemplateEntry& entry = template_entries.emplace_back(); template_entries.push_back({
entry.dstBinding = binding; .dstBinding = binding,
entry.dstArrayElement = 0; .dstArrayElement = 0,
entry.descriptorCount = num_samplers; .descriptorCount = num_samplers,
entry.descriptorType = descriptor_type; .descriptorType = descriptor_type,
entry.offset = offset; .offset = offset,
entry.stride = entry_size; .stride = entry_size,
});
++binding; ++binding;
offset += num_samplers * entry_size; offset += num_samplers * entry_size;
@ -389,22 +391,24 @@ void AddEntry(std::vector<VkDescriptorUpdateTemplateEntry>& template_entries, u3
// Nvidia has a bug where updating multiple texels at once causes the driver to crash. // Nvidia has a bug where updating multiple texels at once causes the driver to crash.
// Note: Fixed in driver Windows 443.24, Linux 440.66.15 // Note: Fixed in driver Windows 443.24, Linux 440.66.15
for (u32 i = 0; i < count; ++i) { for (u32 i = 0; i < count; ++i) {
VkDescriptorUpdateTemplateEntry& entry = template_entries.emplace_back(); template_entries.push_back({
entry.dstBinding = binding + i; .dstBinding = binding + i,
entry.dstArrayElement = 0; .dstArrayElement = 0,
entry.descriptorCount = 1; .descriptorCount = 1,
entry.descriptorType = descriptor_type; .descriptorType = descriptor_type,
entry.offset = static_cast<std::size_t>(offset + i * entry_size); .offset = static_cast<std::size_t>(offset + i * entry_size),
entry.stride = entry_size; .stride = entry_size,
});
} }
} else if (count > 0) { } else if (count > 0) {
VkDescriptorUpdateTemplateEntry& entry = template_entries.emplace_back(); template_entries.push_back({
entry.dstBinding = binding; .dstBinding = binding,
entry.dstArrayElement = 0; .dstArrayElement = 0,
entry.descriptorCount = count; .descriptorCount = count,
entry.descriptorType = descriptor_type; .descriptorType = descriptor_type,
entry.offset = offset; .offset = offset,
entry.stride = entry_size; .stride = entry_size,
});
} }
offset += count * entry_size; offset += count * entry_size;
binding += count; binding += count;

@ -47,14 +47,14 @@ std::pair<VkQueryPool, u32> QueryPool::Commit(VKFence& fence) {
void QueryPool::Allocate(std::size_t begin, std::size_t end) { void QueryPool::Allocate(std::size_t begin, std::size_t end) {
usage.resize(end); usage.resize(end);
VkQueryPoolCreateInfo query_pool_ci; pools.push_back(device->GetLogical().CreateQueryPool({
query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,
query_pool_ci.pNext = nullptr; .pNext = nullptr,
query_pool_ci.flags = 0; .flags = 0,
query_pool_ci.queryType = GetTarget(type); .queryType = GetTarget(type),
query_pool_ci.queryCount = static_cast<u32>(end - begin); .queryCount = static_cast<u32>(end - begin),
query_pool_ci.pipelineStatistics = 0; .pipelineStatistics = 0,
pools.push_back(device->GetLogical().CreateQueryPool(query_pool_ci)); }));
} }
void QueryPool::Reserve(std::pair<VkQueryPool, u32> query) { void QueryPool::Reserve(std::pair<VkQueryPool, u32> query) {

@ -64,20 +64,22 @@ VkViewport GetViewportState(const VKDevice& device, const Maxwell& regs, std::si
const auto& src = regs.viewport_transform[index]; const auto& src = regs.viewport_transform[index];
const float width = src.scale_x * 2.0f; const float width = src.scale_x * 2.0f;
const float height = src.scale_y * 2.0f; const float height = src.scale_y * 2.0f;
VkViewport viewport;
viewport.x = src.translate_x - src.scale_x;
viewport.y = src.translate_y - src.scale_y;
viewport.width = width != 0.0f ? width : 1.0f;
viewport.height = height != 0.0f ? height : 1.0f;
const float reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1.0f : 0.0f; const float reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1.0f : 0.0f;
viewport.minDepth = src.translate_z - src.scale_z * reduce_z;
viewport.maxDepth = src.translate_z + src.scale_z; VkViewport viewport{
.x = src.translate_x - src.scale_x,
.y = src.translate_y - src.scale_y,
.width = width != 0.0f ? width : 1.0f,
.height = height != 0.0f ? height : 1.0f,
.minDepth = src.translate_z - src.scale_z * reduce_z,
.maxDepth = src.translate_z + src.scale_z,
};
if (!device.IsExtDepthRangeUnrestrictedSupported()) { if (!device.IsExtDepthRangeUnrestrictedSupported()) {
viewport.minDepth = std::clamp(viewport.minDepth, 0.0f, 1.0f); viewport.minDepth = std::clamp(viewport.minDepth, 0.0f, 1.0f);
viewport.maxDepth = std::clamp(viewport.maxDepth, 0.0f, 1.0f); viewport.maxDepth = std::clamp(viewport.maxDepth, 0.0f, 1.0f);
} }
return viewport; return viewport;
} }
@ -508,10 +510,11 @@ void RasterizerVulkan::Clear() {
const u32 color_attachment = regs.clear_buffers.RT; const u32 color_attachment = regs.clear_buffers.RT;
scheduler.Record([color_attachment, clear_value, clear_rect](vk::CommandBuffer cmdbuf) { scheduler.Record([color_attachment, clear_value, clear_rect](vk::CommandBuffer cmdbuf) {
VkClearAttachment attachment; const VkClearAttachment attachment{
attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
attachment.colorAttachment = color_attachment; .colorAttachment = color_attachment,
attachment.clearValue = clear_value; .clearValue = clear_value,
};
cmdbuf.ClearAttachments(attachment, clear_rect); cmdbuf.ClearAttachments(attachment, clear_rect);
}); });
} }
@ -551,13 +554,16 @@ void RasterizerVulkan::DispatchCompute(GPUVAddr code_addr) {
query_cache.UpdateCounters(); query_cache.UpdateCounters();
const auto& launch_desc = system.GPU().KeplerCompute().launch_description; const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
ComputePipelineCacheKey key; auto& pipeline = pipeline_cache.GetComputePipeline({
key.shader = code_addr; .shader = code_addr,
key.shared_memory_size = launch_desc.shared_alloc; .shared_memory_size = launch_desc.shared_alloc,
key.workgroup_size = {launch_desc.block_dim_x, launch_desc.block_dim_y, .workgroup_size =
launch_desc.block_dim_z}; {
launch_desc.block_dim_x,
auto& pipeline = pipeline_cache.GetComputePipeline(key); launch_desc.block_dim_y,
launch_desc.block_dim_z,
},
});
// Compute dispatches can't be executed inside a renderpass // Compute dispatches can't be executed inside a renderpass
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();
@ -841,17 +847,17 @@ std::tuple<VkFramebuffer, VkExtent2D> RasterizerVulkan::ConfigureFramebuffers(
const auto [fbentry, is_cache_miss] = framebuffer_cache.try_emplace(key); const auto [fbentry, is_cache_miss] = framebuffer_cache.try_emplace(key);
auto& framebuffer = fbentry->second; auto& framebuffer = fbentry->second;
if (is_cache_miss) { if (is_cache_miss) {
VkFramebufferCreateInfo framebuffer_ci; framebuffer = device.GetLogical().CreateFramebuffer({
framebuffer_ci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
framebuffer_ci.pNext = nullptr; .pNext = nullptr,
framebuffer_ci.flags = 0; .flags = 0,
framebuffer_ci.renderPass = key.renderpass; .renderPass = key.renderpass,
framebuffer_ci.attachmentCount = static_cast<u32>(key.views.size()); .attachmentCount = static_cast<u32>(key.views.size()),
framebuffer_ci.pAttachments = key.views.data(); .pAttachments = key.views.data(),
framebuffer_ci.width = key.width; .width = key.width,
framebuffer_ci.height = key.height; .height = key.height,
framebuffer_ci.layers = key.layers; .layers = key.layers,
framebuffer = device.GetLogical().CreateFramebuffer(framebuffer_ci); });
} }
return {*framebuffer, VkExtent2D{key.width, key.height}}; return {*framebuffer, VkExtent2D{key.width, key.height}};
@ -1553,17 +1559,17 @@ VkBuffer RasterizerVulkan::DefaultBuffer() {
return *default_buffer; return *default_buffer;
} }
VkBufferCreateInfo ci; default_buffer = device.GetLogical().CreateBuffer({
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 = DEFAULT_BUFFER_SIZE; .size = DEFAULT_BUFFER_SIZE,
ci.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
VK_BUFFER_USAGE_UNIFORM_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,
default_buffer = device.GetLogical().CreateBuffer(ci); });
default_buffer_commit = memory_manager.Commit(default_buffer, false); default_buffer_commit = memory_manager.Commit(default_buffer, false);
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();

@ -39,10 +39,14 @@ VkRenderPass VKRenderPassCache::GetRenderPass(const RenderPassParams& params) {
vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& params) const { vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& params) const {
using namespace VideoCore::Surface; using namespace VideoCore::Surface;
std::vector<VkAttachmentDescription> descriptors;
std::vector<VkAttachmentReference> color_references;
const std::size_t num_attachments = static_cast<std::size_t>(params.num_color_attachments); const std::size_t num_attachments = static_cast<std::size_t>(params.num_color_attachments);
std::vector<VkAttachmentDescription> descriptors;
descriptors.reserve(num_attachments);
std::vector<VkAttachmentReference> color_references;
color_references.reserve(num_attachments);
for (std::size_t rt = 0; rt < num_attachments; ++rt) { for (std::size_t rt = 0; rt < num_attachments; ++rt) {
const auto guest_format = static_cast<Tegra::RenderTargetFormat>(params.color_formats[rt]); const auto guest_format = static_cast<Tegra::RenderTargetFormat>(params.color_formats[rt]);
const PixelFormat pixel_format = PixelFormatFromRenderTargetFormat(guest_format); const PixelFormat pixel_format = PixelFormatFromRenderTargetFormat(guest_format);
@ -54,20 +58,22 @@ vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& param
const VkImageLayout color_layout = ((params.texceptions >> rt) & 1) != 0 const VkImageLayout color_layout = ((params.texceptions >> rt) & 1) != 0
? VK_IMAGE_LAYOUT_GENERAL ? VK_IMAGE_LAYOUT_GENERAL
: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentDescription& descriptor = descriptors.emplace_back(); descriptors.push_back({
descriptor.flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT; .flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT,
descriptor.format = format.format; .format = format.format,
descriptor.samples = VK_SAMPLE_COUNT_1_BIT; .samples = VK_SAMPLE_COUNT_1_BIT,
descriptor.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
descriptor.storeOp = VK_ATTACHMENT_STORE_OP_STORE; .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
descriptor.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
descriptor.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
descriptor.initialLayout = color_layout; .initialLayout = color_layout,
descriptor.finalLayout = color_layout; .finalLayout = color_layout,
});
VkAttachmentReference& reference = color_references.emplace_back(); color_references.push_back({
reference.attachment = static_cast<u32>(rt); .attachment = static_cast<u32>(rt),
reference.layout = color_layout; .layout = color_layout,
});
} }
VkAttachmentReference zeta_attachment_ref; VkAttachmentReference zeta_attachment_ref;
@ -82,32 +88,36 @@ vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& param
const VkImageLayout zeta_layout = params.zeta_texception != 0 const VkImageLayout zeta_layout = params.zeta_texception != 0
? VK_IMAGE_LAYOUT_GENERAL ? VK_IMAGE_LAYOUT_GENERAL
: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAttachmentDescription& descriptor = descriptors.emplace_back(); descriptors.push_back({
descriptor.flags = 0; .flags = 0,
descriptor.format = format.format; .format = format.format,
descriptor.samples = VK_SAMPLE_COUNT_1_BIT; .samples = VK_SAMPLE_COUNT_1_BIT,
descriptor.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
descriptor.storeOp = VK_ATTACHMENT_STORE_OP_STORE; .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
descriptor.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
descriptor.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
descriptor.initialLayout = zeta_layout; .initialLayout = zeta_layout,
descriptor.finalLayout = zeta_layout; .finalLayout = zeta_layout,
});
zeta_attachment_ref.attachment = static_cast<u32>(num_attachments); zeta_attachment_ref = {
zeta_attachment_ref.layout = zeta_layout; .attachment = static_cast<u32>(num_attachments),
.layout = zeta_layout,
};
} }
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 = static_cast<u32>(color_references.size()); .colorAttachmentCount = static_cast<u32>(color_references.size()),
subpass_description.pColorAttachments = color_references.data(); .pColorAttachments = color_references.data(),
subpass_description.pResolveAttachments = nullptr; .pResolveAttachments = nullptr,
subpass_description.pDepthStencilAttachment = has_zeta ? &zeta_attachment_ref : nullptr; .pDepthStencilAttachment = has_zeta ? &zeta_attachment_ref : nullptr,
subpass_description.preserveAttachmentCount = 0; .preserveAttachmentCount = 0,
subpass_description.pPreserveAttachments = nullptr; .pPreserveAttachments = nullptr,
};
VkAccessFlags access = 0; VkAccessFlags access = 0;
VkPipelineStageFlags stage = 0; VkPipelineStageFlags stage = 0;
@ -122,26 +132,27 @@ vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& param
stage |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; stage |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
} }
VkSubpassDependency subpass_dependency; const VkSubpassDependency subpass_dependency{
subpass_dependency.srcSubpass = VK_SUBPASS_EXTERNAL; .srcSubpass = VK_SUBPASS_EXTERNAL,
subpass_dependency.dstSubpass = 0; .dstSubpass = 0,
subpass_dependency.srcStageMask = stage; .srcStageMask = stage,
subpass_dependency.dstStageMask = stage; .dstStageMask = stage,
subpass_dependency.srcAccessMask = 0; .srcAccessMask = 0,
subpass_dependency.dstAccessMask = access; .dstAccessMask = access,
subpass_dependency.dependencyFlags = 0; .dependencyFlags = 0,
};
VkRenderPassCreateInfo ci; return device.GetLogical().CreateRenderPass({
ci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.attachmentCount = static_cast<u32>(descriptors.size()); .attachmentCount = static_cast<u32>(descriptors.size()),
ci.pAttachments = descriptors.data(); .pAttachments = descriptors.data(),
ci.subpassCount = 1; .subpassCount = 1,
ci.pSubpasses = &subpass_description; .pSubpasses = &subpass_description,
ci.dependencyCount = 1; .dependencyCount = 1,
ci.pDependencies = &subpass_dependency; .pDependencies = &subpass_dependency,
return device.GetLogical().CreateRenderPass(ci); });
} }
} // namespace Vulkan } // namespace Vulkan

@ -18,33 +18,32 @@ namespace {
constexpr std::size_t COMMAND_BUFFER_POOL_SIZE = 0x1000; constexpr std::size_t COMMAND_BUFFER_POOL_SIZE = 0x1000;
constexpr std::size_t FENCES_GROW_STEP = 0x40; constexpr std::size_t FENCES_GROW_STEP = 0x40;
VkFenceCreateInfo BuildFenceCreateInfo() { constexpr VkFenceCreateInfo BuildFenceCreateInfo() {
VkFenceCreateInfo fence_ci; return {
fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
fence_ci.pNext = nullptr; .pNext = nullptr,
fence_ci.flags = 0; .flags = 0,
return fence_ci; };
} }
} // Anonymous namespace } // Anonymous namespace
class CommandBufferPool final : public VKFencedPool { class CommandBufferPool final : public VKFencedPool {
public: public:
CommandBufferPool(const VKDevice& device) explicit CommandBufferPool(const VKDevice& device)
: VKFencedPool(COMMAND_BUFFER_POOL_SIZE), device{device} {} : VKFencedPool(COMMAND_BUFFER_POOL_SIZE), device{device} {}
void Allocate(std::size_t begin, std::size_t end) override { void Allocate(std::size_t begin, std::size_t end) override {
// Command buffers are going to be commited, recorded, executed every single usage cycle. // Command buffers are going to be commited, recorded, executed every single usage cycle.
// They are also going to be reseted when commited. // They are also going to be reseted when commited.
VkCommandPoolCreateInfo command_pool_ci;
command_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
command_pool_ci.pNext = nullptr;
command_pool_ci.flags =
VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
command_pool_ci.queueFamilyIndex = device.GetGraphicsFamily();
Pool& pool = pools.emplace_back(); Pool& pool = pools.emplace_back();
pool.handle = device.GetLogical().CreateCommandPool(command_pool_ci); pool.handle = device.GetLogical().CreateCommandPool({
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.pNext = nullptr,
.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT |
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
.queueFamilyIndex = device.GetGraphicsFamily(),
});
pool.cmdbufs = pool.handle.Allocate(COMMAND_BUFFER_POOL_SIZE); pool.cmdbufs = pool.handle.Allocate(COMMAND_BUFFER_POOL_SIZE);
} }

@ -44,32 +44,35 @@ vk::Sampler VKSamplerCache::CreateSampler(const Tegra::Texture::TSCEntry& tsc) c
const bool arbitrary_borders = device.IsExtCustomBorderColorSupported(); const bool arbitrary_borders = device.IsExtCustomBorderColorSupported();
const std::array color = tsc.GetBorderColor(); const std::array color = tsc.GetBorderColor();
VkSamplerCustomBorderColorCreateInfoEXT border; VkSamplerCustomBorderColorCreateInfoEXT border{
border.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT; .sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT,
border.pNext = nullptr; .pNext = nullptr,
border.format = VK_FORMAT_UNDEFINED; .format = VK_FORMAT_UNDEFINED,
};
std::memcpy(&border.customBorderColor, color.data(), sizeof(color)); std::memcpy(&border.customBorderColor, color.data(), sizeof(color));
VkSamplerCreateInfo ci; return device.GetLogical().CreateSampler({
ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
ci.pNext = arbitrary_borders ? &border : nullptr; .pNext = arbitrary_borders ? &border : nullptr,
ci.flags = 0; .flags = 0,
ci.magFilter = MaxwellToVK::Sampler::Filter(tsc.mag_filter); .magFilter = MaxwellToVK::Sampler::Filter(tsc.mag_filter),
ci.minFilter = MaxwellToVK::Sampler::Filter(tsc.min_filter); .minFilter = MaxwellToVK::Sampler::Filter(tsc.min_filter),
ci.mipmapMode = MaxwellToVK::Sampler::MipmapMode(tsc.mipmap_filter); .mipmapMode = MaxwellToVK::Sampler::MipmapMode(tsc.mipmap_filter),
ci.addressModeU = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_u, tsc.mag_filter); .addressModeU = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_u, tsc.mag_filter),
ci.addressModeV = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_v, tsc.mag_filter); .addressModeV = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_v, tsc.mag_filter),
ci.addressModeW = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_p, tsc.mag_filter); .addressModeW = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_p, tsc.mag_filter),
ci.mipLodBias = tsc.GetLodBias(); .mipLodBias = tsc.GetLodBias(),
ci.anisotropyEnable = tsc.GetMaxAnisotropy() > 1.0f ? VK_TRUE : VK_FALSE; .anisotropyEnable =
ci.maxAnisotropy = tsc.GetMaxAnisotropy(); static_cast<VkBool32>(tsc.GetMaxAnisotropy() > 1.0f ? VK_TRUE : VK_FALSE),
ci.compareEnable = tsc.depth_compare_enabled; .maxAnisotropy = tsc.GetMaxAnisotropy(),
ci.compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func); .compareEnable = tsc.depth_compare_enabled,
ci.minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.GetMinLod(); .compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func),
ci.maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.GetMaxLod(); .minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.GetMinLod(),
ci.borderColor = arbitrary_borders ? VK_BORDER_COLOR_INT_CUSTOM_EXT : ConvertBorderColor(color); .maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.GetMaxLod(),
ci.unnormalizedCoordinates = VK_FALSE; .borderColor =
return device.GetLogical().CreateSampler(ci); arbitrary_borders ? VK_BORDER_COLOR_INT_CUSTOM_EXT : ConvertBorderColor(color),
.unnormalizedCoordinates = VK_FALSE,
});
} }
VkSampler VKSamplerCache::ToSamplerType(const vk::Sampler& sampler) const { VkSampler VKSamplerCache::ToSamplerType(const vk::Sampler& sampler) const {

@ -100,16 +100,19 @@ void VKScheduler::RequestRenderpass(VkRenderPass renderpass, VkFramebuffer frame
state.framebuffer = framebuffer; state.framebuffer = framebuffer;
state.render_area = render_area; state.render_area = render_area;
VkRenderPassBeginInfo renderpass_bi; const VkRenderPassBeginInfo renderpass_bi{
renderpass_bi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
renderpass_bi.pNext = nullptr; .pNext = nullptr,
renderpass_bi.renderPass = renderpass; .renderPass = renderpass,
renderpass_bi.framebuffer = framebuffer; .framebuffer = framebuffer,
renderpass_bi.renderArea.offset.x = 0; .renderArea =
renderpass_bi.renderArea.offset.y = 0; {
renderpass_bi.renderArea.extent = render_area; .offset = {.x = 0, .y = 0},
renderpass_bi.clearValueCount = 0; .extent = render_area,
renderpass_bi.pClearValues = nullptr; },
.clearValueCount = 0,
.pClearValues = nullptr,
};
Record([renderpass_bi, end_renderpass](vk::CommandBuffer cmdbuf) { Record([renderpass_bi, end_renderpass](vk::CommandBuffer cmdbuf) {
if (end_renderpass) { if (end_renderpass) {
@ -157,16 +160,17 @@ void VKScheduler::SubmitExecution(VkSemaphore semaphore) {
current_cmdbuf.End(); current_cmdbuf.End();
VkSubmitInfo submit_info; const VkSubmitInfo submit_info{
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
submit_info.pNext = nullptr; .pNext = nullptr,
submit_info.waitSemaphoreCount = 0; .waitSemaphoreCount = 0,
submit_info.pWaitSemaphores = nullptr; .pWaitSemaphores = nullptr,
submit_info.pWaitDstStageMask = nullptr; .pWaitDstStageMask = nullptr,
submit_info.commandBufferCount = 1; .commandBufferCount = 1,
submit_info.pCommandBuffers = current_cmdbuf.address(); .pCommandBuffers = current_cmdbuf.address(),
submit_info.signalSemaphoreCount = semaphore ? 1 : 0; .signalSemaphoreCount = semaphore ? 1U : 0U,
submit_info.pSignalSemaphores = &semaphore; .pSignalSemaphores = &semaphore,
};
switch (const VkResult result = device.GetGraphicsQueue().Submit(submit_info, *current_fence)) { switch (const VkResult result = device.GetGraphicsQueue().Submit(submit_info, *current_fence)) {
case VK_SUCCESS: case VK_SUCCESS:
break; break;
@ -181,19 +185,18 @@ void VKScheduler::SubmitExecution(VkSemaphore semaphore) {
void VKScheduler::AllocateNewContext() { void VKScheduler::AllocateNewContext() {
++ticks; ++ticks;
VkCommandBufferBeginInfo cmdbuf_bi;
cmdbuf_bi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
cmdbuf_bi.pNext = nullptr;
cmdbuf_bi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
cmdbuf_bi.pInheritanceInfo = nullptr;
std::unique_lock lock{mutex}; std::unique_lock lock{mutex};
current_fence = next_fence; current_fence = next_fence;
next_fence = &resource_manager.CommitFence(); next_fence = &resource_manager.CommitFence();
current_cmdbuf = vk::CommandBuffer(resource_manager.CommitCommandBuffer(*current_fence), current_cmdbuf = vk::CommandBuffer(resource_manager.CommitCommandBuffer(*current_fence),
device.GetDispatchLoader()); device.GetDispatchLoader());
current_cmdbuf.Begin(cmdbuf_bi); current_cmdbuf.Begin({
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.pNext = nullptr,
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
.pInheritanceInfo = nullptr,
});
// Enable counters once again. These are disabled when a command buffer is finished. // Enable counters once again. These are disabled when a command buffer is finished.
if (query_cache) { if (query_cache) {

@ -19,13 +19,13 @@ vk::ShaderModule BuildShader(const VKDevice& device, std::size_t code_size, cons
const auto data = std::make_unique<u32[]>(code_size / sizeof(u32)); const auto data = std::make_unique<u32[]>(code_size / sizeof(u32));
std::memcpy(data.get(), code_data, code_size); std::memcpy(data.get(), code_data, code_size);
VkShaderModuleCreateInfo ci; return device.GetLogical().CreateShaderModule({
ci.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.codeSize = code_size; .codeSize = code_size,
ci.pCode = data.get(); .pCode = data.get(),
return device.GetLogical().CreateShaderModule(ci); });
} }
} // namespace Vulkan } // namespace Vulkan

@ -71,20 +71,19 @@ VKBuffer* VKStagingBufferPool::TryGetReservedBuffer(std::size_t size, bool host_
VKBuffer& VKStagingBufferPool::CreateStagingBuffer(std::size_t size, bool host_visible) { VKBuffer& VKStagingBufferPool::CreateStagingBuffer(std::size_t size, bool host_visible) {
const u32 log2 = Common::Log2Ceil64(size); const u32 log2 = Common::Log2Ceil64(size);
VkBufferCreateInfo ci;
ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
ci.pNext = nullptr;
ci.flags = 0;
ci.size = 1ULL << log2;
ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
ci.queueFamilyIndexCount = 0;
ci.pQueueFamilyIndices = nullptr;
auto buffer = std::make_unique<VKBuffer>(); auto buffer = std::make_unique<VKBuffer>();
buffer->handle = device.GetLogical().CreateBuffer(ci); buffer->handle = device.GetLogical().CreateBuffer({
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = 1ULL << log2,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,
});
buffer->commit = memory_manager.Commit(buffer->handle, host_visible); buffer->commit = memory_manager.Commit(buffer->handle, host_visible);
auto& entries = GetCache(host_visible)[log2].entries; auto& entries = GetCache(host_visible)[log2].entries;

@ -122,30 +122,27 @@ void VKStreamBuffer::CreateBuffers(VkBufferUsageFlags usage) {
// Substract from the preferred heap size some bytes to avoid getting out of memory. // Substract from the preferred heap size some bytes to avoid getting out of memory.
const VkDeviceSize heap_size = memory_properties.memoryHeaps[preferred_heap].size; const VkDeviceSize heap_size = memory_properties.memoryHeaps[preferred_heap].size;
const VkDeviceSize allocable_size = heap_size - 9 * 1024 * 1024; const VkDeviceSize allocable_size = heap_size - 9 * 1024 * 1024;
buffer = device.GetLogical().CreateBuffer({
VkBufferCreateInfo buffer_ci; .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
buffer_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; .pNext = nullptr,
buffer_ci.pNext = nullptr; .flags = 0,
buffer_ci.flags = 0; .size = std::min(PREFERRED_STREAM_BUFFER_SIZE, allocable_size),
buffer_ci.size = std::min(PREFERRED_STREAM_BUFFER_SIZE, allocable_size); .usage = usage,
buffer_ci.usage = usage; .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
buffer_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; .queueFamilyIndexCount = 0,
buffer_ci.queueFamilyIndexCount = 0; .pQueueFamilyIndices = nullptr,
buffer_ci.pQueueFamilyIndices = nullptr; });
buffer = device.GetLogical().CreateBuffer(buffer_ci);
const auto requirements = device.GetLogical().GetBufferMemoryRequirements(*buffer); const auto requirements = device.GetLogical().GetBufferMemoryRequirements(*buffer);
const u32 required_flags = requirements.memoryTypeBits; const u32 required_flags = requirements.memoryTypeBits;
stream_buffer_size = static_cast<u64>(requirements.size); stream_buffer_size = static_cast<u64>(requirements.size);
VkMemoryAllocateInfo memory_ai; memory = device.GetLogical().AllocateMemory({
memory_ai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
memory_ai.pNext = nullptr; .pNext = nullptr,
memory_ai.allocationSize = requirements.size; .allocationSize = requirements.size,
memory_ai.memoryTypeIndex = GetMemoryType(memory_properties, required_flags); .memoryTypeIndex = GetMemoryType(memory_properties, required_flags),
});
memory = device.GetLogical().AllocateMemory(memory_ai);
buffer.BindMemory(*memory, 0); buffer.BindMemory(*memory, 0);
} }

@ -95,15 +95,16 @@ bool VKSwapchain::Present(VkSemaphore render_semaphore, VKFence& fence) {
const auto present_queue{device.GetPresentQueue()}; const auto present_queue{device.GetPresentQueue()};
bool recreated = false; bool recreated = false;
VkPresentInfoKHR present_info; const VkPresentInfoKHR present_info{
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
present_info.pNext = nullptr; .pNext = nullptr,
present_info.waitSemaphoreCount = render_semaphore ? 2U : 1U; .waitSemaphoreCount = render_semaphore ? 2U : 1U,
present_info.pWaitSemaphores = semaphores.data(); .pWaitSemaphores = semaphores.data(),
present_info.swapchainCount = 1; .swapchainCount = 1,
present_info.pSwapchains = swapchain.address(); .pSwapchains = swapchain.address(),
present_info.pImageIndices = &image_index; .pImageIndices = &image_index,
present_info.pResults = nullptr; .pResults = nullptr,
};
switch (const VkResult result = present_queue.Present(present_info)) { switch (const VkResult result = present_queue.Present(present_info)) {
case VK_SUCCESS: case VK_SUCCESS:
@ -147,24 +148,25 @@ void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities,
requested_image_count = capabilities.maxImageCount; requested_image_count = capabilities.maxImageCount;
} }
VkSwapchainCreateInfoKHR swapchain_ci; VkSwapchainCreateInfoKHR swapchain_ci{
swapchain_ci.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
swapchain_ci.pNext = nullptr; .pNext = nullptr,
swapchain_ci.flags = 0; .flags = 0,
swapchain_ci.surface = surface; .surface = surface,
swapchain_ci.minImageCount = requested_image_count; .minImageCount = requested_image_count,
swapchain_ci.imageFormat = surface_format.format; .imageFormat = surface_format.format,
swapchain_ci.imageColorSpace = surface_format.colorSpace; .imageColorSpace = surface_format.colorSpace,
swapchain_ci.imageArrayLayers = 1; .imageArrayLayers = 1,
swapchain_ci.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
swapchain_ci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
swapchain_ci.queueFamilyIndexCount = 0; .queueFamilyIndexCount = 0,
swapchain_ci.pQueueFamilyIndices = nullptr; .pQueueFamilyIndices = nullptr,
swapchain_ci.preTransform = capabilities.currentTransform; .preTransform = capabilities.currentTransform,
swapchain_ci.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
swapchain_ci.presentMode = present_mode; .presentMode = present_mode,
swapchain_ci.clipped = VK_FALSE; .clipped = VK_FALSE,
swapchain_ci.oldSwapchain = nullptr; .oldSwapchain = nullptr,
};
const u32 graphics_family{device.GetGraphicsFamily()}; const u32 graphics_family{device.GetGraphicsFamily()};
const u32 present_family{device.GetPresentFamily()}; const u32 present_family{device.GetPresentFamily()};
@ -173,8 +175,6 @@ void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities,
swapchain_ci.imageSharingMode = VK_SHARING_MODE_CONCURRENT; swapchain_ci.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
swapchain_ci.queueFamilyIndexCount = static_cast<u32>(queue_indices.size()); swapchain_ci.queueFamilyIndexCount = static_cast<u32>(queue_indices.size());
swapchain_ci.pQueueFamilyIndices = queue_indices.data(); swapchain_ci.pQueueFamilyIndices = queue_indices.data();
} else {
swapchain_ci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
} }
// Request the size again to reduce the possibility of a TOCTOU race condition. // Request the size again to reduce the possibility of a TOCTOU race condition.
@ -200,20 +200,28 @@ void VKSwapchain::CreateSemaphores() {
} }
void VKSwapchain::CreateImageViews() { void VKSwapchain::CreateImageViews() {
VkImageViewCreateInfo ci; VkImageViewCreateInfo ci{
ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
// ci.image .viewType = VK_IMAGE_VIEW_TYPE_2D,
ci.viewType = VK_IMAGE_VIEW_TYPE_2D; .format = image_format,
ci.format = image_format; .components =
ci.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, {
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}; .r = VK_COMPONENT_SWIZZLE_IDENTITY,
ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; .g = VK_COMPONENT_SWIZZLE_IDENTITY,
ci.subresourceRange.baseMipLevel = 0; .b = VK_COMPONENT_SWIZZLE_IDENTITY,
ci.subresourceRange.levelCount = 1; .a = VK_COMPONENT_SWIZZLE_IDENTITY,
ci.subresourceRange.baseArrayLayer = 0; },
ci.subresourceRange.layerCount = 1; .subresourceRange =
{
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
};
image_views.resize(image_count); image_views.resize(image_count);
for (std::size_t i = 0; i < image_count; i++) { for (std::size_t i = 0; i < image_count; i++) {

@ -95,17 +95,18 @@ VkImageViewType GetImageViewType(SurfaceTarget target) {
vk::Buffer CreateBuffer(const VKDevice& device, const SurfaceParams& params, vk::Buffer CreateBuffer(const VKDevice& device, const SurfaceParams& params,
std::size_t host_memory_size) { std::size_t host_memory_size) {
// TODO(Rodrigo): Move texture buffer creation to the buffer cache // TODO(Rodrigo): Move texture buffer creation to the buffer cache
VkBufferCreateInfo ci; return device.GetLogical().CreateBuffer({
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 = static_cast<VkDeviceSize>(host_memory_size); .size = static_cast<VkDeviceSize>(host_memory_size),
ci.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | .usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; VK_BUFFER_USAGE_TRANSFER_DST_BIT,
ci.queueFamilyIndexCount = 0; .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
ci.pQueueFamilyIndices = nullptr; .queueFamilyIndexCount = 0,
return device.GetLogical().CreateBuffer(ci); .pQueueFamilyIndices = nullptr,
});
} }
VkBufferViewCreateInfo GenerateBufferViewCreateInfo(const VKDevice& device, VkBufferViewCreateInfo GenerateBufferViewCreateInfo(const VKDevice& device,
@ -113,15 +114,16 @@ VkBufferViewCreateInfo GenerateBufferViewCreateInfo(const VKDevice& device,
std::size_t host_memory_size) { std::size_t host_memory_size) {
ASSERT(params.IsBuffer()); ASSERT(params.IsBuffer());
VkBufferViewCreateInfo ci; return {
ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.buffer = buffer; .buffer = buffer,
ci.format = MaxwellToVK::SurfaceFormat(device, FormatType::Buffer, params.pixel_format).format; .format =
ci.offset = 0; MaxwellToVK::SurfaceFormat(device, FormatType::Buffer, params.pixel_format).format,
ci.range = static_cast<VkDeviceSize>(host_memory_size); .offset = 0,
return ci; .range = static_cast<VkDeviceSize>(host_memory_size),
};
} }
VkImageCreateInfo GenerateImageCreateInfo(const VKDevice& device, const SurfaceParams& params) { VkImageCreateInfo GenerateImageCreateInfo(const VKDevice& device, const SurfaceParams& params) {
@ -130,23 +132,23 @@ VkImageCreateInfo GenerateImageCreateInfo(const VKDevice& device, const SurfaceP
const auto [format, attachable, storage] = const auto [format, attachable, storage] =
MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, params.pixel_format); MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, params.pixel_format);
VkImageCreateInfo ci; 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 = SurfaceTargetToImage(params.target); .imageType = SurfaceTargetToImage(params.target),
ci.format = format; .format = format,
ci.mipLevels = params.num_levels; .mipLevels = params.num_levels,
ci.arrayLayers = static_cast<u32>(params.GetNumLayers()); .arrayLayers = static_cast<u32>(params.GetNumLayers()),
ci.samples = VK_SAMPLE_COUNT_1_BIT; .samples = VK_SAMPLE_COUNT_1_BIT,
ci.tiling = VK_IMAGE_TILING_OPTIMAL; .tiling = VK_IMAGE_TILING_OPTIMAL,
ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; .usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
ci.queueFamilyIndexCount = 0; VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
ci.pQueueFamilyIndices = nullptr; .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; .queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,
ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT; };
if (attachable) { if (attachable) {
ci.usage |= params.IsPixelFormatZeta() ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ci.usage |= params.IsPixelFormatZeta() ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
@ -321,22 +323,25 @@ void CachedSurface::UploadImage(const std::vector<u8>& staging_buffer) {
} }
VkBufferImageCopy CachedSurface::GetBufferImageCopy(u32 level) const { VkBufferImageCopy CachedSurface::GetBufferImageCopy(u32 level) const {
VkBufferImageCopy copy; return {
copy.bufferOffset = params.GetHostMipmapLevelOffset(level, is_converted); .bufferOffset = params.GetHostMipmapLevelOffset(level, is_converted),
copy.bufferRowLength = 0; .bufferRowLength = 0,
copy.bufferImageHeight = 0; .bufferImageHeight = 0,
copy.imageSubresource.aspectMask = image->GetAspectMask(); .imageSubresource =
copy.imageSubresource.mipLevel = level; {
copy.imageSubresource.baseArrayLayer = 0; .aspectMask = image->GetAspectMask(),
copy.imageSubresource.layerCount = static_cast<u32>(params.GetNumLayers()); .mipLevel = level,
copy.imageOffset.x = 0; .baseArrayLayer = 0,
copy.imageOffset.y = 0; .layerCount = static_cast<u32>(params.GetNumLayers()),
copy.imageOffset.z = 0; },
copy.imageExtent.width = params.GetMipWidth(level); .imageOffset = {.x = 0, .y = 0, .z = 0},
copy.imageExtent.height = params.GetMipHeight(level); .imageExtent =
copy.imageExtent.depth = {
params.target == SurfaceTarget::Texture3D ? params.GetMipDepth(level) : 1; .width = params.GetMipWidth(level),
return copy; .height = params.GetMipHeight(level),
.depth = params.target == SurfaceTarget::Texture3D ? params.GetMipDepth(level) : 1U,
},
};
} }
VkImageSubresourceRange CachedSurface::GetImageSubresourceRange() const { VkImageSubresourceRange CachedSurface::GetImageSubresourceRange() const {
@ -416,20 +421,29 @@ VkImageView CachedSurfaceView::GetImageView(SwizzleSource x_source, SwizzleSourc
ASSERT(num_slices == params.depth); ASSERT(num_slices == params.depth);
} }
VkImageViewCreateInfo ci; image_view = device.GetLogical().CreateImageView({
ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.image = surface.GetImageHandle(); .image = surface.GetImageHandle(),
ci.viewType = image_view_type; .viewType = image_view_type,
ci.format = surface.GetImage().GetFormat(); .format = surface.GetImage().GetFormat(),
ci.components = {swizzle[0], swizzle[1], swizzle[2], swizzle[3]}; .components =
ci.subresourceRange.aspectMask = aspect; {
ci.subresourceRange.baseMipLevel = base_level; .r = swizzle[0],
ci.subresourceRange.levelCount = num_levels; .g = swizzle[1],
ci.subresourceRange.baseArrayLayer = base_layer; .b = swizzle[2],
ci.subresourceRange.layerCount = num_layers; .a = swizzle[3],
image_view = device.GetLogical().CreateImageView(ci); },
.subresourceRange =
{
.aspectMask = aspect,
.baseMipLevel = base_level,
.levelCount = num_levels,
.baseArrayLayer = base_layer,
.layerCount = num_layers,
},
});
return last_image_view = *image_view; return last_image_view = *image_view;
} }
@ -439,17 +453,26 @@ VkImageView CachedSurfaceView::GetAttachment() {
return *render_target; return *render_target;
} }
VkImageViewCreateInfo ci; VkImageViewCreateInfo ci{
ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.image = surface.GetImageHandle(); .image = surface.GetImageHandle(),
ci.format = surface.GetImage().GetFormat(); .format = surface.GetImage().GetFormat(),
ci.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, .components =
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}; {
ci.subresourceRange.aspectMask = aspect_mask; .r = VK_COMPONENT_SWIZZLE_IDENTITY,
ci.subresourceRange.baseMipLevel = base_level; .g = VK_COMPONENT_SWIZZLE_IDENTITY,
ci.subresourceRange.levelCount = num_levels; .b = VK_COMPONENT_SWIZZLE_IDENTITY,
.a = VK_COMPONENT_SWIZZLE_IDENTITY,
},
.subresourceRange =
{
.aspectMask = aspect_mask,
.baseMipLevel = base_level,
.levelCount = num_levels,
},
};
if (image_view_type == VK_IMAGE_VIEW_TYPE_3D) { if (image_view_type == VK_IMAGE_VIEW_TYPE_3D) {
ci.viewType = num_slices > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D; ci.viewType = num_slices > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
ci.subresourceRange.baseArrayLayer = base_slice; ci.subresourceRange.baseArrayLayer = base_slice;
@ -502,24 +525,40 @@ void VKTextureCache::ImageCopy(Surface& src_surface, Surface& dst_surface,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkImageCopy copy; const VkImageCopy copy{
copy.srcSubresource.aspectMask = src_surface->GetAspectMask(); .srcSubresource =
copy.srcSubresource.mipLevel = copy_params.source_level; {
copy.srcSubresource.baseArrayLayer = copy_params.source_z; .aspectMask = src_surface->GetAspectMask(),
copy.srcSubresource.layerCount = num_layers; .mipLevel = copy_params.source_level,
copy.srcOffset.x = copy_params.source_x; .baseArrayLayer = copy_params.source_z,
copy.srcOffset.y = copy_params.source_y; .layerCount = num_layers,
copy.srcOffset.z = 0; },
copy.dstSubresource.aspectMask = dst_surface->GetAspectMask(); .srcOffset =
copy.dstSubresource.mipLevel = copy_params.dest_level; {
copy.dstSubresource.baseArrayLayer = dst_base_layer; .x = static_cast<s32>(copy_params.source_x),
copy.dstSubresource.layerCount = num_layers; .y = static_cast<s32>(copy_params.source_y),
copy.dstOffset.x = copy_params.dest_x; .z = 0,
copy.dstOffset.y = copy_params.dest_y; },
copy.dstOffset.z = dst_offset_z; .dstSubresource =
copy.extent.width = copy_params.width; {
copy.extent.height = copy_params.height; .aspectMask = dst_surface->GetAspectMask(),
copy.extent.depth = extent_z; .mipLevel = copy_params.dest_level,
.baseArrayLayer = dst_base_layer,
.layerCount = num_layers,
},
.dstOffset =
{
.x = static_cast<s32>(copy_params.dest_x),
.y = static_cast<s32>(copy_params.dest_y),
.z = static_cast<s32>(dst_offset_z),
},
.extent =
{
.width = copy_params.width,
.height = copy_params.height,
.depth = extent_z,
},
};
const VkImage src_image = src_surface->GetImageHandle(); const VkImage src_image = src_surface->GetImageHandle();
const VkImage dst_image = dst_surface->GetImageHandle(); const VkImage dst_image = dst_surface->GetImageHandle();

@ -377,24 +377,26 @@ VkResult Free(VkDevice device, VkCommandPool handle, Span<VkCommandBuffer> buffe
Instance Instance::Create(Span<const char*> layers, Span<const char*> extensions, Instance Instance::Create(Span<const char*> layers, Span<const char*> extensions,
InstanceDispatch& dld) noexcept { InstanceDispatch& dld) noexcept {
VkApplicationInfo application_info; static constexpr VkApplicationInfo application_info{
application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
application_info.pNext = nullptr; .pNext = nullptr,
application_info.pApplicationName = "yuzu Emulator"; .pApplicationName = "yuzu Emulator",
application_info.applicationVersion = VK_MAKE_VERSION(0, 1, 0); .applicationVersion = VK_MAKE_VERSION(0, 1, 0),
application_info.pEngineName = "yuzu Emulator"; .pEngineName = "yuzu Emulator",
application_info.engineVersion = VK_MAKE_VERSION(0, 1, 0); .engineVersion = VK_MAKE_VERSION(0, 1, 0),
application_info.apiVersion = VK_API_VERSION_1_1; .apiVersion = VK_API_VERSION_1_1,
};
VkInstanceCreateInfo ci; const VkInstanceCreateInfo ci{
ci.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.pApplicationInfo = &application_info; .pApplicationInfo = &application_info,
ci.enabledLayerCount = layers.size(); .enabledLayerCount = layers.size(),
ci.ppEnabledLayerNames = layers.data(); .ppEnabledLayerNames = layers.data(),
ci.enabledExtensionCount = extensions.size(); .enabledExtensionCount = extensions.size(),
ci.ppEnabledExtensionNames = extensions.data(); .ppEnabledExtensionNames = extensions.data(),
};
VkInstance instance; VkInstance instance;
if (dld.vkCreateInstance(&ci, nullptr, &instance) != VK_SUCCESS) { if (dld.vkCreateInstance(&ci, nullptr, &instance) != VK_SUCCESS) {
@ -425,19 +427,20 @@ std::optional<std::vector<VkPhysicalDevice>> Instance::EnumeratePhysicalDevices(
DebugCallback Instance::TryCreateDebugCallback( DebugCallback Instance::TryCreateDebugCallback(
PFN_vkDebugUtilsMessengerCallbackEXT callback) noexcept { PFN_vkDebugUtilsMessengerCallbackEXT callback) noexcept {
VkDebugUtilsMessengerCreateInfoEXT ci; const VkDebugUtilsMessengerCreateInfoEXT ci{
ci.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
ci.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT; VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT,
ci.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
ci.pfnUserCallback = callback; .pfnUserCallback = callback,
ci.pUserData = nullptr; .pUserData = nullptr,
};
VkDebugUtilsMessengerEXT messenger; VkDebugUtilsMessengerEXT messenger;
if (dld->vkCreateDebugUtilsMessengerEXT(handle, &ci, nullptr, &messenger) != VK_SUCCESS) { if (dld->vkCreateDebugUtilsMessengerEXT(handle, &ci, nullptr, &messenger) != VK_SUCCESS) {
@ -468,12 +471,13 @@ DescriptorSets DescriptorPool::Allocate(const VkDescriptorSetAllocateInfo& ai) c
} }
CommandBuffers CommandPool::Allocate(std::size_t num_buffers, VkCommandBufferLevel level) const { CommandBuffers CommandPool::Allocate(std::size_t num_buffers, VkCommandBufferLevel level) const {
VkCommandBufferAllocateInfo ai; const VkCommandBufferAllocateInfo ai{
ai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
ai.pNext = nullptr; .pNext = nullptr,
ai.commandPool = handle; .commandPool = handle,
ai.level = level; .level = level,
ai.commandBufferCount = static_cast<u32>(num_buffers); .commandBufferCount = static_cast<u32>(num_buffers),
};
std::unique_ptr buffers = std::make_unique<VkCommandBuffer[]>(num_buffers); std::unique_ptr buffers = std::make_unique<VkCommandBuffer[]>(num_buffers);
switch (const VkResult result = dld->vkAllocateCommandBuffers(owner, &ai, buffers.get())) { switch (const VkResult result = dld->vkAllocateCommandBuffers(owner, &ai, buffers.get())) {
@ -497,17 +501,18 @@ std::vector<VkImage> SwapchainKHR::GetImages() const {
Device Device::Create(VkPhysicalDevice physical_device, Span<VkDeviceQueueCreateInfo> queues_ci, Device Device::Create(VkPhysicalDevice physical_device, Span<VkDeviceQueueCreateInfo> queues_ci,
Span<const char*> enabled_extensions, const void* next, Span<const char*> enabled_extensions, const void* next,
DeviceDispatch& dld) noexcept { DeviceDispatch& dld) noexcept {
VkDeviceCreateInfo ci; const VkDeviceCreateInfo ci{
ci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
ci.pNext = next; .pNext = next,
ci.flags = 0; .flags = 0,
ci.queueCreateInfoCount = queues_ci.size(); .queueCreateInfoCount = queues_ci.size(),
ci.pQueueCreateInfos = queues_ci.data(); .pQueueCreateInfos = queues_ci.data(),
ci.enabledLayerCount = 0; .enabledLayerCount = 0,
ci.ppEnabledLayerNames = nullptr; .ppEnabledLayerNames = nullptr,
ci.enabledExtensionCount = enabled_extensions.size(); .enabledExtensionCount = enabled_extensions.size(),
ci.ppEnabledExtensionNames = enabled_extensions.data(); .ppEnabledExtensionNames = enabled_extensions.data(),
ci.pEnabledFeatures = nullptr; .pEnabledFeatures = nullptr,
};
VkDevice device; VkDevice device;
if (dld.vkCreateDevice(physical_device, &ci, nullptr, &device) != VK_SUCCESS) { if (dld.vkCreateDevice(physical_device, &ci, nullptr, &device) != VK_SUCCESS) {
@ -548,10 +553,11 @@ ImageView Device::CreateImageView(const VkImageViewCreateInfo& ci) const {
} }
Semaphore Device::CreateSemaphore() const { Semaphore Device::CreateSemaphore() const {
VkSemaphoreCreateInfo ci; static constexpr VkSemaphoreCreateInfo ci{
ci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
};
VkSemaphore object; VkSemaphore object;
Check(dld->vkCreateSemaphore(handle, &ci, nullptr, &object)); Check(dld->vkCreateSemaphore(handle, &ci, nullptr, &object));
@ -639,10 +645,12 @@ ShaderModule Device::CreateShaderModule(const VkShaderModuleCreateInfo& ci) cons
} }
Event Device::CreateEvent() const { Event Device::CreateEvent() const {
VkEventCreateInfo ci; static constexpr VkEventCreateInfo ci{
ci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; .sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
ci.pNext = nullptr; .pNext = nullptr,
ci.flags = 0; .flags = 0,
};
VkEvent object; VkEvent object;
Check(dld->vkCreateEvent(handle, &ci, nullptr, &object)); Check(dld->vkCreateEvent(handle, &ci, nullptr, &object));
return Event(object, handle, *dld); return Event(object, handle, *dld);