TextureCache: Ensure that all render target textures have as many layers as the frame buffer.

Also fixes a case where the D3D code path did not initialize num_layers leading to undefined behaviour.
This commit is contained in:
Jules Blok 2014-11-06 11:41:39 +01:00
parent 02ad1a36ea
commit 8210b9c915
7 changed files with 13 additions and 15 deletions

View File

@ -21,8 +21,6 @@ int FramebufferManager::m_targetHeight;
int FramebufferManager::m_msaaSamples; int FramebufferManager::m_msaaSamples;
GLenum FramebufferManager::m_textureType; GLenum FramebufferManager::m_textureType;
int FramebufferManager::m_EFBLayers;
GLuint FramebufferManager::m_efbFramebuffer; GLuint FramebufferManager::m_efbFramebuffer;
GLuint FramebufferManager::m_xfbFramebuffer; GLuint FramebufferManager::m_xfbFramebuffer;
GLuint FramebufferManager::m_efbColor; GLuint FramebufferManager::m_efbColor;

View File

@ -74,8 +74,6 @@ public:
// Resolved framebuffer is only used in MSAA mode. // Resolved framebuffer is only used in MSAA mode.
static GLuint GetResolvedFramebuffer() { return m_resolvedFramebuffer; } static GLuint GetResolvedFramebuffer() { return m_resolvedFramebuffer; }
static int GetEFBLayers() { return m_EFBLayers; }
static void SetFramebuffer(GLuint fb); static void SetFramebuffer(GLuint fb);
// If in MSAA mode, this will perform a resolve of the specified rectangle, and return the resolve target as a texture ID. // If in MSAA mode, this will perform a resolve of the specified rectangle, and return the resolve target as a texture ID.
@ -103,8 +101,6 @@ private:
static int m_msaaSamples; static int m_msaaSamples;
static GLenum m_textureType; static GLenum m_textureType;
static int m_EFBLayers;
static GLuint m_efbFramebuffer; static GLuint m_efbFramebuffer;
static GLuint m_xfbFramebuffer; static GLuint m_xfbFramebuffer;
static GLuint m_efbColor; static GLuint m_efbColor;

View File

@ -221,10 +221,7 @@ TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(
gl_type = GL_UNSIGNED_BYTE; gl_type = GL_UNSIGNED_BYTE;
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, gl_iformat, scaled_tex_w, scaled_tex_h, FramebufferManager::GetEFBLayers(), 0, gl_format, gl_type, nullptr);
entry->num_layers = FramebufferManager::GetEFBLayers();
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, gl_iformat, scaled_tex_w, scaled_tex_h, entry->num_layers, 0, gl_format, gl_type, nullptr);
glBindTexture(GL_TEXTURE_2D_ARRAY, 0); glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
glGenFramebuffers(1, &entry->framebuffer); glGenFramebuffers(1, &entry->framebuffer);

View File

@ -12,6 +12,8 @@ const XFBSourceBase* FramebufferManagerBase::m_overlappingXFBArray[MAX_VIRTUAL_X
unsigned int FramebufferManagerBase::s_last_xfb_width = 1; unsigned int FramebufferManagerBase::s_last_xfb_width = 1;
unsigned int FramebufferManagerBase::s_last_xfb_height = 1; unsigned int FramebufferManagerBase::s_last_xfb_height = 1;
unsigned int FramebufferManagerBase::m_EFBLayers = 1;
FramebufferManagerBase::FramebufferManagerBase() FramebufferManagerBase::FramebufferManagerBase()
{ {
m_realXFBSource = nullptr; m_realXFBSource = nullptr;

View File

@ -55,6 +55,8 @@ public:
static int ScaleToVirtualXfbWidth(int x, unsigned int backbuffer_width); static int ScaleToVirtualXfbWidth(int x, unsigned int backbuffer_width);
static int ScaleToVirtualXfbHeight(int y, unsigned int backbuffer_height); static int ScaleToVirtualXfbHeight(int y, unsigned int backbuffer_height);
static int GetEFBLayers() { return m_EFBLayers; }
protected: protected:
struct VirtualXFB struct VirtualXFB
{ {
@ -70,6 +72,8 @@ protected:
typedef std::list<VirtualXFB> VirtualXFBListType; typedef std::list<VirtualXFB> VirtualXFBListType;
static unsigned int m_EFBLayers;
private: private:
virtual XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height) = 0; virtual XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height) = 0;
// TODO: figure out why OGL is different for this guy // TODO: figure out why OGL is different for this guy

View File

@ -538,7 +538,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage,
entry->Load(width, height, expandedWidth, 0); entry->Load(width, height, expandedWidth, 0);
} }
entry->SetGeneralParameters(address, texture_size, full_format, entry->num_mipmaps); entry->SetGeneralParameters(address, texture_size, full_format, entry->num_mipmaps, entry->num_layers);
entry->SetDimensions(nativeW, nativeH, width, height); entry->SetDimensions(nativeW, nativeH, width, height);
entry->hash = tex_hash; entry->hash = tex_hash;
@ -895,12 +895,12 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat
TCacheEntryBase *entry = textures[dstAddr]; TCacheEntryBase *entry = textures[dstAddr];
if (entry) if (entry)
{ {
if (entry->type == TCET_EC_DYNAMIC && entry->native_width == tex_w && entry->native_height == tex_h) if (entry->type == TCET_EC_DYNAMIC && entry->native_width == tex_w && entry->native_height == tex_h && entry->num_layers == FramebufferManagerBase::GetEFBLayers())
{ {
scaled_tex_w = tex_w; scaled_tex_w = tex_w;
scaled_tex_h = tex_h; scaled_tex_h = tex_h;
} }
else if (!(entry->type == TCET_EC_VRAM && entry->virtual_width == scaled_tex_w && entry->virtual_height == scaled_tex_h)) else if (!(entry->type == TCET_EC_VRAM && entry->virtual_width == scaled_tex_w && entry->virtual_height == scaled_tex_h && entry->num_layers == FramebufferManagerBase::GetEFBLayers()))
{ {
if (entry->type == TCET_EC_VRAM) if (entry->type == TCET_EC_VRAM)
{ {
@ -923,7 +923,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat
textures[dstAddr] = entry = AllocateRenderTarget(scaled_tex_w, scaled_tex_h); textures[dstAddr] = entry = AllocateRenderTarget(scaled_tex_w, scaled_tex_h);
// TODO: Using the wrong dstFormat, dumb... // TODO: Using the wrong dstFormat, dumb...
entry->SetGeneralParameters(dstAddr, 0, dstFormat, 1); entry->SetGeneralParameters(dstAddr, 0, dstFormat, 1, FramebufferManagerBase::GetEFBLayers());
entry->SetDimensions(tex_w, tex_h, scaled_tex_w, scaled_tex_h); entry->SetDimensions(tex_w, tex_h, scaled_tex_w, scaled_tex_h);
entry->SetHashes(TEXHASH_INVALID); entry->SetHashes(TEXHASH_INVALID);
entry->type = TCET_EC_VRAM; entry->type = TCET_EC_VRAM;

View File

@ -47,12 +47,13 @@ public:
int frameCount; int frameCount;
void SetGeneralParameters(u32 _addr, u32 _size, u32 _format, unsigned int _num_mipmaps) void SetGeneralParameters(u32 _addr, u32 _size, u32 _format, unsigned int _num_mipmaps, unsigned int _num_layers)
{ {
addr = _addr; addr = _addr;
size_in_bytes = _size; size_in_bytes = _size;
format = _format; format = _format;
num_mipmaps = _num_mipmaps; num_mipmaps = _num_mipmaps;
num_layers = _num_layers;
} }
void SetDimensions(unsigned int _native_width, unsigned int _native_height, unsigned int _virtual_width, unsigned int _virtual_height) void SetDimensions(unsigned int _native_width, unsigned int _native_height, unsigned int _virtual_width, unsigned int _virtual_height)