Skip to content
Permalink
Browse files

Merge pull request #1899 from degasus/texcache

Texture Pool
  • Loading branch information...
degasus committed Jan 18, 2015
2 parents 37a770b + 9f13a77 commit 5357b9c95ff2458e3b8c3112e303924a0d460ce6
@@ -81,40 +81,43 @@ void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
D3D::ReplaceRGBATexture2D(texture->GetTex(), TextureCache::temp, width, height, expanded_width, level, usage);
}

TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, unsigned int height,
unsigned int tex_levels, PC_TexFormat pcfmt)
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntryConfig& config)
{
D3D11_USAGE usage = D3D11_USAGE_DEFAULT;
D3D11_CPU_ACCESS_FLAG cpu_access = (D3D11_CPU_ACCESS_FLAG)0;

if (tex_levels == 1)
if (config.rendertarget)
{
usage = D3D11_USAGE_DYNAMIC;
cpu_access = D3D11_CPU_ACCESS_WRITE;
return new TCacheEntry(config, D3DTexture2D::Create(config.width, config.height,
(D3D11_BIND_FLAG)((int)D3D11_BIND_RENDER_TARGET | (int)D3D11_BIND_SHADER_RESOURCE),
D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM, 1, config.layers));
}
else
{
D3D11_USAGE usage = D3D11_USAGE_DEFAULT;
D3D11_CPU_ACCESS_FLAG cpu_access = (D3D11_CPU_ACCESS_FLAG)0;

const D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM,
width, height, 1, tex_levels, D3D11_BIND_SHADER_RESOURCE, usage, cpu_access);
if (config.levels == 1)
{
usage = D3D11_USAGE_DYNAMIC;
cpu_access = D3D11_CPU_ACCESS_WRITE;
}

ID3D11Texture2D *pTexture;
const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &pTexture);
CHECK(SUCCEEDED(hr), "Create texture of the TextureCache");
const D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM,
config.width, config.height, 1, config.levels, D3D11_BIND_SHADER_RESOURCE, usage, cpu_access);

TCacheEntryConfig config;
config.width = width;
config.height = height;
config.levels = tex_levels;
ID3D11Texture2D *pTexture;
const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &pTexture);
CHECK(SUCCEEDED(hr), "Create texture of the TextureCache");

TCacheEntry* const entry = new TCacheEntry(config, new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE));
entry->usage = usage;
TCacheEntry* const entry = new TCacheEntry(config, new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE));
entry->usage = usage;

// TODO: better debug names
D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetTex(), "a texture of the TextureCache");
D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetSRV(), "shader resource view of a texture of the TextureCache");
// TODO: better debug names
D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetTex(), "a texture of the TextureCache");
D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetSRV(), "shader resource view of a texture of the TextureCache");

SAFE_RELEASE(pTexture);
SAFE_RELEASE(pTexture);

return entry;
return entry;
}
}

void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
@@ -192,20 +195,6 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
}
}

TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(
unsigned int scaled_tex_w, unsigned int scaled_tex_h, unsigned int layers)
{
TCacheEntryConfig config;
config.width = scaled_tex_w;
config.height = scaled_tex_h;
config.layers = layers;
config.rendertarget = true;

return new TCacheEntry(config, D3DTexture2D::Create(scaled_tex_w, scaled_tex_h,
(D3D11_BIND_FLAG)((int)D3D11_BIND_RENDER_TARGET | (int)D3D11_BIND_SHADER_RESOURCE),
D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM, 1, layers));
}

TextureCache::TextureCache()
{
// FIXME: Is it safe here?
@@ -38,10 +38,8 @@ class TextureCache : public ::TextureCache
bool Save(const std::string& filename, unsigned int level) override;
};

TCacheEntryBase* CreateTexture(unsigned int width, unsigned int height,
unsigned int tex_levels, PC_TexFormat pcfmt) override;
TCacheEntryBase* CreateTexture(const TCacheEntryConfig& config) override;

TCacheEntryBase* CreateRenderTargetTexture(unsigned int scaled_tex_w, unsigned int scaled_tex_h, unsigned int layers) override;
u64 EncodeToRamFromTexture(u32 address, void* source_texture, u32 SourceW, u32 SourceH, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source) {return 0;};

void CompileShaders() override { }
@@ -109,80 +109,28 @@ bool TextureCache::TCacheEntry::Save(const std::string& filename, unsigned int l
return SaveTexture(filename, GL_TEXTURE_2D_ARRAY, texture, config.width, config.height, level);
}

TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, unsigned int height,
unsigned int tex_levels, PC_TexFormat pcfmt)
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntryConfig& config)
{
int gl_format = 0,
gl_iformat = 0,
gl_type = 0;
TCacheEntry* entry = new TCacheEntry(config);

if (pcfmt != PC_TEX_FMT_DXT1)
glActiveTexture(GL_TEXTURE0+9);
glBindTexture(GL_TEXTURE_2D_ARRAY, entry->texture);

glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, config.levels - 1);

if (config.rendertarget)
{
switch (pcfmt)
for (u32 level = 0; level <= config.levels; level++)
{
default:
case PC_TEX_FMT_NONE:
PanicAlert("Invalid PC texture format %i", pcfmt);
case PC_TEX_FMT_BGRA32:
gl_format = GL_BGRA;
gl_iformat = GL_RGBA;
gl_type = GL_UNSIGNED_BYTE;
break;

case PC_TEX_FMT_RGBA32:
gl_format = GL_RGBA;
gl_iformat = GL_RGBA;
gl_type = GL_UNSIGNED_BYTE;
break;
case PC_TEX_FMT_I4_AS_I8:
gl_format = GL_LUMINANCE;
gl_iformat = GL_INTENSITY4;
gl_type = GL_UNSIGNED_BYTE;
break;

case PC_TEX_FMT_IA4_AS_IA8:
gl_format = GL_LUMINANCE_ALPHA;
gl_iformat = GL_LUMINANCE4_ALPHA4;
gl_type = GL_UNSIGNED_BYTE;
break;

case PC_TEX_FMT_I8:
gl_format = GL_LUMINANCE;
gl_iformat = GL_INTENSITY8;
gl_type = GL_UNSIGNED_BYTE;
break;

case PC_TEX_FMT_IA8:
gl_format = GL_LUMINANCE_ALPHA;
gl_iformat = GL_LUMINANCE8_ALPHA8;
gl_type = GL_UNSIGNED_BYTE;
break;
case PC_TEX_FMT_RGB565:
gl_format = GL_RGB;
gl_iformat = GL_RGB;
gl_type = GL_UNSIGNED_SHORT_5_6_5;
break;
glTexImage3D(GL_TEXTURE_2D_ARRAY, level, GL_RGBA, config.width, config.height, config.layers, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
}
glGenFramebuffers(1, &entry->framebuffer);
FramebufferManager::SetFramebuffer(entry->framebuffer);
FramebufferManager::FramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_ARRAY, entry->texture, 0);
}

TCacheEntryConfig config;
config.width = width;
config.height = height;
config.levels = tex_levels;

TCacheEntry &entry = *new TCacheEntry(config);
entry.gl_format = gl_format;
entry.gl_iformat = gl_iformat;
entry.gl_type = gl_type;
entry.pcfmt = pcfmt;

glActiveTexture(GL_TEXTURE0+9);
glBindTexture(GL_TEXTURE_2D_ARRAY, entry.texture);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, tex_levels - 1);

TextureCache::SetStage();

return &entry;
return entry;
}

void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
@@ -194,57 +142,18 @@ void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
PanicAlert("size of level %d must be %dx%d, but %dx%d requested",
level, std::max(1u, config.width >> level), std::max(1u, config.height >> level), width, height);

if (pcfmt != PC_TEX_FMT_DXT1)
{
glActiveTexture(GL_TEXTURE0+9);
glBindTexture(GL_TEXTURE_2D_ARRAY, texture);

if (expanded_width != width)
glPixelStorei(GL_UNPACK_ROW_LENGTH, expanded_width);

glTexImage3D(GL_TEXTURE_2D_ARRAY, level, gl_iformat, width, height, 1, 0, gl_format, gl_type, temp);

if (expanded_width != width)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}
else
{
PanicAlert("PC_TEX_FMT_DXT1 support disabled");
//glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
//width, height, 0, expanded_width * expanded_height/2, temp);
}
TextureCache::SetStage();
}

TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(
unsigned int scaled_tex_w, unsigned int scaled_tex_h, unsigned int layers)
{
TCacheEntryConfig config;
config.width = scaled_tex_w;
config.height = scaled_tex_h;
config.layers = layers;
config.rendertarget = true;
TCacheEntry *const entry = new TCacheEntry(config);

glActiveTexture(GL_TEXTURE0+9);
glBindTexture(GL_TEXTURE_2D_ARRAY, entry->texture);
glBindTexture(GL_TEXTURE_2D_ARRAY, texture);

const GLenum
gl_format = GL_RGBA,
gl_iformat = GL_RGBA,
gl_type = GL_UNSIGNED_BYTE;
if (expanded_width != width)
glPixelStorei(GL_UNPACK_ROW_LENGTH, expanded_width);

glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, gl_iformat, scaled_tex_w, scaled_tex_h, layers, 0, gl_format, gl_type, nullptr);
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
glTexImage3D(GL_TEXTURE_2D_ARRAY, level, GL_RGBA, width, height, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp);

glGenFramebuffers(1, &entry->framebuffer);
FramebufferManager::SetFramebuffer(entry->framebuffer);
FramebufferManager::FramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_ARRAY, entry->texture, 0);
if (expanded_width != width)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);

SetStage();

return entry;
TextureCache::SetStage();
}

void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
@@ -27,12 +27,6 @@ class TextureCache : public ::TextureCache
GLuint texture;
GLuint framebuffer;

PC_TexFormat pcfmt;

int gl_format;
int gl_iformat;
int gl_type;

//TexMode0 mode; // current filter and clamp modes that texture is set to
//TexMode1 mode1; // current filter and clamp modes that texture is set to

@@ -53,10 +47,7 @@ class TextureCache : public ::TextureCache

~TextureCache();

TCacheEntryBase* CreateTexture(unsigned int width, unsigned int height,
unsigned int tex_levels, PC_TexFormat pcfmt) override;

TCacheEntryBase* CreateRenderTargetTexture(unsigned int scaled_tex_w, unsigned int scaled_tex_h, unsigned int layers) override;
TCacheEntryBase* CreateTexture(const TCacheEntryConfig& config) override;

void CompileShaders() override;
void DeleteShaders() override;
@@ -28,6 +28,7 @@ std::string Statistics::ToString()
{
std::string str;
str += StringFromFormat("Textures created: %i\n", stats.numTexturesCreated);
str += StringFromFormat("Textures uploaded: %i\n", stats.numTexturesUploaded);
str += StringFromFormat("Textures alive: %i\n", stats.numTexturesAlive);
str += StringFromFormat("pshaders created: %i\n", stats.numPixelShadersCreated);
str += StringFromFormat("pshaders alive: %i\n", stats.numPixelShadersAlive);
@@ -18,6 +18,7 @@ struct Statistics
int numVertexShadersAlive;

int numTexturesCreated;
int numTexturesUploaded;
int numTexturesAlive;

int numVertexLoaders;

0 comments on commit 5357b9c

Please sign in to comment.
You can’t perform that action at this time.