mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-09-26 11:06:25 -05:00
Latte: Add support for texture readback with non-zero slice index
This commit is contained in:
@@ -704,7 +704,7 @@ void optimizedLinearReadbackWriteLoop(LatteTextureLoaderCtx* textureLoader, uint
|
||||
sint32 yc = y;
|
||||
sint32 pixelOffset = yc * pitch;
|
||||
copyType* rowPixelData = (copyType*)(linearPixelData + pixelOffset * sizeof(copyType));
|
||||
copyType* blockData = (copyType*)LatteTextureLoader_getInputLinearOptimized_(textureLoader, 0, y, 1, 1, sizeof(copyType) * 8, 0, 1, 0, textureLoader->pitch, textureLoader->height);
|
||||
copyType* blockData = (copyType*)LatteTextureLoader_getInputLinearOptimized_(textureLoader, 0, y, 1, 1, sizeof(copyType) * 8, textureLoader->sliceIndex, 1, 0, textureLoader->pitch, textureLoader->surfaceInfoHeight);
|
||||
if constexpr (sizeof(copyType) == 4)
|
||||
{
|
||||
memcpy_dwords(blockData, rowPixelData, textureLoader->width);
|
||||
@@ -726,10 +726,6 @@ void LatteTextureLoader_writeReadbackTextureToMemory(LatteTextureDefinition* tex
|
||||
LatteTextureLoaderCtx textureLoader = { 0 };
|
||||
LatteTextureLoader_begin(&textureLoader, sliceIndex, mipIndex, textureData->physAddress, textureData->physMipAddress, textureData->format, textureData->dim, textureData->width, textureData->height, textureData->depth, textureData->mipLevels, textureData->pitch, textureData->tileMode, textureData->swizzle);
|
||||
|
||||
#ifdef CEMU_DEBUG_ASSERT
|
||||
if (textureData->depth != 1)
|
||||
cemuLog_log(LogType::Force, "_writeReadbackTextureToMemory(): Texture has multiple slices (not supported)");
|
||||
#endif
|
||||
if (textureLoader.physAddress == MPTR_NULL)
|
||||
{
|
||||
cemuLog_log(LogType::Force, "_writeReadbackTextureToMemory(): Texture has invalid address");
|
||||
|
||||
@@ -145,7 +145,7 @@ void LatteTextureReadback_UpdateFinishedTransfers(bool forceFinish)
|
||||
}
|
||||
#endif
|
||||
uint8* pixelData = readbackInfo->GetData();
|
||||
LatteTextureLoader_writeReadbackTextureToMemory(&readbackInfo->hostTextureCopy, 0, 0, pixelData);
|
||||
LatteTextureLoader_writeReadbackTextureToMemory(&readbackInfo->hostTextureCopy, readbackInfo->m_firstSlice, 0, pixelData);
|
||||
readbackInfo->ReleaseData();
|
||||
// get the original texture if it still exists and invalidate the current data hash
|
||||
LatteTextureView* origTexView = LatteTextureViewLookupCache::lookupSlice(readbackInfo->hostTextureCopy.physAddress, readbackInfo->hostTextureCopy.width, readbackInfo->hostTextureCopy.height, readbackInfo->hostTextureCopy.pitch, 0, 0, readbackInfo->hostTextureCopy.format);
|
||||
@@ -180,4 +180,4 @@ bool LatteTextureReadback_ReadbackToLinearBlocking(LatteTextureView* sourceView,
|
||||
info->ReleaseData();
|
||||
delete info;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ class LatteTextureReadbackInfo
|
||||
{
|
||||
public:
|
||||
LatteTextureReadbackInfo(LatteTextureView* textureView)
|
||||
: hostTextureCopy(textureView->baseTexture), m_textureView(textureView)
|
||||
: hostTextureCopy(textureView->baseTexture), m_firstSlice(textureView->firstSlice), m_textureView(textureView)
|
||||
{}
|
||||
|
||||
virtual ~LatteTextureReadbackInfo() = default;
|
||||
@@ -24,6 +24,7 @@ public:
|
||||
bool forceFinish{ false }; // set to true if not finished in time for dependent operation
|
||||
// texture info
|
||||
LatteTextureDefinition hostTextureCopy{};
|
||||
sint32 m_firstSlice{};
|
||||
|
||||
protected:
|
||||
LatteTextureView* m_textureView;
|
||||
|
||||
@@ -15,7 +15,6 @@ void LatteTextureReadbackInfoMtl::StartTransfer()
|
||||
|
||||
auto* baseTexture = (LatteTextureMtl*)m_textureView->baseTexture;
|
||||
|
||||
cemu_assert_debug(m_textureView->firstSlice == 0);
|
||||
cemu_assert_debug(m_textureView->firstMip == 0);
|
||||
cemu_assert_debug(m_textureView->baseTexture->dim != Latte::E_DIM::DIM_3D);
|
||||
|
||||
@@ -24,7 +23,7 @@ void LatteTextureReadbackInfoMtl::StartTransfer()
|
||||
|
||||
auto blitCommandEncoder = m_mtlr->GetBlitCommandEncoder();
|
||||
|
||||
blitCommandEncoder->copyFromTexture(baseTexture->GetTexture(), 0, 0, MTL::Origin{0, 0, 0}, MTL::Size{(uint32)baseTexture->width, (uint32)baseTexture->height, 1}, m_mtlr->GetTextureReadbackBuffer(), m_bufferOffset, bytesPerRow, bytesPerImage);
|
||||
blitCommandEncoder->copyFromTexture(baseTexture->GetTexture(), m_firstSlice, 0, MTL::Origin{0, 0, 0}, MTL::Size{(uint32)baseTexture->width, (uint32)baseTexture->height, 1}, m_mtlr->GetTextureReadbackBuffer(), m_bufferOffset, bytesPerRow, bytesPerImage);
|
||||
|
||||
m_commandBuffer = m_mtlr->GetCurrentCommandBuffer()->retain();
|
||||
// TODO: uncomment?
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "Cafe/HW/Latte/Renderer/Renderer.h"
|
||||
#include "Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.h"
|
||||
#include "Cafe/HW/Latte/Renderer/OpenGL/OpenGLTextureReadback.h"
|
||||
#include "Cafe/HW/Latte/Renderer/OpenGL/LatteTextureViewGL.h"
|
||||
#include "Cafe/HW/Latte/Renderer/OpenGL/LatteTextureGL.h"
|
||||
|
||||
LatteTextureReadbackInfoGL::LatteTextureReadbackInfoGL(LatteTextureView* textureView)
|
||||
: LatteTextureReadbackInfo(textureView)
|
||||
@@ -94,13 +92,15 @@ LatteTextureReadbackInfoGL::~LatteTextureReadbackInfoGL()
|
||||
void LatteTextureReadbackInfoGL::StartTransfer()
|
||||
{
|
||||
cemu_assert(m_textureView);
|
||||
((OpenGLRenderer*)g_renderer.get())->texture_bindAndActivate(m_textureView, 0);
|
||||
LatteTextureGL* baseTexture = (LatteTextureGL*)m_textureView->baseTexture;
|
||||
cemu_assert_debug(m_textureView->firstMip == 0);
|
||||
cemu_assert_debug(m_textureView->baseTexture->dim != Latte::E_DIM::DIM_3D);
|
||||
// create unsynchronized buffer
|
||||
glGenBuffers(1, &texImageBufferGL);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, texImageBufferGL);
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, m_image_size, NULL, GL_DYNAMIC_READ);
|
||||
// request texture read into buffer
|
||||
glGetTexImage(((LatteTextureViewGL*)m_textureView)->glTexTarget, 0, m_texFormatGL, m_texDataTypeGL, NULL);
|
||||
glGetTextureSubImage(baseTexture->glId_texture, 0, 0, 0, m_firstSlice, baseTexture->width, baseTexture->height, 1, m_texFormatGL, m_texDataTypeGL, m_image_size, NULL);
|
||||
glFlush();
|
||||
// create fence sync (so we can check if the image copy operation finished)
|
||||
imageCopyFinSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
|
||||
@@ -102,7 +102,6 @@ void LatteTextureReadbackInfoVk::StartTransfer()
|
||||
auto* baseTexture = (LatteTextureVk*)m_textureView->baseTexture;
|
||||
baseTexture->GetImageObj()->flagForCurrentCommandBuffer();
|
||||
|
||||
cemu_assert_debug(m_textureView->firstSlice == 0);
|
||||
cemu_assert_debug(m_textureView->firstMip == 0);
|
||||
cemu_assert_debug(m_textureView->baseTexture->dim != Latte::E_DIM::DIM_3D);
|
||||
|
||||
@@ -112,7 +111,7 @@ void LatteTextureReadbackInfoVk::StartTransfer()
|
||||
region.bufferImageHeight = baseTexture->height;
|
||||
|
||||
region.imageSubresource.aspectMask = baseTexture->GetImageAspect();
|
||||
region.imageSubresource.baseArrayLayer = 0;
|
||||
region.imageSubresource.baseArrayLayer = m_firstSlice;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageSubresource.mipLevel = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user