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;
|
maxLevel = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkFormat actualFmt = scaleFactor > 1 ? VULKAN_8888_FORMAT : dstFmt;
|
||||||
|
|
||||||
if (replaceImages) {
|
if (replaceImages) {
|
||||||
if (!entry->vkTex) {
|
if (!entry->vkTex) {
|
||||||
Crash();
|
Crash();
|
||||||
|
@ -1399,7 +1401,7 @@ void TextureCacheVulkan::SetTexture(VulkanPushBuffer *uploadBuffer) {
|
||||||
VulkanTexture *image = entry->vkTex->texture_;
|
VulkanTexture *image = entry->vkTex->texture_;
|
||||||
|
|
||||||
const VkComponentMapping *mapping;
|
const VkComponentMapping *mapping;
|
||||||
switch (dstFmt) {
|
switch (actualFmt) {
|
||||||
case VULKAN_4444_FORMAT:
|
case VULKAN_4444_FORMAT:
|
||||||
mapping = &VULKAN_4444_SWIZZLE;
|
mapping = &VULKAN_4444_SWIZZLE;
|
||||||
break;
|
break;
|
||||||
|
@ -1417,7 +1419,7 @@ void TextureCacheVulkan::SetTexture(VulkanPushBuffer *uploadBuffer) {
|
||||||
break;
|
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;
|
lastBoundTexture = entry->vkTex;
|
||||||
|
|
||||||
|
@ -1425,7 +1427,7 @@ void TextureCacheVulkan::SetTexture(VulkanPushBuffer *uploadBuffer) {
|
||||||
for (int i = 0; i <= maxLevel; i++) {
|
for (int i = 0; i <= maxLevel; i++) {
|
||||||
int mipWidth = gstate.getTextureWidth(i) * scaleFactor;
|
int mipWidth = gstate.getTextureWidth(i) * scaleFactor;
|
||||||
int mipHeight = gstate.getTextureHeight(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 stride = (mipWidth * bpp + 15) & ~15;
|
||||||
int size = stride * mipHeight;
|
int size = stride * mipHeight;
|
||||||
uint32_t bufferOffset;
|
uint32_t bufferOffset;
|
||||||
|
@ -1697,7 +1699,8 @@ void TextureCacheVulkan::LoadTextureLevel(TexCacheEntry &entry, uint8_t *writePt
|
||||||
if (scaleFactor > 1) {
|
if (scaleFactor > 1) {
|
||||||
tmpTexBufRearrange.resize(std::max(bufw, w) * h);
|
tmpTexBufRearrange.resize(std::max(bufw, w) * h);
|
||||||
pixelData = tmpTexBufRearrange.data();
|
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);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (finalBuf != pixelData) {
|
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;
|
decPitch = bufw * bpp;
|
||||||
}
|
}
|
||||||
|
pixelData = (u32 *)finalBuf;
|
||||||
rowBytes = w * bpp;
|
rowBytes = w * bpp;
|
||||||
gpuStats.numTexturesDecoded++;
|
gpuStats.numTexturesDecoded++;
|
||||||
|
|
||||||
pixelData = (u32 *)finalBuf;
|
|
||||||
if (scaleFactor > 1) {
|
if (scaleFactor > 1) {
|
||||||
u32 fmt = dstFmt;
|
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);
|
scaler.Scale(pixelData, fmt, w, h, scaleFactor);
|
||||||
dstFmt = (VkFormat)fmt;
|
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) {
|
if ((entry.status & TexCacheEntry::STATUS_CHANGE_FREQUENT) == 0) {
|
||||||
|
|
|
@ -21,38 +21,45 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "gfx/gl_common.h"
|
|
||||||
|
|
||||||
#include "GPU/Common/TextureScalerCommon.h"
|
#include "Common/Vulkan/VulkanContext.h"
|
||||||
#include "GPU/Vulkan/TextureScalerVulkan.h"
|
|
||||||
#include "Common/ColorConv.h"
|
#include "Common/ColorConv.h"
|
||||||
#include "Common/Log.h"
|
#include "Common/Log.h"
|
||||||
#include "Common/ThreadPools.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) {
|
int TextureScalerVulkan::BytesPerPixel(u32 format) {
|
||||||
return (format == GL_UNSIGNED_BYTE) ? 4 : 2;
|
return (format == VULKAN_8888_FORMAT) ? 4 : 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 TextureScalerVulkan::Get8888Format() {
|
u32 TextureScalerVulkan::Get8888Format() {
|
||||||
return GL_UNSIGNED_BYTE;
|
return VULKAN_8888_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureScalerVulkan::ConvertTo8888(u32 format, u32* source, u32* &dest, int width, int height) {
|
void TextureScalerVulkan::ConvertTo8888(u32 format, u32* source, u32* &dest, int width, int height) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case GL_UNSIGNED_BYTE:
|
case VULKAN_8888_FORMAT:
|
||||||
dest = source; // already fine
|
dest = source; // already fine
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_UNSIGNED_SHORT_4_4_4_4:
|
case VULKAN_4444_FORMAT:
|
||||||
GlobalThreadPool::Loop(std::bind(&convert4444_gl, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
|
GlobalThreadPool::Loop(std::bind(&convert4444_dx9, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_UNSIGNED_SHORT_5_6_5:
|
case VULKAN_565_FORMAT:
|
||||||
GlobalThreadPool::Loop(std::bind(&convert565_gl, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
|
GlobalThreadPool::Loop(std::bind(&convert565_dx9, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_UNSIGNED_SHORT_5_5_5_1:
|
case VULKAN_1555_FORMAT:
|
||||||
GlobalThreadPool::Loop(std::bind(&convert5551_gl, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
|
GlobalThreadPool::Loop(std::bind(&convert5551_dx9, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Add table
Reference in a new issue