[Vulkan] Generalize texture conversion, and fix cube textures in the process.

This commit is contained in:
gibbed 2018-05-26 11:19:08 -05:00
parent 1def8cfc59
commit 9231317eeb
3 changed files with 15 additions and 87 deletions

View File

@ -17,6 +17,7 @@
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/memory.h"
#include "xenia/base/profiling.h"
#include "third_party/xxhash/xxhash.h"
@ -108,6 +109,7 @@ static uint32_t TiledOffset2DInner(uint32_t x, uint32_t y, uint32_t log2_bpp,
void Untile(uint8_t* output_buffer, const uint8_t* input_buffer,
const UntileInfo* untile_info) {
SCOPE_profile_cpu_f("gpu");
assert_not_null(untile_info);
assert_not_null(untile_info->input_format_info);
assert_not_null(untile_info->output_format_info);

View File

@ -919,9 +919,11 @@ void TextureCache::FlushPendingCommands(VkCommandBuffer command_buffer,
vkBeginCommandBuffer(command_buffer, &begin_info);
}
bool TextureCache::ConvertTexture2D(uint8_t* dest,
VkBufferImageCopy* copy_region,
bool TextureCache::ConvertTexture(uint8_t* dest, VkBufferImageCopy* copy_region,
uint32_t mip, const TextureInfo& src) {
#if FINE_GRAINED_DRAW_SCOPES
SCOPE_profile_cpu_f("gpu");
#endif // FINE_GRAINED_DRAW_SCOPES
uint32_t offset_x = 0;
uint32_t offset_y = 0;
uint32_t address = src.GetMipLocation(mip, &offset_x, &offset_y, true);
@ -930,29 +932,32 @@ bool TextureCache::ConvertTexture2D(uint8_t* dest,
auto src_usage = src.GetMipMemoryUsage(mip, true);
auto dst_usage = GetMipMemoryUsage(src, mip);
uint32_t src_pitch =
src_usage.block_pitch * src.format_info()->bytes_per_block();
uint32_t dst_pitch =
dst_usage.block_pitch * GetFormatInfo(src.format)->bytes_per_block();
uint32_t mip_width, mip_height;
src.GetMipSize(mip, &mip_width, &mip_height);
auto copy_block = GetFormatCopyBlock(src.format);
if (!src.is_tiled) {
uint32_t src_pitch =
src_usage.block_pitch * src.format_info()->bytes_per_block();
uint32_t dst_pitch =
dst_usage.block_pitch * GetFormatInfo(src.format)->bytes_per_block();
const uint8_t* src_mem = reinterpret_cast<const uint8_t*>(host_address);
if (!src.is_tiled) {
for (uint32_t face = 0; face < dst_usage.depth; face++) {
src_mem += offset_y * src_pitch;
src_mem += offset_x * src.format_info()->bytes_per_block();
for (uint32_t y = 0; y < dst_usage.block_height; y++) {
copy_block(src.endianness, dest + y * dst_pitch, src_mem + y * src_pitch,
dst_pitch);
copy_block(src.endianness, dest + y * dst_pitch,
src_mem + y * src_pitch, dst_pitch);
}
src_mem += src_pitch * src_usage.block_height;
dest += dst_pitch * dst_usage.block_height;
}
} else {
// Untile image.
// We could do this in a shader to speed things up, as this is pretty slow.
const uint8_t* src_mem = reinterpret_cast<const uint8_t*>(host_address);
for (uint32_t face = 0; face < dst_usage.depth; face++) {
texture_conversion::UntileInfo untile_info;
std::memset(&untile_info, 0, sizeof(untile_info));
untile_info.offset_x = offset_x;
@ -967,65 +972,6 @@ bool TextureCache::ConvertTexture2D(uint8_t* dest,
copy_block(src.endianness, o, i, l);
};
texture_conversion::Untile(dest, src_mem, &untile_info);
}
copy_region->bufferRowLength = dst_usage.pitch;
copy_region->bufferImageHeight = dst_usage.height;
copy_region->imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, mip, 0, 1};
copy_region->imageExtent = {mip_width, mip_height, 1};
return true;
}
bool TextureCache::ConvertTextureCube(uint8_t* dest,
VkBufferImageCopy* copy_region,
uint32_t mip, const TextureInfo& src) {
uint32_t offset_x = 0;
uint32_t offset_y = 0;
uint32_t address = src.GetMipLocation(mip, &offset_x, &offset_y, true);
void* host_address = memory_->TranslatePhysical(address);
auto src_usage = src.GetMipMemoryUsage(mip, true);
auto dst_usage = GetMipMemoryUsage(src, mip);
uint32_t src_pitch =
src_usage.block_pitch * src.format_info()->bytes_per_block();
uint32_t dst_pitch =
dst_usage.block_pitch * GetFormatInfo(src.format)->bytes_per_block();
uint32_t mip_width, mip_height;
src.GetMipSize(mip, &mip_width, &mip_height);
auto copy_block = GetFormatCopyBlock(src.format);
if (!src.is_tiled) {
const uint8_t* src_mem = reinterpret_cast<const uint8_t*>(host_address);
for (int face = 0; face < 6; face++) {
src_mem += offset_y * src_pitch;
src_mem += offset_x * src.format_info()->bytes_per_block();
for (uint32_t y = 0; y < dst_usage.block_height; y++) {
copy_block(src.endianness, dest + y * dst_pitch,
src_mem + y * src_pitch, dst_pitch);
}
src_mem += src_pitch * src_usage.block_height;
dest += dst_pitch * dst_usage.block_height;
}
} else {
const uint8_t* src_mem = reinterpret_cast<const uint8_t*>(host_address);
for (int face = 0; face < 6; face++) {
texture_conversion::UntileInfo untile_info;
std::memset(&untile_info, 0, sizeof(untile_info));
untile_info.offset_x = offset_x;
untile_info.offset_y = offset_y;
untile_info.width = dst_usage.block_pitch;
untile_info.height = dst_usage.block_height;
untile_info.input_pitch = src_usage.block_pitch;
untile_info.output_pitch = dst_usage.block_pitch;
untile_info.input_format_info = src.format_info();
untile_info.output_format_info = GetFormatInfo(src.format);
untile_info.copy_callback = [=](auto o, auto i, auto l) {
copy_block(src.endianness, o, i, l);
};
src_mem += src_pitch * src_usage.block_height;
dest += dst_pitch * dst_usage.block_height;
}
@ -1033,28 +979,12 @@ bool TextureCache::ConvertTextureCube(uint8_t* dest,
copy_region->bufferRowLength = dst_usage.pitch;
copy_region->bufferImageHeight = dst_usage.height;
copy_region->imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, mip, 0, 6};
copy_region->imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, mip, 0,
dst_usage.depth};
copy_region->imageExtent = {mip_width, mip_height, 1};
return true;
}
bool TextureCache::ConvertTexture(uint8_t* dest, VkBufferImageCopy* copy_region,
uint32_t mip, const TextureInfo& src) {
switch (src.dimension) {
case Dimension::k1D:
assert_always();
break;
case Dimension::k2D:
return ConvertTexture2D(dest, copy_region, mip, src);
case Dimension::k3D:
assert_always();
break;
case Dimension::kCube:
return ConvertTextureCube(dest, copy_region, mip, src);
}
return false;
}
bool TextureCache::UploadTexture(VkCommandBuffer command_buffer,
VkFence completion_fence, Texture* dest,
const TextureInfo& src) {

View File

@ -150,10 +150,6 @@ class TextureCache {
void FlushPendingCommands(VkCommandBuffer command_buffer,
VkFence completion_fence);
bool ConvertTexture2D(uint8_t* dest, VkBufferImageCopy* copy_region,
uint32_t mip, const TextureInfo& src);
bool ConvertTextureCube(uint8_t* dest, VkBufferImageCopy* copy_regions,
uint32_t mip, const TextureInfo& src);
bool ConvertTexture(uint8_t* dest, VkBufferImageCopy* copy_region,
uint32_t mip, const TextureInfo& src);