mirror of
https://github.com/libretro/Play-.git
synced 2025-03-04 09:17:50 +00:00
Got rid of texture uploaders.
This commit is contained in:
parent
db34f8193c
commit
76b9142e9a
@ -318,7 +318,7 @@ void CGSH_OpenGL::InitializeRC()
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClearDepthf(0.0f);
|
||||
|
||||
SetupTextureUploaders();
|
||||
SetupTextureUpdaters();
|
||||
|
||||
m_presentProgram = GeneratePresentProgram();
|
||||
m_presentVertexBuffer = GeneratePresentVertexBuffer();
|
||||
@ -2209,14 +2209,18 @@ CGSH_OpenGL::CFramebuffer::~CFramebuffer()
|
||||
|
||||
void CGSH_OpenGL::PopulateFramebuffer(const FramebufferPtr& framebuffer)
|
||||
{
|
||||
auto texFormat = GetTextureFormatInfo(framebuffer->m_psm);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_copyToFbTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, texFormat.internalFormat, framebuffer->m_width, framebuffer->m_height,
|
||||
0, texFormat.format, texFormat.type, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
((this)->*(m_textureUploader[framebuffer->m_psm]))(framebuffer->m_basePtr,
|
||||
framebuffer->m_width / 64, framebuffer->m_width, framebuffer->m_height);
|
||||
((this)->*(m_textureUpdater[framebuffer->m_psm]))(framebuffer->m_basePtr,
|
||||
framebuffer->m_width / 64, 0, 0, framebuffer->m_width, framebuffer->m_height);
|
||||
CHECKGLERROR();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer->m_framebuffer);
|
||||
|
@ -145,7 +145,6 @@ private:
|
||||
CVTBUFFERSIZE = 0x800000,
|
||||
};
|
||||
|
||||
typedef void (CGSH_OpenGL::*TEXTUREUPLOADER)(uint32, uint32, unsigned int, unsigned int);
|
||||
typedef void (CGSH_OpenGL::*TEXTUREUPDATER)(uint32, uint32, unsigned int, unsigned int, unsigned int, unsigned int);
|
||||
|
||||
struct VERTEX
|
||||
@ -257,6 +256,13 @@ private:
|
||||
float scaleRatioY = 1;
|
||||
};
|
||||
|
||||
struct TEXTUREFORMAT_INFO
|
||||
{
|
||||
GLenum internalFormat;
|
||||
GLenum format;
|
||||
GLenum type;
|
||||
};
|
||||
|
||||
enum class PRIM_VERTEX_ATTRIB
|
||||
{
|
||||
POSITION = 1,
|
||||
@ -283,7 +289,7 @@ private:
|
||||
void WriteRegisterImpl(uint8, uint64) override;
|
||||
|
||||
void InitializeRC();
|
||||
void SetupTextureUploaders();
|
||||
void SetupTextureUpdaters();
|
||||
virtual void PresentBackbuffer() = 0;
|
||||
void MakeLinearZOrtho(float*, float, float, float, float);
|
||||
unsigned int GetCurrentReadCircuit();
|
||||
@ -339,21 +345,13 @@ private:
|
||||
void SetupTexture(uint64, uint64, uint64, uint64, uint64);
|
||||
static bool IsCompatibleFramebufferPSM(unsigned int, unsigned int);
|
||||
static uint32 GetFramebufferBitDepth(uint32);
|
||||
static TEXTUREFORMAT_INFO GetTextureFormatInfo(uint32);
|
||||
|
||||
FramebufferPtr FindFramebuffer(const FRAME&) const;
|
||||
DepthbufferPtr FindDepthbuffer(const ZBUF&, const FRAME&) const;
|
||||
|
||||
void DumpTexture(unsigned int, unsigned int, uint32);
|
||||
|
||||
//Texture uploaders
|
||||
void TexUploader_Invalid(uint32, uint32, unsigned int, unsigned int);
|
||||
|
||||
void TexUploader_Psm32(uint32, uint32, unsigned int, unsigned int);
|
||||
template <typename> void TexUploader_Psm16(uint32, uint32, unsigned int, unsigned int);
|
||||
|
||||
template <typename> void TexUploader_Psm48(uint32, uint32, unsigned int, unsigned int);
|
||||
template <uint32, uint32> void TexUploader_Psm48H(uint32, uint32, unsigned int, unsigned int);
|
||||
|
||||
//Texture updaters
|
||||
void TexUpdater_Invalid(uint32, uint32, unsigned int, unsigned int, unsigned int, unsigned int);
|
||||
|
||||
@ -422,7 +420,6 @@ private:
|
||||
static const unsigned int g_shaderClampModes[CGSHandler::CLAMP_MODE_MAX];
|
||||
static const unsigned int g_alphaTestInverse[CGSHandler::ALPHA_TEST_MAX];
|
||||
|
||||
TEXTUREUPLOADER m_textureUploader[CGSHandler::PSM_MAX];
|
||||
TEXTUREUPDATER m_textureUpdater[CGSHandler::PSM_MAX];
|
||||
|
||||
enum GLSTATE_BITS : uint32
|
||||
|
@ -14,25 +14,13 @@
|
||||
// Texture Loading
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
void CGSH_OpenGL::SetupTextureUploaders()
|
||||
void CGSH_OpenGL::SetupTextureUpdaters()
|
||||
{
|
||||
for(unsigned int i = 0; i < PSM_MAX; i++)
|
||||
{
|
||||
m_textureUploader[i] = &CGSH_OpenGL::TexUploader_Invalid;
|
||||
m_textureUpdater[i] = &CGSH_OpenGL::TexUpdater_Invalid;
|
||||
}
|
||||
|
||||
m_textureUploader[PSMCT32] = &CGSH_OpenGL::TexUploader_Psm32;
|
||||
m_textureUploader[PSMCT24] = &CGSH_OpenGL::TexUploader_Psm32;
|
||||
m_textureUploader[PSMCT16] = &CGSH_OpenGL::TexUploader_Psm16<CGsPixelFormats::CPixelIndexorPSMCT16>;
|
||||
m_textureUploader[PSMCT24_UNK] = &CGSH_OpenGL::TexUploader_Psm32;
|
||||
m_textureUploader[PSMCT16S] = &CGSH_OpenGL::TexUploader_Psm16<CGsPixelFormats::CPixelIndexorPSMCT16S>;
|
||||
m_textureUploader[PSMT8] = &CGSH_OpenGL::TexUploader_Psm48<CGsPixelFormats::CPixelIndexorPSMT8>;
|
||||
m_textureUploader[PSMT4] = &CGSH_OpenGL::TexUploader_Psm48<CGsPixelFormats::CPixelIndexorPSMT4>;
|
||||
m_textureUploader[PSMT8H] = &CGSH_OpenGL::TexUploader_Psm48H<24, 0xFF>;
|
||||
m_textureUploader[PSMT4HL] = &CGSH_OpenGL::TexUploader_Psm48H<24, 0x0F>;
|
||||
m_textureUploader[PSMT4HH] = &CGSH_OpenGL::TexUploader_Psm48H<28, 0x0F>;
|
||||
|
||||
m_textureUpdater[PSMCT32] = &CGSH_OpenGL::TexUpdater_Psm32;
|
||||
m_textureUpdater[PSMCT24] = &CGSH_OpenGL::TexUpdater_Psm32;
|
||||
m_textureUpdater[PSMCT16] = &CGSH_OpenGL::TexUpdater_Psm16<CGsPixelFormats::CPixelIndexorPSMCT16>;
|
||||
@ -74,6 +62,29 @@ uint32 CGSH_OpenGL::GetFramebufferBitDepth(uint32 psm)
|
||||
}
|
||||
}
|
||||
|
||||
CGSH_OpenGL::TEXTUREFORMAT_INFO CGSH_OpenGL::GetTextureFormatInfo(uint32 psm)
|
||||
{
|
||||
switch(psm)
|
||||
{
|
||||
case PSMCT32:
|
||||
case PSMCT24:
|
||||
case PSMCT24_UNK:
|
||||
return TEXTUREFORMAT_INFO { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE };
|
||||
case PSMCT16:
|
||||
case PSMCT16S:
|
||||
return TEXTUREFORMAT_INFO { GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 };
|
||||
case PSMT8:
|
||||
case PSMT4:
|
||||
case PSMT8H:
|
||||
case PSMT4HL:
|
||||
case PSMT4HH:
|
||||
return TEXTUREFORMAT_INFO { GL_R8, GL_RED, GL_UNSIGNED_BYTE };
|
||||
default:
|
||||
assert(false);
|
||||
return TEXTUREFORMAT_INFO { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE };
|
||||
}
|
||||
}
|
||||
|
||||
CGSH_OpenGL::TEXTURE_INFO CGSH_OpenGL::PrepareTexture(const TEX0& tex0)
|
||||
{
|
||||
TEXTURE_INFO texInfo;
|
||||
@ -133,44 +144,7 @@ CGSH_OpenGL::TEXTURE_INFO CGSH_OpenGL::PrepareTexture(const TEX0& tex0)
|
||||
}
|
||||
|
||||
auto texture = TexCache_Search(tex0);
|
||||
if(texture)
|
||||
{
|
||||
texInfo.textureHandle = texture->m_texture;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture->m_texture);
|
||||
auto& cachedArea = texture->m_cachedArea;
|
||||
|
||||
auto texturePageSize = CGsPixelFormats::GetPsmPageSize(tex0.nPsm);
|
||||
auto areaRect = cachedArea.GetAreaPageRect();
|
||||
|
||||
while(cachedArea.HasDirtyPages())
|
||||
{
|
||||
auto dirtyRect = cachedArea.GetDirtyPageRect();
|
||||
assert((dirtyRect.width != 0) && (dirtyRect.height != 0));
|
||||
cachedArea.ClearDirtyPages(dirtyRect);
|
||||
|
||||
uint32 texX = dirtyRect.x * texturePageSize.first;
|
||||
uint32 texY = dirtyRect.y * texturePageSize.second;
|
||||
uint32 texWidth = dirtyRect.width * texturePageSize.first;
|
||||
uint32 texHeight = dirtyRect.height * texturePageSize.second;
|
||||
if(texX >= tex0.GetWidth()) continue;
|
||||
if(texY >= tex0.GetHeight()) continue;
|
||||
//assert(texX < tex0.GetWidth());
|
||||
//assert(texY < tex0.GetHeight());
|
||||
if((texX + texWidth) > tex0.GetWidth())
|
||||
{
|
||||
texWidth = tex0.GetWidth() - texX;
|
||||
}
|
||||
if((texY + texHeight) > tex0.GetHeight())
|
||||
{
|
||||
texHeight = tex0.GetHeight() - texY;
|
||||
}
|
||||
((this)->*(m_textureUpdater[tex0.nPsm]))(tex0.GetBufPtr(), tex0.nBufWidth, texX, texY, texWidth, texHeight);
|
||||
}
|
||||
|
||||
cachedArea.ClearDirtyPages();
|
||||
}
|
||||
else
|
||||
if(!texture)
|
||||
{
|
||||
//Validate texture dimensions to prevent problems
|
||||
auto texWidth = tex0.GetWidth();
|
||||
@ -179,16 +153,55 @@ CGSH_OpenGL::TEXTURE_INFO CGSH_OpenGL::PrepareTexture(const TEX0& tex0)
|
||||
assert(texHeight <= 1024);
|
||||
texWidth = std::min<uint32>(texWidth, 1024);
|
||||
texHeight = std::min<uint32>(texHeight, 1024);
|
||||
auto texFormat = GetTextureFormatInfo(tex0.nPsm);
|
||||
|
||||
GLuint textureHandle = 0;
|
||||
glGenTextures(1, &textureHandle);
|
||||
glBindTexture(GL_TEXTURE_2D, textureHandle);
|
||||
((this)->*(m_textureUploader[tex0.nPsm]))(tex0.GetBufPtr(), tex0.nBufWidth, texWidth, texHeight);
|
||||
TexCache_Insert(tex0, textureHandle);
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, texFormat.internalFormat, texWidth, texHeight);
|
||||
CHECKGLERROR();
|
||||
|
||||
texInfo.textureHandle = textureHandle;
|
||||
TexCache_Insert(tex0, textureHandle);
|
||||
texture = TexCache_Search(tex0);
|
||||
assert(textureHandle == texture->m_texture);
|
||||
|
||||
texture->m_cachedArea.Invalidate(0, RAMSIZE);
|
||||
}
|
||||
|
||||
texInfo.textureHandle = texture->m_texture;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture->m_texture);
|
||||
auto& cachedArea = texture->m_cachedArea;
|
||||
auto texturePageSize = CGsPixelFormats::GetPsmPageSize(tex0.nPsm);
|
||||
auto areaRect = cachedArea.GetAreaPageRect();
|
||||
|
||||
while(cachedArea.HasDirtyPages())
|
||||
{
|
||||
auto dirtyRect = cachedArea.GetDirtyPageRect();
|
||||
assert((dirtyRect.width != 0) && (dirtyRect.height != 0));
|
||||
cachedArea.ClearDirtyPages(dirtyRect);
|
||||
|
||||
uint32 texX = dirtyRect.x * texturePageSize.first;
|
||||
uint32 texY = dirtyRect.y * texturePageSize.second;
|
||||
uint32 texWidth = dirtyRect.width * texturePageSize.first;
|
||||
uint32 texHeight = dirtyRect.height * texturePageSize.second;
|
||||
if(texX >= tex0.GetWidth()) continue;
|
||||
if(texY >= tex0.GetHeight()) continue;
|
||||
//assert(texX < tex0.GetWidth());
|
||||
//assert(texY < tex0.GetHeight());
|
||||
if((texX + texWidth) > tex0.GetWidth())
|
||||
{
|
||||
texWidth = tex0.GetWidth() - texX;
|
||||
}
|
||||
if((texY + texHeight) > tex0.GetHeight())
|
||||
{
|
||||
texHeight = tex0.GetHeight() - texY;
|
||||
}
|
||||
((this)->*(m_textureUpdater[tex0.nPsm]))(tex0.GetBufPtr(), tex0.nBufWidth, texX, texY, texWidth, texHeight);
|
||||
}
|
||||
|
||||
cachedArea.ClearDirtyPages();
|
||||
|
||||
return texInfo;
|
||||
}
|
||||
|
||||
@ -296,98 +309,6 @@ void CGSH_OpenGL::DumpTexture(unsigned int nWidth, unsigned int nHeight, uint32
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGSH_OpenGL::TexUploader_Invalid(uint32, uint32, unsigned int, unsigned int)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CGSH_OpenGL::TexUploader_Psm32(uint32 bufPtr, uint32 bufWidth, unsigned int texWidth, unsigned int texHeight)
|
||||
{
|
||||
CGsPixelFormats::CPixelIndexorPSMCT32 indexor(m_pRAM, bufPtr, bufWidth);
|
||||
|
||||
uint32* dst = reinterpret_cast<uint32*>(m_pCvtBuffer);
|
||||
for(unsigned int j = 0; j < texHeight; j++)
|
||||
{
|
||||
for(unsigned int i = 0; i < texWidth; i++)
|
||||
{
|
||||
dst[i] = indexor.GetPixel(i, j);
|
||||
}
|
||||
|
||||
dst += texWidth;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_pCvtBuffer);
|
||||
CHECKGLERROR();
|
||||
}
|
||||
|
||||
template <typename IndexorType>
|
||||
void CGSH_OpenGL::TexUploader_Psm16(uint32 bufPtr, uint32 bufWidth, unsigned int texWidth, unsigned int texHeight)
|
||||
{
|
||||
IndexorType indexor(m_pRAM, bufPtr, bufWidth);
|
||||
|
||||
auto dst = reinterpret_cast<uint16*>(m_pCvtBuffer);
|
||||
for(unsigned int j = 0; j < texHeight; j++)
|
||||
{
|
||||
for(unsigned int i = 0; i < texWidth; i++)
|
||||
{
|
||||
auto pixel = indexor.GetPixel(i, j);
|
||||
auto cvtPixel =
|
||||
(((pixel & 0x001F) >> 0) << 11) | //R
|
||||
(((pixel & 0x03E0) >> 5) << 6) | //G
|
||||
(((pixel & 0x7C00) >> 10) << 1) | //B
|
||||
(pixel >> 15); //A
|
||||
dst[i] = cvtPixel;
|
||||
}
|
||||
|
||||
dst += texWidth;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, m_pCvtBuffer);
|
||||
CHECKGLERROR();
|
||||
}
|
||||
|
||||
template <typename IndexorType>
|
||||
void CGSH_OpenGL::TexUploader_Psm48(uint32 bufPtr, uint32 bufWidth, unsigned int texWidth, unsigned int texHeight)
|
||||
{
|
||||
IndexorType indexor(m_pRAM, bufPtr, bufWidth);
|
||||
|
||||
uint8* dst = m_pCvtBuffer;
|
||||
for(unsigned int j = 0; j < texHeight; j++)
|
||||
{
|
||||
for(unsigned int i = 0; i < texWidth; i++)
|
||||
{
|
||||
dst[i] = indexor.GetPixel(i, j);
|
||||
}
|
||||
|
||||
dst += texWidth;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, texWidth, texHeight, 0, GL_RED, GL_UNSIGNED_BYTE, m_pCvtBuffer);
|
||||
CHECKGLERROR();
|
||||
}
|
||||
|
||||
template <uint32 shiftAmount, uint32 mask>
|
||||
void CGSH_OpenGL::TexUploader_Psm48H(uint32 bufPtr, uint32 bufWidth, unsigned int texWidth, unsigned int texHeight)
|
||||
{
|
||||
CGsPixelFormats::CPixelIndexorPSMCT32 indexor(m_pRAM, bufPtr, bufWidth);
|
||||
|
||||
uint8* dst = m_pCvtBuffer;
|
||||
for(unsigned int j = 0; j < texHeight; j++)
|
||||
{
|
||||
for(unsigned int i = 0; i < texWidth; i++)
|
||||
{
|
||||
uint32 pixel = indexor.GetPixel(i, j);
|
||||
pixel = (pixel >> shiftAmount) & mask;
|
||||
dst[i] = static_cast<uint8>(pixel);
|
||||
}
|
||||
|
||||
dst += texWidth;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, texWidth, texHeight, 0, GL_RED, GL_UNSIGNED_BYTE, m_pCvtBuffer);
|
||||
CHECKGLERROR();
|
||||
}
|
||||
|
||||
void CGSH_OpenGL::TexUpdater_Invalid(uint32 bufPtr, uint32 bufWidth, unsigned int texX, unsigned int texY, unsigned int texWidth, unsigned int texHeight)
|
||||
{
|
||||
assert(0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user