Upload PSP textures through a push buffer instead of image copy. More flexible.

This commit is contained in:
Henrik Rydgard 2016-03-14 23:25:00 +01:00
parent 5ea01ffff6
commit 8a62724316
5 changed files with 21 additions and 21 deletions

View file

@ -1436,6 +1436,7 @@ void VulkanTexture::CreateDirect(int w, int h, int numMips, VkFormat format) {
tex_width = w;
tex_height = h;
numMips_ = numMips;
format_ = format;
VkImageCreateInfo image_create_info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
image_create_info.imageType = VK_IMAGE_TYPE_2D;
@ -1497,10 +1498,10 @@ void VulkanTexture::CreateDirect(int w, int h, int numMips, VkFormat format) {
assert(res == VK_SUCCESS);
}
void VulkanTexture::UploadMip(int mip, VkBuffer buffer, size_t offset, size_t stride) {
void VulkanTexture::UploadMip(int mip, VkBuffer buffer, size_t offset, size_t rowLength) {
VkBufferImageCopy copy_region = {};
copy_region.bufferOffset = offset;
copy_region.bufferRowLength = (uint32_t)stride;
copy_region.bufferRowLength = (uint32_t)rowLength;
copy_region.bufferImageHeight = tex_height;
copy_region.imageExtent.width = tex_width;
copy_region.imageExtent.height = tex_height;

View file

@ -366,7 +366,7 @@ public:
// Fast uploads from buffer. Mipmaps supported.
void CreateDirect(int w, int h, int numMips, VkFormat format);
void UploadMip(int mip, VkBuffer buffer, size_t offset, size_t stride);
void UploadMip(int mip, VkBuffer buffer, size_t offset, size_t rowLength); // rowLength is in pixels
void EndCreate();
void Destroy();
@ -416,12 +416,10 @@ public:
VulkanPushBuffer(VulkanContext *vulkan, size_t size) : offset_(0), size_(size), writePtr_(nullptr), deviceMemory_(0) {
VkDevice device = vulkan->GetDevice();
VkBufferCreateInfo b = {};
b.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
b.pNext = nullptr;
VkBufferCreateInfo b = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
b.size = size;
b.flags = 0;
b.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
b.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
b.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
b.queueFamilyIndexCount = 0;
b.pQueueFamilyIndices = nullptr;

View file

@ -467,7 +467,7 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) {
// TODO: The descriptor set seems to be unbinding the texture when not specified. Cache it or the imageView instead?
// TODO: Add this back when fixed: gstate_c.textureChanged != TEXCHANGE_UNCHANGED &&
if (!gstate.isModeClear() && gstate.isTextureMapEnabled()) {
textureCache_->SetTexture();
textureCache_->SetTexture(frame->pushData);
gstate_c.textureChanged = TEXCHANGE_UNCHANGED;
if (gstate_c.needShaderTexClamp) {
// We will rarely need to set this, so let's do it every time on use rather than in runloop.

View file

@ -1069,7 +1069,7 @@ bool TextureCacheVulkan::SetOffsetTexture(u32 offset) {
return false;
}
void TextureCacheVulkan::SetTexture() {
void TextureCacheVulkan::SetTexture(VulkanPushBuffer *uploadBuffer) {
#ifdef DEBUG_TEXTURES
if (SetDebugTexture()) {
// A different texture was bound, let's rebind next time.
@ -1453,14 +1453,21 @@ void TextureCacheVulkan::SetTexture() {
entry->vkTex = new CachedTextureVulkan();
entry->vkTex->texture_ = new VulkanTexture(vulkan_);
VulkanTexture *image = entry->vkTex->texture_;
VkResult res = image->Create(w, h, dstFmt);
assert(res == VK_SUCCESS);
image->CreateDirect(w, h, 1, dstFmt);
}
lastBoundTexture = entry->vkTex;
// In Vulkan, fortunately, we have full control over mipmapping.
// For now, we only load the base texture. More to come.
LoadTextureLevel(*entry, 0, replaceImages, scaleFactor, dstFmt);
// Upload the texture data.
int bpp = dstFmt == VULKAN_8888_FORMAT ? 4 : 2;
int stride = (w * bpp + 15) & ~15;
int size = stride * h;
size_t bufferOffset;
void *data = uploadBuffer->Push(size, &bufferOffset);
LoadTextureLevel(*entry, (uint8_t *)data, stride, 0, replaceImages, scaleFactor, dstFmt);
entry->vkTex->texture_->UploadMip(0, uploadBuffer->GetVkBuffer(), bufferOffset, stride / bpp);
// Mipmapping only enable when texture scaling disable
/*
@ -1740,7 +1747,7 @@ TextureCacheVulkan::TexCacheEntry::Status TextureCacheVulkan::CheckAlpha(const u
return (TexCacheEntry::Status)res;
}
void TextureCacheVulkan::LoadTextureLevel(TexCacheEntry &entry, int level, bool replaceImages, int scaleFactor, VkFormat dstFmt) {
void TextureCacheVulkan::LoadTextureLevel(TexCacheEntry &entry, uint8_t *writePtr, int rowPitch, int level, bool replaceImages, int scaleFactor, VkFormat dstFmt) {
CachedTextureVulkan *tex = entry.vkTex;
int w = gstate.getTextureWidth(level);
int h = gstate.getTextureHeight(level);
@ -1751,7 +1758,6 @@ void TextureCacheVulkan::LoadTextureLevel(TexCacheEntry &entry, int level, bool
PROFILE_THIS_SCOPE("decodetex");
u32 texByteAlign = 1;
GETextureFormat tfmt = (GETextureFormat)entry.format;
GEPaletteFormat clutformat = gstate.getClutPaletteFormat();
int bufw;
@ -1784,16 +1790,11 @@ void TextureCacheVulkan::LoadTextureLevel(TexCacheEntry &entry, int level, bool
}
PROFILE_THIS_SCOPE("loadtex");
// Upload the texture data. TODO: Decode directly into this buffer.
int rowPitch;
uint8_t *writePtr = entry.vkTex->texture_->Lock(level, &rowPitch);
for (int y = 0; y < h; y++) {
memcpy(writePtr + rowPitch * y, (const uint8_t *)pixelData + decPitch * y, rowBytes);
// uncomment to make all textures white for debugging
//memset(writePtr + rowPitch * y, 0xff, rowBytes);
}
entry.vkTex->texture_->Unlock();
/*
if (!lowMemoryMode_) {

View file

@ -85,7 +85,7 @@ public:
TextureCacheVulkan(VulkanContext *vulkan);
~TextureCacheVulkan();
void SetTexture();
void SetTexture(VulkanPushBuffer *uploadBuffer);
virtual bool SetOffsetTexture(u32 offset) override;
void Clear(bool delete_them);
@ -126,7 +126,7 @@ private:
void DeleteTexture(TexCache::iterator it);
void *ReadIndexedTex(int level, const u8 *texptr, int bytesPerIndex, VkFormat dstFmt, int bufw);
void UpdateSamplingParams(TexCacheEntry &entry, SamplerCacheKey &key);
void LoadTextureLevel(TexCacheEntry &entry, int level, bool replaceImages, int scaleFactor, VkFormat dstFmt);
void LoadTextureLevel(TexCacheEntry &entry, uint8_t *writePtr, int rowPitch, int level, bool replaceImages, int scaleFactor, VkFormat dstFmt);
VkFormat GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const;
void *DecodeTextureLevel(GETextureFormat format, GEPaletteFormat clutformat, int level, u32 &texByteAlign, VkFormat dstFmt, int scaleFactor, int *bufw = 0);
TexCacheEntry::Status CheckAlpha(const u32 *pixelData, VkFormat dstFmt, int stride, int w, int h);