diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 231 |
1 files changed, 135 insertions, 96 deletions
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 430031665..99b21a543 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -95,17 +95,18 @@ VkImageViewType GetImageViewType(SurfaceTarget target) { | |||
| 95 | vk::Buffer CreateBuffer(const VKDevice& device, const SurfaceParams& params, | 95 | vk::Buffer CreateBuffer(const VKDevice& device, const SurfaceParams& params, |
| 96 | std::size_t host_memory_size) { | 96 | std::size_t host_memory_size) { |
| 97 | // TODO(Rodrigo): Move texture buffer creation to the buffer cache | 97 | // TODO(Rodrigo): Move texture buffer creation to the buffer cache |
| 98 | VkBufferCreateInfo ci; | 98 | return device.GetLogical().CreateBuffer({ |
| 99 | ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; | 99 | .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, |
| 100 | ci.pNext = nullptr; | 100 | .pNext = nullptr, |
| 101 | ci.flags = 0; | 101 | .flags = 0, |
| 102 | ci.size = static_cast<VkDeviceSize>(host_memory_size); | 102 | .size = static_cast<VkDeviceSize>(host_memory_size), |
| 103 | ci.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | | 103 | .usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | |
| 104 | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; | 104 | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | |
| 105 | ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; | 105 | VK_BUFFER_USAGE_TRANSFER_DST_BIT, |
| 106 | ci.queueFamilyIndexCount = 0; | 106 | .sharingMode = VK_SHARING_MODE_EXCLUSIVE, |
| 107 | ci.pQueueFamilyIndices = nullptr; | 107 | .queueFamilyIndexCount = 0, |
| 108 | return device.GetLogical().CreateBuffer(ci); | 108 | .pQueueFamilyIndices = nullptr, |
| 109 | }); | ||
| 109 | } | 110 | } |
| 110 | 111 | ||
| 111 | VkBufferViewCreateInfo GenerateBufferViewCreateInfo(const VKDevice& device, | 112 | VkBufferViewCreateInfo GenerateBufferViewCreateInfo(const VKDevice& device, |
| @@ -113,15 +114,16 @@ VkBufferViewCreateInfo GenerateBufferViewCreateInfo(const VKDevice& device, | |||
| 113 | std::size_t host_memory_size) { | 114 | std::size_t host_memory_size) { |
| 114 | ASSERT(params.IsBuffer()); | 115 | ASSERT(params.IsBuffer()); |
| 115 | 116 | ||
| 116 | VkBufferViewCreateInfo ci; | 117 | return { |
| 117 | ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; | 118 | .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, |
| 118 | ci.pNext = nullptr; | 119 | .pNext = nullptr, |
| 119 | ci.flags = 0; | 120 | .flags = 0, |
| 120 | ci.buffer = buffer; | 121 | .buffer = buffer, |
| 121 | ci.format = MaxwellToVK::SurfaceFormat(device, FormatType::Buffer, params.pixel_format).format; | 122 | .format = |
| 122 | ci.offset = 0; | 123 | MaxwellToVK::SurfaceFormat(device, FormatType::Buffer, params.pixel_format).format, |
| 123 | ci.range = static_cast<VkDeviceSize>(host_memory_size); | 124 | .offset = 0, |
| 124 | return ci; | 125 | .range = static_cast<VkDeviceSize>(host_memory_size), |
| 126 | }; | ||
| 125 | } | 127 | } |
| 126 | 128 | ||
| 127 | VkImageCreateInfo GenerateImageCreateInfo(const VKDevice& device, const SurfaceParams& params) { | 129 | VkImageCreateInfo GenerateImageCreateInfo(const VKDevice& device, const SurfaceParams& params) { |
| @@ -130,23 +132,23 @@ VkImageCreateInfo GenerateImageCreateInfo(const VKDevice& device, const SurfaceP | |||
| 130 | const auto [format, attachable, storage] = | 132 | const auto [format, attachable, storage] = |
| 131 | MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, params.pixel_format); | 133 | MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, params.pixel_format); |
| 132 | 134 | ||
| 133 | VkImageCreateInfo ci; | 135 | VkImageCreateInfo ci{ |
| 134 | ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; | 136 | .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, |
| 135 | ci.pNext = nullptr; | 137 | .pNext = nullptr, |
| 136 | ci.flags = 0; | 138 | .flags = 0, |
| 137 | ci.imageType = SurfaceTargetToImage(params.target); | 139 | .imageType = SurfaceTargetToImage(params.target), |
| 138 | ci.format = format; | 140 | .format = format, |
| 139 | ci.mipLevels = params.num_levels; | 141 | .mipLevels = params.num_levels, |
| 140 | ci.arrayLayers = static_cast<u32>(params.GetNumLayers()); | 142 | .arrayLayers = static_cast<u32>(params.GetNumLayers()), |
| 141 | ci.samples = VK_SAMPLE_COUNT_1_BIT; | 143 | .samples = VK_SAMPLE_COUNT_1_BIT, |
| 142 | ci.tiling = VK_IMAGE_TILING_OPTIMAL; | 144 | .tiling = VK_IMAGE_TILING_OPTIMAL, |
| 143 | ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; | 145 | .usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | |
| 144 | ci.queueFamilyIndexCount = 0; | 146 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, |
| 145 | ci.pQueueFamilyIndices = nullptr; | 147 | .sharingMode = VK_SHARING_MODE_EXCLUSIVE, |
| 146 | ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; | 148 | .queueFamilyIndexCount = 0, |
| 147 | 149 | .pQueueFamilyIndices = nullptr, | |
| 148 | ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | | 150 | .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, |
| 149 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; | 151 | }; |
| 150 | if (attachable) { | 152 | if (attachable) { |
| 151 | ci.usage |= params.IsPixelFormatZeta() ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | 153 | ci.usage |= params.IsPixelFormatZeta() ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
| 152 | : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; | 154 | : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| @@ -323,22 +325,25 @@ void CachedSurface::UploadImage(const std::vector<u8>& staging_buffer) { | |||
| 323 | } | 325 | } |
| 324 | 326 | ||
| 325 | VkBufferImageCopy CachedSurface::GetBufferImageCopy(u32 level) const { | 327 | VkBufferImageCopy CachedSurface::GetBufferImageCopy(u32 level) const { |
| 326 | VkBufferImageCopy copy; | 328 | return { |
| 327 | copy.bufferOffset = params.GetHostMipmapLevelOffset(level, is_converted); | 329 | .bufferOffset = params.GetHostMipmapLevelOffset(level, is_converted), |
| 328 | copy.bufferRowLength = 0; | 330 | .bufferRowLength = 0, |
| 329 | copy.bufferImageHeight = 0; | 331 | .bufferImageHeight = 0, |
| 330 | copy.imageSubresource.aspectMask = image->GetAspectMask(); | 332 | .imageSubresource = |
| 331 | copy.imageSubresource.mipLevel = level; | 333 | { |
| 332 | copy.imageSubresource.baseArrayLayer = 0; | 334 | .aspectMask = image->GetAspectMask(), |
| 333 | copy.imageSubresource.layerCount = static_cast<u32>(params.GetNumLayers()); | 335 | .mipLevel = level, |
| 334 | copy.imageOffset.x = 0; | 336 | .baseArrayLayer = 0, |
| 335 | copy.imageOffset.y = 0; | 337 | .layerCount = static_cast<u32>(params.GetNumLayers()), |
| 336 | copy.imageOffset.z = 0; | 338 | }, |
| 337 | copy.imageExtent.width = params.GetMipWidth(level); | 339 | .imageOffset = {.x = 0, .y = 0, .z = 0}, |
| 338 | copy.imageExtent.height = params.GetMipHeight(level); | 340 | .imageExtent = |
| 339 | copy.imageExtent.depth = | 341 | { |
| 340 | params.target == SurfaceTarget::Texture3D ? params.GetMipDepth(level) : 1; | 342 | .width = params.GetMipWidth(level), |
| 341 | return copy; | 343 | .height = params.GetMipHeight(level), |
| 344 | .depth = params.target == SurfaceTarget::Texture3D ? params.GetMipDepth(level) : 1U, | ||
| 345 | }, | ||
| 346 | }; | ||
| 342 | } | 347 | } |
| 343 | 348 | ||
| 344 | VkImageSubresourceRange CachedSurface::GetImageSubresourceRange() const { | 349 | VkImageSubresourceRange CachedSurface::GetImageSubresourceRange() const { |
| @@ -418,20 +423,29 @@ VkImageView CachedSurfaceView::GetImageView(SwizzleSource x_source, SwizzleSourc | |||
| 418 | ASSERT(num_slices == params.depth); | 423 | ASSERT(num_slices == params.depth); |
| 419 | } | 424 | } |
| 420 | 425 | ||
| 421 | VkImageViewCreateInfo ci; | 426 | image_view = device.GetLogical().CreateImageView({ |
| 422 | ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; | 427 | .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, |
| 423 | ci.pNext = nullptr; | 428 | .pNext = nullptr, |
| 424 | ci.flags = 0; | 429 | .flags = 0, |
| 425 | ci.image = surface.GetImageHandle(); | 430 | .image = surface.GetImageHandle(), |
| 426 | ci.viewType = image_view_type; | 431 | .viewType = image_view_type, |
| 427 | ci.format = surface.GetImage().GetFormat(); | 432 | .format = surface.GetImage().GetFormat(), |
| 428 | ci.components = {swizzle[0], swizzle[1], swizzle[2], swizzle[3]}; | 433 | .components = |
| 429 | ci.subresourceRange.aspectMask = aspect; | 434 | { |
| 430 | ci.subresourceRange.baseMipLevel = base_level; | 435 | .r = swizzle[0], |
| 431 | ci.subresourceRange.levelCount = num_levels; | 436 | .g = swizzle[1], |
| 432 | ci.subresourceRange.baseArrayLayer = base_layer; | 437 | .b = swizzle[2], |
| 433 | ci.subresourceRange.layerCount = num_layers; | 438 | .a = swizzle[3], |
| 434 | image_view = device.GetLogical().CreateImageView(ci); | 439 | }, |
| 440 | .subresourceRange = | ||
| 441 | { | ||
| 442 | .aspectMask = aspect, | ||
| 443 | .baseMipLevel = base_level, | ||
| 444 | .levelCount = num_levels, | ||
| 445 | .baseArrayLayer = base_layer, | ||
| 446 | .layerCount = num_layers, | ||
| 447 | }, | ||
| 448 | }); | ||
| 435 | 449 | ||
| 436 | return last_image_view = *image_view; | 450 | return last_image_view = *image_view; |
| 437 | } | 451 | } |
| @@ -441,17 +455,26 @@ VkImageView CachedSurfaceView::GetAttachment() { | |||
| 441 | return *render_target; | 455 | return *render_target; |
| 442 | } | 456 | } |
| 443 | 457 | ||
| 444 | VkImageViewCreateInfo ci; | 458 | VkImageViewCreateInfo ci{ |
| 445 | ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; | 459 | .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, |
| 446 | ci.pNext = nullptr; | 460 | .pNext = nullptr, |
| 447 | ci.flags = 0; | 461 | .flags = 0, |
| 448 | ci.image = surface.GetImageHandle(); | 462 | .image = surface.GetImageHandle(), |
| 449 | ci.format = surface.GetImage().GetFormat(); | 463 | .format = surface.GetImage().GetFormat(), |
| 450 | ci.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, | 464 | .components = |
| 451 | VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}; | 465 | { |
| 452 | ci.subresourceRange.aspectMask = aspect_mask; | 466 | .r = VK_COMPONENT_SWIZZLE_IDENTITY, |
| 453 | ci.subresourceRange.baseMipLevel = base_level; | 467 | .g = VK_COMPONENT_SWIZZLE_IDENTITY, |
| 454 | ci.subresourceRange.levelCount = num_levels; | 468 | .b = VK_COMPONENT_SWIZZLE_IDENTITY, |
| 469 | .a = VK_COMPONENT_SWIZZLE_IDENTITY, | ||
| 470 | }, | ||
| 471 | .subresourceRange = | ||
| 472 | { | ||
| 473 | .aspectMask = aspect_mask, | ||
| 474 | .baseMipLevel = base_level, | ||
| 475 | .levelCount = num_levels, | ||
| 476 | }, | ||
| 477 | }; | ||
| 455 | if (image_view_type == VK_IMAGE_VIEW_TYPE_3D) { | 478 | if (image_view_type == VK_IMAGE_VIEW_TYPE_3D) { |
| 456 | ci.viewType = num_slices > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D; | 479 | ci.viewType = num_slices > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D; |
| 457 | ci.subresourceRange.baseArrayLayer = base_slice; | 480 | ci.subresourceRange.baseArrayLayer = base_slice; |
| @@ -504,24 +527,40 @@ void VKTextureCache::ImageCopy(Surface& src_surface, Surface& dst_surface, | |||
| 504 | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, | 527 | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, |
| 505 | VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); | 528 | VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); |
| 506 | 529 | ||
| 507 | VkImageCopy copy; | 530 | const VkImageCopy copy{ |
| 508 | copy.srcSubresource.aspectMask = src_surface->GetAspectMask(); | 531 | .srcSubresource = |
| 509 | copy.srcSubresource.mipLevel = copy_params.source_level; | 532 | { |
| 510 | copy.srcSubresource.baseArrayLayer = copy_params.source_z; | 533 | .aspectMask = src_surface->GetAspectMask(), |
| 511 | copy.srcSubresource.layerCount = num_layers; | 534 | .mipLevel = copy_params.source_level, |
| 512 | copy.srcOffset.x = copy_params.source_x; | 535 | .baseArrayLayer = copy_params.source_z, |
| 513 | copy.srcOffset.y = copy_params.source_y; | 536 | .layerCount = num_layers, |
| 514 | copy.srcOffset.z = 0; | 537 | }, |
| 515 | copy.dstSubresource.aspectMask = dst_surface->GetAspectMask(); | 538 | .srcOffset = |
| 516 | copy.dstSubresource.mipLevel = copy_params.dest_level; | 539 | { |
| 517 | copy.dstSubresource.baseArrayLayer = dst_base_layer; | 540 | .x = static_cast<s32>(copy_params.source_x), |
| 518 | copy.dstSubresource.layerCount = num_layers; | 541 | .y = static_cast<s32>(copy_params.source_y), |
| 519 | copy.dstOffset.x = copy_params.dest_x; | 542 | .z = 0, |
| 520 | copy.dstOffset.y = copy_params.dest_y; | 543 | }, |
| 521 | copy.dstOffset.z = dst_offset_z; | 544 | .dstSubresource = |
| 522 | copy.extent.width = copy_params.width; | 545 | { |
| 523 | copy.extent.height = copy_params.height; | 546 | .aspectMask = dst_surface->GetAspectMask(), |
| 524 | copy.extent.depth = extent_z; | 547 | .mipLevel = copy_params.dest_level, |
| 548 | .baseArrayLayer = dst_base_layer, | ||
| 549 | .layerCount = num_layers, | ||
| 550 | }, | ||
| 551 | .dstOffset = | ||
| 552 | { | ||
| 553 | .x = static_cast<s32>(copy_params.dest_x), | ||
| 554 | .y = static_cast<s32>(copy_params.dest_y), | ||
| 555 | .z = static_cast<s32>(dst_offset_z), | ||
| 556 | }, | ||
| 557 | .extent = | ||
| 558 | { | ||
| 559 | .width = copy_params.width, | ||
| 560 | .height = copy_params.height, | ||
| 561 | .depth = extent_z, | ||
| 562 | }, | ||
| 563 | }; | ||
| 525 | 564 | ||
| 526 | const VkImage src_image = src_surface->GetImageHandle(); | 565 | const VkImage src_image = src_surface->GetImageHandle(); |
| 527 | const VkImage dst_image = dst_surface->GetImageHandle(); | 566 | const VkImage dst_image = dst_surface->GetImageHandle(); |