mirror of
https://github.com/libretro/ppsspp.git
synced 2025-03-04 14:37:17 +00:00
Vulkan: Convert depth format on readback.
Although, the GPU debugger stuff already handles more formats, it's hard to get the current format to avoid the conversion...
This commit is contained in:
parent
fc32a7b24e
commit
3a84b63777
@ -73,5 +73,6 @@ inline bool DataFormatIsColor(DataFormat fmt) {
|
||||
}
|
||||
|
||||
void ConvertFromRGBA8888(uint8_t *dst, const uint8_t *src, uint32_t dstStride, uint32_t srcStride, uint32_t width, uint32_t height, DataFormat format);
|
||||
void ConvertToD32F(uint8_t *dst, const uint8_t *src, uint32_t dstStride, uint32_t srcStride, uint32_t width, uint32_t height, DataFormat format);
|
||||
|
||||
} // namespace
|
||||
|
@ -891,7 +891,7 @@ void VulkanQueueRunner::PerformReadbackImage(const VKRStep &step, VkCommandBuffe
|
||||
void VulkanQueueRunner::CopyReadbackBuffer(int width, int height, Draw::DataFormat srcFormat, Draw::DataFormat destFormat, int pixelStride, uint8_t *pixels) {
|
||||
// Read back to the requested address in ram from buffer.
|
||||
void *mappedData;
|
||||
const size_t srcPixelSize = DataFormatSizeInBytes(destFormat);
|
||||
const size_t srcPixelSize = DataFormatSizeInBytes(srcFormat);
|
||||
|
||||
VkResult res = vkMapMemory(vulkan_->GetDevice(), readbackMemory_, 0, width * height * srcPixelSize, 0, &mappedData);
|
||||
assert(res == VK_SUCCESS);
|
||||
@ -905,8 +905,10 @@ void VulkanQueueRunner::CopyReadbackBuffer(int width, int height, Draw::DataForm
|
||||
src += width * srcPixelSize;
|
||||
dst += pixelStride * srcPixelSize;
|
||||
}
|
||||
} else if (destFormat == Draw::DataFormat::D32F) {
|
||||
ConvertToD32F(pixels, (const uint8_t *)mappedData, pixelStride, width, width, height, srcFormat);
|
||||
} else {
|
||||
// TODO: Maybe depth conversion or something?
|
||||
// TODO: Maybe a depth conversion or something?
|
||||
assert(false);
|
||||
}
|
||||
vkUnmapMemory(vulkan_->GetDevice(), readbackMemory_);
|
||||
|
@ -407,11 +407,13 @@ void VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, int a
|
||||
case VK_FORMAT_R8G8B8A8_UNORM: srcFormat = Draw::DataFormat::R8G8B8A8_UNORM; break;
|
||||
default: assert(false);
|
||||
}
|
||||
} else if (aspectBits & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
||||
} else if (aspectBits & VK_IMAGE_ASPECT_STENCIL_BIT) {
|
||||
// Copies from stencil are always S8.
|
||||
srcFormat = Draw::DataFormat::S8;
|
||||
} else if (aspectBits & VK_IMAGE_ASPECT_DEPTH_BIT) {
|
||||
switch (src->depth.format) {
|
||||
case VK_FORMAT_D24_UNORM_S8_UINT: srcFormat = Draw::DataFormat::D24_S8; break;
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT: srcFormat = Draw::DataFormat::D32F_S8; break;
|
||||
// TODO: Wrong.
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT: srcFormat = Draw::DataFormat::D32F; break;
|
||||
case VK_FORMAT_D16_UNORM_S8_UINT: srcFormat = Draw::DataFormat::D16; break;
|
||||
default: assert(false);
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
|
||||
@ -13,6 +14,7 @@ size_t DataFormatSizeInBytes(DataFormat fmt) {
|
||||
case DataFormat::R8G8_UNORM: return 2;
|
||||
case DataFormat::R8G8B8_UNORM: return 3;
|
||||
|
||||
case DataFormat::R4G4_UNORM_PACK8: return 1;
|
||||
case DataFormat::R4G4B4A4_UNORM_PACK16: return 2;
|
||||
case DataFormat::B4G4R4A4_UNORM_PACK16: return 2;
|
||||
case DataFormat::A4R4G4B4_UNORM_PACK16: return 2;
|
||||
@ -38,6 +40,13 @@ size_t DataFormatSizeInBytes(DataFormat fmt) {
|
||||
case DataFormat::R32G32B32_FLOAT: return 12;
|
||||
case DataFormat::R32G32B32A32_FLOAT: return 16;
|
||||
|
||||
case DataFormat::S8: return 1;
|
||||
case DataFormat::D16: return 2;
|
||||
case DataFormat::D24_S8: return 4;
|
||||
case DataFormat::D32F: return 4;
|
||||
// Or maybe 8...
|
||||
case DataFormat::D32F_S8: return 5;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -372,5 +381,43 @@ void ConvertFromRGBA8888(uint8_t *dst, const uint8_t *src, uint32_t dstStride, u
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertToD32F(uint8_t *dst, const uint8_t *src, uint32_t dstStride, uint32_t srcStride, uint32_t width, uint32_t height, DataFormat format) {
|
||||
if (format == Draw::DataFormat::D32F) {
|
||||
const float *src32 = (const float *)src;
|
||||
float *dst32 = (float *)dst;
|
||||
if (src == dst) {
|
||||
return;
|
||||
} else {
|
||||
for (uint32_t y = 0; y < height; ++y) {
|
||||
memcpy(dst32, src32, width * 4);
|
||||
src32 += srcStride;
|
||||
dst32 += dstStride;
|
||||
}
|
||||
}
|
||||
} else if (format == Draw::DataFormat::D16) {
|
||||
const uint16_t *src16 = (const uint16_t *)src;
|
||||
float *dst32 = (float *)dst;
|
||||
for (uint32_t y = 0; y < height; ++y) {
|
||||
for (uint32_t x = 0; x < width; ++x) {
|
||||
dst32[x] = (float)(int)src16[x] / 65535.0f;
|
||||
}
|
||||
src16 += srcStride;
|
||||
dst32 += dstStride;
|
||||
}
|
||||
} else if (format == Draw::DataFormat::D24_S8) {
|
||||
const uint32_t *src32 = (const uint32_t *)src;
|
||||
float *dst32 = (float *)dst;
|
||||
for (uint32_t y = 0; y < height; ++y) {
|
||||
for (uint32_t x = 0; x < width; ++x) {
|
||||
dst32[x] = (src32[x] & 0x00FFFFFF) / 16777215.0f;
|
||||
}
|
||||
src32 += srcStride;
|
||||
dst32 += dstStride;
|
||||
}
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Draw
|
||||
|
Loading…
x
Reference in New Issue
Block a user