mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Vulkan: Fix various problems with tex scaling.
This commit is contained in:
parent
99bf2c5aeb
commit
fe4c0e9f5a
2 changed files with 46 additions and 19 deletions
|
@ -1389,6 +1389,8 @@ void TextureCacheVulkan::SetTexture(VulkanPushBuffer *uploadBuffer) {
|
|||
maxLevel = 0;
|
||||
}
|
||||
|
||||
VkFormat actualFmt = scaleFactor > 1 ? VULKAN_8888_FORMAT : dstFmt;
|
||||
|
||||
if (replaceImages) {
|
||||
if (!entry->vkTex) {
|
||||
Crash();
|
||||
|
@ -1399,7 +1401,7 @@ void TextureCacheVulkan::SetTexture(VulkanPushBuffer *uploadBuffer) {
|
|||
VulkanTexture *image = entry->vkTex->texture_;
|
||||
|
||||
const VkComponentMapping *mapping;
|
||||
switch (dstFmt) {
|
||||
switch (actualFmt) {
|
||||
case VULKAN_4444_FORMAT:
|
||||
mapping = &VULKAN_4444_SWIZZLE;
|
||||
break;
|
||||
|
@ -1417,7 +1419,7 @@ void TextureCacheVulkan::SetTexture(VulkanPushBuffer *uploadBuffer) {
|
|||
break;
|
||||
}
|
||||
|
||||
image->CreateDirect(w * scaleFactor, h * scaleFactor, maxLevel + 1, dstFmt, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping);
|
||||
image->CreateDirect(w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping);
|
||||
}
|
||||
lastBoundTexture = entry->vkTex;
|
||||
|
||||
|
@ -1425,7 +1427,7 @@ void TextureCacheVulkan::SetTexture(VulkanPushBuffer *uploadBuffer) {
|
|||
for (int i = 0; i <= maxLevel; i++) {
|
||||
int mipWidth = gstate.getTextureWidth(i) * scaleFactor;
|
||||
int mipHeight = gstate.getTextureHeight(i) * scaleFactor;
|
||||
int bpp = dstFmt == VULKAN_8888_FORMAT ? 4 : 2;
|
||||
int bpp = actualFmt == VULKAN_8888_FORMAT ? 4 : 2;
|
||||
int stride = (mipWidth * bpp + 15) & ~15;
|
||||
int size = stride * mipHeight;
|
||||
uint32_t bufferOffset;
|
||||
|
@ -1697,7 +1699,8 @@ void TextureCacheVulkan::LoadTextureLevel(TexCacheEntry &entry, uint8_t *writePt
|
|||
if (scaleFactor > 1) {
|
||||
tmpTexBufRearrange.resize(std::max(bufw, w) * h);
|
||||
pixelData = tmpTexBufRearrange.data();
|
||||
decPitch = bufw * bpp;
|
||||
// We want to end up with a neatly packed texture for scaling.
|
||||
decPitch = w * bpp;
|
||||
}
|
||||
|
||||
void *finalBuf = DecodeTextureLevel((u8 *)pixelData, decPitch, tfmt, clutformat, texaddr, level, dstFmt, scaleFactor, bufw);
|
||||
|
@ -1705,18 +1708,35 @@ void TextureCacheVulkan::LoadTextureLevel(TexCacheEntry &entry, uint8_t *writePt
|
|||
return;
|
||||
}
|
||||
if (finalBuf != pixelData) {
|
||||
// Since we didn't write to pixelData, we must've ignored decPitch too.
|
||||
// TODO: Can remove once all formats are decoded directly and respect decPitch.
|
||||
decPitch = bufw * bpp;
|
||||
}
|
||||
pixelData = (u32 *)finalBuf;
|
||||
rowBytes = w * bpp;
|
||||
gpuStats.numTexturesDecoded++;
|
||||
|
||||
pixelData = (u32 *)finalBuf;
|
||||
if (scaleFactor > 1) {
|
||||
u32 fmt = dstFmt;
|
||||
// We need to repack it sometimes.
|
||||
// TODO: Can remove once all formats are decoded directly and respect decPitch.
|
||||
if (decPitch != w * bpp) {
|
||||
tmpTexBufRearrange.resize(w * h);
|
||||
const u8 *src = (u8 *)pixelData;
|
||||
u8 *dst = (u8 *)tmpTexBufRearrange.data();
|
||||
for (int y = 0; y < h; y++) {
|
||||
memcpy(dst + rowBytes * y, src + decPitch * y, rowBytes);
|
||||
}
|
||||
pixelData = (u32 *)dst;
|
||||
}
|
||||
|
||||
scaler.Scale(pixelData, fmt, w, h, scaleFactor);
|
||||
dstFmt = (VkFormat)fmt;
|
||||
decPitch *= scaleFactor;
|
||||
rowBytes *= scaleFactor;
|
||||
|
||||
// We always end up at 8888. Other parts check for this.
|
||||
assert(dstFmt == VULKAN_8888_FORMAT);
|
||||
decPitch = w * sizeof(u32);
|
||||
rowBytes = w * sizeof(u32);
|
||||
}
|
||||
|
||||
if ((entry.status & TexCacheEntry::STATUS_CHANGE_FREQUENT) == 0) {
|
||||
|
|
|
@ -21,38 +21,45 @@
|
|||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include "gfx/gl_common.h"
|
||||
|
||||
#include "GPU/Common/TextureScalerCommon.h"
|
||||
#include "GPU/Vulkan/TextureScalerVulkan.h"
|
||||
#include "Common/Vulkan/VulkanContext.h"
|
||||
#include "Common/ColorConv.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Common/ThreadPools.h"
|
||||
#include "GPU/Common/TextureScalerCommon.h"
|
||||
#include "GPU/Vulkan/TextureScalerVulkan.h"
|
||||
|
||||
// TODO: Share in TextureCacheVulkan.h?
|
||||
// Note: some drivers prefer B4G4R4A4_UNORM_PACK16 over R4G4B4A4_UNORM_PACK16.
|
||||
#define VULKAN_4444_FORMAT VK_FORMAT_B4G4R4A4_UNORM_PACK16
|
||||
#define VULKAN_1555_FORMAT VK_FORMAT_A1R5G5B5_UNORM_PACK16
|
||||
#define VULKAN_565_FORMAT VK_FORMAT_B5G6R5_UNORM_PACK16
|
||||
#define VULKAN_8888_FORMAT VK_FORMAT_R8G8B8A8_UNORM
|
||||
|
||||
int TextureScalerVulkan::BytesPerPixel(u32 format) {
|
||||
return (format == GL_UNSIGNED_BYTE) ? 4 : 2;
|
||||
return (format == VULKAN_8888_FORMAT) ? 4 : 2;
|
||||
}
|
||||
|
||||
u32 TextureScalerVulkan::Get8888Format() {
|
||||
return GL_UNSIGNED_BYTE;
|
||||
return VULKAN_8888_FORMAT;
|
||||
}
|
||||
|
||||
void TextureScalerVulkan::ConvertTo8888(u32 format, u32* source, u32* &dest, int width, int height) {
|
||||
switch (format) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
case VULKAN_8888_FORMAT:
|
||||
dest = source; // already fine
|
||||
break;
|
||||
|
||||
case GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
GlobalThreadPool::Loop(std::bind(&convert4444_gl, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
|
||||
case VULKAN_4444_FORMAT:
|
||||
GlobalThreadPool::Loop(std::bind(&convert4444_dx9, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
|
||||
break;
|
||||
|
||||
case GL_UNSIGNED_SHORT_5_6_5:
|
||||
GlobalThreadPool::Loop(std::bind(&convert565_gl, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
|
||||
case VULKAN_565_FORMAT:
|
||||
GlobalThreadPool::Loop(std::bind(&convert565_dx9, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
|
||||
break;
|
||||
|
||||
case GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
GlobalThreadPool::Loop(std::bind(&convert5551_gl, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
|
||||
case VULKAN_1555_FORMAT:
|
||||
GlobalThreadPool::Loop(std::bind(&convert5551_dx9, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Add table
Reference in a new issue