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