[GPU/Vulkan] Add support for 2D image stacks.

This commit is contained in:
gibbed 2018-06-05 07:51:51 -05:00
parent 4caa2a2145
commit 1409b9c565
3 changed files with 36 additions and 12 deletions

View File

@ -38,24 +38,35 @@ bool TextureInfo::Prepare(const xe_gpu_texture_fetch_t& fetch,
info.dimension = static_cast<Dimension>(fetch.dimension); info.dimension = static_cast<Dimension>(fetch.dimension);
info.width = info.height = info.depth = 0; info.width = info.height = info.depth = 0;
info.is_stacked = false;
switch (info.dimension) { switch (info.dimension) {
case Dimension::k1D: case Dimension::k1D:
info.dimension = Dimension::k2D; // we treat 1D textures as 2D info.dimension = Dimension::k2D; // we treat 1D textures as 2D
info.width = fetch.size_1d.width; info.width = fetch.size_1d.width;
assert_true(!fetch.stacked);
break; break;
case Dimension::k2D: case Dimension::k2D:
if (!fetch.stacked) {
info.width = fetch.size_2d.width; info.width = fetch.size_2d.width;
info.height = fetch.size_2d.height; info.height = fetch.size_2d.height;
} else {
info.width = fetch.size_stack.width;
info.height = fetch.size_stack.height;
info.depth = fetch.size_stack.depth;
info.is_stacked = true;
}
break; break;
case Dimension::k3D: case Dimension::k3D:
info.width = fetch.size_3d.width; info.width = fetch.size_3d.width;
info.height = fetch.size_3d.height; info.height = fetch.size_3d.height;
info.depth = fetch.size_3d.depth; info.depth = fetch.size_3d.depth;
assert_true(!fetch.stacked);
break; break;
case Dimension::kCube: case Dimension::kCube:
info.width = fetch.size_stack.width; info.width = fetch.size_stack.width;
info.height = fetch.size_stack.height; info.height = fetch.size_stack.height;
info.depth = fetch.size_stack.depth; info.depth = fetch.size_stack.depth;
assert_true(!fetch.stacked);
break; break;
default: default:
assert_unhandled_case(info.dimension); assert_unhandled_case(info.dimension);

View File

@ -329,6 +329,7 @@ struct TextureInfo {
uint32_t pitch; // pitch in blocks uint32_t pitch; // pitch in blocks
uint32_t mip_min_level; uint32_t mip_min_level;
uint32_t mip_max_level; uint32_t mip_max_level;
bool is_stacked;
bool is_tiled; bool is_tiled;
bool has_packed_mips; bool has_packed_mips;

View File

@ -191,7 +191,12 @@ TextureCache::Texture* TextureCache::AllocateTexture(
switch (texture_info.dimension) { switch (texture_info.dimension) {
case Dimension::k1D: case Dimension::k1D:
case Dimension::k2D: case Dimension::k2D:
if (!texture_info.is_stacked) {
image_info.imageType = VK_IMAGE_TYPE_2D; image_info.imageType = VK_IMAGE_TYPE_2D;
} else {
image_info.imageType = VK_IMAGE_TYPE_3D;
image_info.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
}
break; break;
case Dimension::k3D: case Dimension::k3D:
image_info.imageType = VK_IMAGE_TYPE_3D; image_info.imageType = VK_IMAGE_TYPE_3D;
@ -249,9 +254,9 @@ TextureCache::Texture* TextureCache::AllocateTexture(
image_info.format = format; image_info.format = format;
image_info.extent.width = texture_info.width + 1; image_info.extent.width = texture_info.width + 1;
image_info.extent.height = texture_info.height + 1; image_info.extent.height = texture_info.height + 1;
image_info.extent.depth = !is_cube ? texture_info.depth + 1 : 1; image_info.extent.depth = !is_cube ? 1 + texture_info.depth : 1;
image_info.mipLevels = texture_info.mip_min_level + texture_info.mip_levels(); image_info.mipLevels = texture_info.mip_min_level + texture_info.mip_levels();
image_info.arrayLayers = !is_cube ? 1 : 6; image_info.arrayLayers = !is_cube ? 1 : 1 + texture_info.depth;
image_info.samples = VK_SAMPLE_COUNT_1_BIT; image_info.samples = VK_SAMPLE_COUNT_1_BIT;
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
image_info.queueFamilyIndexCount = 0; image_info.queueFamilyIndexCount = 0;
@ -263,6 +268,7 @@ TextureCache::Texture* TextureCache::AllocateTexture(
assert_true(image_props.maxExtent.height >= image_info.extent.height); assert_true(image_props.maxExtent.height >= image_info.extent.height);
assert_true(image_props.maxExtent.depth >= image_info.extent.depth); assert_true(image_props.maxExtent.depth >= image_info.extent.depth);
assert_true(image_props.maxMipLevels >= image_info.mipLevels); assert_true(image_props.maxMipLevels >= image_info.mipLevels);
assert_true(image_props.maxArrayLayers >= image_info.arrayLayers);
VmaAllocation alloc; VmaAllocation alloc;
VmaAllocationCreateInfo vma_create_info = { VmaAllocationCreateInfo vma_create_info = {
@ -519,7 +525,11 @@ TextureCache::TextureView* TextureCache::DemandView(Texture* texture,
switch (texture->texture_info.dimension) { switch (texture->texture_info.dimension) {
case Dimension::k1D: case Dimension::k1D:
case Dimension::k2D: case Dimension::k2D:
if (!texture->texture_info.is_stacked) {
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D; view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
} else {
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
}
break; break;
case Dimension::k3D: case Dimension::k3D:
view_info.viewType = VK_IMAGE_VIEW_TYPE_3D; view_info.viewType = VK_IMAGE_VIEW_TYPE_3D;
@ -569,7 +579,8 @@ TextureCache::TextureView* TextureCache::DemandView(Texture* texture,
view_info.subresourceRange.baseMipLevel = texture->texture_info.mip_min_level; view_info.subresourceRange.baseMipLevel = texture->texture_info.mip_min_level;
view_info.subresourceRange.levelCount = texture->texture_info.mip_levels(); view_info.subresourceRange.levelCount = texture->texture_info.mip_levels();
view_info.subresourceRange.baseArrayLayer = 0; view_info.subresourceRange.baseArrayLayer = 0;
view_info.subresourceRange.layerCount = !is_cube ? 1 : 6; view_info.subresourceRange.layerCount =
!is_cube ? 1 : 1 + texture->texture_info.depth;
VkImageView view; VkImageView view;
auto status = vkCreateImageView(*device_, &view_info, nullptr, &view); auto status = vkCreateImageView(*device_, &view_info, nullptr, &view);
@ -924,7 +935,7 @@ bool TextureCache::ConvertTexture(uint8_t* dest, VkBufferImageCopy* copy_region,
copy_region->imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; copy_region->imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_region->imageSubresource.mipLevel = mip; copy_region->imageSubresource.mipLevel = mip;
copy_region->imageSubresource.baseArrayLayer = 0; copy_region->imageSubresource.baseArrayLayer = 0;
copy_region->imageSubresource.layerCount = !is_cube ? 1 : 6; copy_region->imageSubresource.layerCount = !is_cube ? 1 : dst_extent.depth;
copy_region->imageExtent.width = std::max(1u, (src.width + 1) >> mip); copy_region->imageExtent.width = std::max(1u, (src.width + 1) >> mip);
copy_region->imageExtent.height = std::max(1u, (src.height + 1) >> mip); copy_region->imageExtent.height = std::max(1u, (src.height + 1) >> mip);
copy_region->imageExtent.depth = !is_cube ? dst_extent.depth : 1; copy_region->imageExtent.depth = !is_cube ? dst_extent.depth : 1;
@ -942,13 +953,14 @@ bool TextureCache::UploadTexture(VkCommandBuffer command_buffer,
XELOGGPU( XELOGGPU(
"Uploading texture @ 0x%.8X/0x%.8X (%ux%ux%u, format: %s, dim: %s, " "Uploading texture @ 0x%.8X/0x%.8X (%ux%ux%u, format: %s, dim: %s, "
"levels: %u (%u-%u), pitch: %u, tiled: %s, packed mips: %s, unpack " "levels: %u (%u-%u), stacked: %s, pitch: %u, tiled: %s, packed mips: %s, "
"length: 0x%.8X)", "unpack length: 0x%.8X)",
src.memory.base_address, src.memory.mip_address, src.width + 1, src.memory.base_address, src.memory.mip_address, src.width + 1,
src.height + 1, src.depth + 1, src.format_info()->name, src.height + 1, src.depth + 1, src.format_info()->name,
get_dimension_name(src.dimension), src.mip_levels(), src.mip_min_level, get_dimension_name(src.dimension), src.mip_levels(), src.mip_min_level,
src.mip_max_level, src.pitch, src.is_tiled ? "yes" : "no", src.mip_max_level, src.is_stacked ? "yes" : "no", src.pitch,
src.has_packed_mips ? "yes" : "no", unpack_length); src.is_tiled ? "yes" : "no", src.has_packed_mips ? "yes" : "no",
unpack_length);
XELOGGPU("Extent: %ux%ux%u %u,%u,%u", src.extent.pitch, src.extent.height, XELOGGPU("Extent: %ux%ux%u %u,%u,%u", src.extent.pitch, src.extent.height,
src.extent.depth, src.extent.block_pitch_h, src.extent.block_height, src.extent.depth, src.extent.block_pitch_h, src.extent.block_height,