mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-26 15:45:41 +00:00
edb11dc223
The old texture code was being bottle necked by the texture reads. We mirrored the real3d texture memory directly, including the mipmaps in a single large texture. I *think* most h/w has some sort of texture cache for a 2x2 or 4x4 block of pixels for a texture. What we were doing was reading the base texture, then reading the mipmap data from a totally separate part of the same texture which I can only assume flushed this cache. What I did was to create mipmap chains for the texture sheet, then copy the mipmap data there. Doing this basically doubles performance.
72 lines
1.9 KiB
C++
72 lines
1.9 KiB
C++
#include "TextureBank.h"
|
|
|
|
New3D::TextureBank::TextureBank()
|
|
{
|
|
glGenTextures(1, &m_texID);
|
|
glBindTexture(GL_TEXTURE_2D, m_texID);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
|
|
|
int width = 2048;
|
|
int height = 1024;
|
|
int level = 0;
|
|
|
|
while (width>=1 && height>=1) {
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, level, GL_R16UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, nullptr); // allocate storage
|
|
|
|
width = (width > 1) ? width / 2 : 1;
|
|
height = (height > 1) ? height / 2 : 1;
|
|
|
|
level++;
|
|
|
|
if (width == 1 && height == 1) {
|
|
glTexImage2D(GL_TEXTURE_2D, level, GL_R16UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, nullptr); // allocate storage
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_numLevels = level;
|
|
}
|
|
|
|
New3D::TextureBank::~TextureBank()
|
|
{
|
|
if (m_texID) {
|
|
glDeleteTextures(1, &m_texID);
|
|
m_texID = 0;
|
|
}
|
|
}
|
|
|
|
void New3D::TextureBank::AttachMemory(const UINT16* textureRam)
|
|
{
|
|
m_textureRam = textureRam;
|
|
}
|
|
|
|
void New3D::TextureBank::Bind()
|
|
{
|
|
glBindTexture(GL_TEXTURE_2D, m_texID);
|
|
}
|
|
|
|
void New3D::TextureBank::UploadTextures(int level, int x, int y, int width, int height)
|
|
{
|
|
glBindTexture(GL_TEXTURE_2D, m_texID);
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
|
|
|
|
const int mipXBase[] = { 0, 1024, 1536, 1792, 1920, 1984, 2016, 2032, 2040, 2044, 2046, 2047 };
|
|
const int mipYBase[] = { 0, 512, 768, 896, 960, 992, 1008, 1016, 1020, 1022, 1023 };
|
|
|
|
int subX = x - mipXBase[level];
|
|
int subY = y - mipYBase[level];
|
|
|
|
for (unsigned i = 0; i < height; i++) {
|
|
glTexSubImage2D(GL_TEXTURE_2D, level, subX, subY + i, width, 1, GL_RED_INTEGER, GL_UNSIGNED_SHORT, m_textureRam + ((y + i) * 2048) + x);
|
|
}
|
|
}
|
|
|
|
int New3D::TextureBank::GetNumberOfLevels()
|
|
{
|
|
return m_numLevels;
|
|
}
|