Cemu/src/Cafe/HW/Latte/Renderer/OpenGL/TextureReadbackGL.cpp
why-keith caa57a3cfd
Logging migration (forceLogDebug_printf) (#780)
* script changes - no arguments

* script changes with 2 arguments

* script changes with > 2 arguments

* script conversions with 1 argument - pt. 1

* script conversions with 1 argument - pt. 2

* script conversions with 1 argument - pt. 3

* script conversions with 1 argument - pt. 4

* script conversions with 1 argument - pt. 5

Pointer format hunting

* Fixed pointer format

* script conversions with 1 argument - final

* fixed conversion in non utf-8 file

* fixed conversion with capital letter

* actually fixed conversion with capital letter

* fixed another capital lettering issue

* Added conversions with LR removed

* removed LR from logs

* Converted logs that previously contained LR

* converted log that originally specified string length

* fixed log with commas in main text

* fixed multi-line log

* Fixed more logs with commas in main text

* Fixed unformatted pointer

* added conversion with float value

* converted lines with double parameters

* converted missed line

* corrected argument formatting

Co-authored-by: Crementif <26669564+Crementif@users.noreply.github.com>

* Fixed misspellings of "unhandled"

unhandeled -> unhandled

Co-authored-by: Crementif <26669564+Crementif@users.noreply.github.com>

---------

Co-authored-by: Crementif <26669564+Crementif@users.noreply.github.com>
2023-04-25 08:43:31 +02:00

131 lines
3.9 KiB
C++

#include "Cafe/HW/Latte/Renderer/Renderer.h"
#include "Cafe/HW/Latte/Renderer/OpenGL/OpenGLTextureReadback.h"
#include "Cafe/HW/Latte/Renderer/OpenGL/LatteTextureViewGL.h"
LatteTextureReadbackInfoGL::LatteTextureReadbackInfoGL(LatteTextureView* textureView)
: LatteTextureReadbackInfo(textureView)
{
LatteTexture* baseTexture = textureView->baseTexture;
// handle format
if (textureView->format == Latte::E_GX2SURFFMT::R8_G8_B8_A8_UNORM)
{
m_image_size = baseTexture->width*baseTexture->height * 4;
m_texFormatGL = GL_RGBA;
m_texDataTypeGL = GL_UNSIGNED_BYTE;
}
else if (textureView->format == Latte::E_GX2SURFFMT::R8_G8_B8_A8_SRGB)
{
m_image_size = baseTexture->width*baseTexture->height * 4;
m_texFormatGL = GL_RGBA;
m_texDataTypeGL = GL_UNSIGNED_BYTE;
}
else if (textureView->format == Latte::E_GX2SURFFMT::R32_G32_B32_A32_FLOAT)
{
m_image_size = baseTexture->width*baseTexture->height * 16;
m_texFormatGL = GL_RGBA;
m_texDataTypeGL = GL_FLOAT;
}
else if (textureView->format == Latte::E_GX2SURFFMT::R32_FLOAT)
{
if (baseTexture->isDepth)
{
m_image_size = baseTexture->width*baseTexture->height * 4;
m_texFormatGL = GL_DEPTH_COMPONENT;
m_texDataTypeGL = GL_FLOAT;
}
else
{
m_image_size = baseTexture->width*baseTexture->height * 4;
m_texFormatGL = GL_RED;
m_texDataTypeGL = GL_FLOAT;
}
}
else if (textureView->format == Latte::E_GX2SURFFMT::R16_UNORM)
{
if (baseTexture->isDepth)
{
m_image_size = baseTexture->width*baseTexture->height * 2;
m_texFormatGL = GL_DEPTH_COMPONENT;
m_texDataTypeGL = GL_UNSIGNED_SHORT;
cemu_assert_unimplemented();
}
else
{
m_image_size = baseTexture->width*baseTexture->height * 2;
m_texFormatGL = GL_RED;
m_texDataTypeGL = GL_UNSIGNED_SHORT;
}
}
else if (textureView->format == Latte::E_GX2SURFFMT::R16_G16_B16_A16_FLOAT)
{
m_image_size = baseTexture->width*baseTexture->height * 8;
m_texFormatGL = GL_RGBA;
m_texDataTypeGL = GL_HALF_FLOAT;
}
else if (textureView->format == Latte::E_GX2SURFFMT::R8_G8_UNORM)
{
m_image_size = baseTexture->width*baseTexture->height * 2;
m_texFormatGL = GL_RG;
m_texDataTypeGL = GL_UNSIGNED_BYTE;
}
else if (textureView->format == Latte::E_GX2SURFFMT::R16_G16_B16_A16_UNORM)
{
m_image_size = baseTexture->width*baseTexture->height * 8;
m_texFormatGL = GL_RGBA;
m_texDataTypeGL = GL_UNSIGNED_SHORT;
}
else
{
cemuLog_logDebug(LogType::Force, "Unsupported texture readback format {:04x}", (uint32)textureView->format);
return;
}
}
LatteTextureReadbackInfoGL::~LatteTextureReadbackInfoGL()
{
if(imageCopyFinSync != 0)
glDeleteSync(imageCopyFinSync);
if(texImageBufferGL)
glDeleteBuffers(1, &texImageBufferGL);
}
void LatteTextureReadbackInfoGL::StartTransfer()
{
cemu_assert(m_textureView);
g_renderer->texture_bindAndActivate(m_textureView, 0);
// 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);
glFlush();
// create fence sync (so we can check if the image copy operation finished)
imageCopyFinSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
m_textureView = nullptr;
}
bool LatteTextureReadbackInfoGL::IsFinished()
{
GLenum status = glClientWaitSync(imageCopyFinSync, 0, 0);
if (status == GL_TIMEOUT_EXPIRED)
return false;
else if (status == GL_ALREADY_SIGNALED || status == GL_SIGNALED)
return true;
else
throw std::runtime_error("_updateFinishedTransfers(): Error during readback sync check\n");
}
uint8* LatteTextureReadbackInfoGL::GetData()
{
glBindBuffer(GL_PIXEL_PACK_BUFFER, texImageBufferGL);
return (uint8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
}
void LatteTextureReadbackInfoGL::ReleaseData()
{
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
}