mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Upload PSP textures through a push buffer instead of image copy. More flexible.
This commit is contained in:
parent
5ea01ffff6
commit
8a62724316
5 changed files with 21 additions and 21 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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_) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue