Vulkan CP: Use the color blitter
This commit is contained in:
@@ -311,7 +311,7 @@ void TextureCache::DestroyEmptySet() {
|
||||
}
|
||||
|
||||
TextureCache::Texture* TextureCache::AllocateTexture(
|
||||
const TextureInfo& texture_info) {
|
||||
const TextureInfo& texture_info, VkFormatFeatureFlags required_flags) {
|
||||
// Create an image first.
|
||||
VkImageCreateInfo image_info = {};
|
||||
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
@@ -341,18 +341,24 @@ TextureCache::Texture* TextureCache::AllocateTexture(
|
||||
: VK_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
image_info.usage =
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
// Check the device limits for the format before we create it.
|
||||
VkFormatProperties props;
|
||||
vkGetPhysicalDeviceFormatProperties(*device_, format, &props);
|
||||
uint32_t required_flags =
|
||||
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT;
|
||||
if ((props.optimalTilingFeatures & required_flags) != required_flags) {
|
||||
// Texture needs conversion on upload to a native format.
|
||||
// assert_always();
|
||||
assert_always();
|
||||
}
|
||||
|
||||
if (props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) {
|
||||
// Add color attachment usage if it's supported.
|
||||
image_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
}
|
||||
|
||||
if (props.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT) {
|
||||
image_info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
}
|
||||
|
||||
VkImageFormatProperties image_props;
|
||||
@@ -413,6 +419,10 @@ bool TextureCache::FreeTexture(Texture* texture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (texture->framebuffer) {
|
||||
vkDestroyFramebuffer(*device_, texture->framebuffer, nullptr);
|
||||
}
|
||||
|
||||
for (auto it = texture->views.begin(); it != texture->views.end();) {
|
||||
vkDestroyImageView(*device_, (*it)->view, nullptr);
|
||||
it = texture->views.erase(it);
|
||||
@@ -449,7 +459,9 @@ TextureCache::Texture* TextureCache::DemandResolveTexture(
|
||||
}
|
||||
|
||||
// No texture at this location. Make a new one.
|
||||
auto texture = AllocateTexture(texture_info);
|
||||
auto texture =
|
||||
AllocateTexture(texture_info, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
|
||||
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
|
||||
|
||||
// Setup a debug name for the texture.
|
||||
device_->DbgSetObjectName(
|
||||
@@ -965,23 +977,30 @@ void TextureCache::ConvertTexture2D(uint8_t* dest, const TextureInfo& src) {
|
||||
uint32_t offset_x;
|
||||
uint32_t offset_y;
|
||||
TextureInfo::GetPackedTileOffset(src, &offset_x, &offset_y);
|
||||
auto bpp = (bytes_per_block >> 2) +
|
||||
((bytes_per_block >> 1) >> (bytes_per_block >> 2));
|
||||
for (uint32_t y = 0, output_base_offset = 0;
|
||||
y < std::min(src.size_2d.block_height, src.size_2d.logical_height);
|
||||
y++, output_base_offset += src.size_2d.output_pitch) {
|
||||
auto input_base_offset = TextureInfo::TiledOffset2DOuter(
|
||||
offset_y + y,
|
||||
(src.size_2d.input_width / src.format_info()->block_width), bpp);
|
||||
for (uint32_t x = 0, output_offset = output_base_offset;
|
||||
x < src.size_2d.block_width; x++, output_offset += bytes_per_block) {
|
||||
auto log2_bpp = (bytes_per_block >> 2) +
|
||||
((bytes_per_block >> 1) >> (bytes_per_block >> 2));
|
||||
|
||||
// Offset to the current row, in bytes.
|
||||
uint32_t output_row_offset = 0;
|
||||
for (uint32_t y = 0; y < src.size_2d.block_height; y++) {
|
||||
auto input_row_offset = TextureInfo::TiledOffset2DOuter(
|
||||
offset_y + y, src.size_2d.block_width, log2_bpp);
|
||||
|
||||
// Go block-by-block on this row.
|
||||
uint32_t output_offset = output_row_offset;
|
||||
for (uint32_t x = 0; x < src.size_2d.block_width; x++) {
|
||||
auto input_offset =
|
||||
TextureInfo::TiledOffset2DInner(offset_x + x, offset_y + y, bpp,
|
||||
input_base_offset) >>
|
||||
bpp;
|
||||
TextureInfo::TiledOffset2DInner(offset_x + x, offset_y + y,
|
||||
log2_bpp, input_row_offset) >>
|
||||
log2_bpp;
|
||||
|
||||
TextureSwap(src.endianness, dest + output_offset,
|
||||
src_mem + input_offset * bytes_per_block, bytes_per_block);
|
||||
|
||||
output_offset += bytes_per_block;
|
||||
}
|
||||
|
||||
output_row_offset += src.size_2d.output_pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1174,6 +1193,13 @@ bool TextureCache::UploadTexture2D(VkCommandBuffer command_buffer,
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.image = dest->image;
|
||||
barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
|
||||
if (dest->format == VK_FORMAT_D16_UNORM_S8_UINT ||
|
||||
dest->format == VK_FORMAT_D24_UNORM_S8_UINT ||
|
||||
dest->format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
|
||||
barrier.subresourceRange.aspectMask =
|
||||
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &barrier);
|
||||
|
||||
Reference in New Issue
Block a user