gsdx-ogl: rework palette texture handling

Redirect the red channel to alpha channel for 8 bits texture.

It avoid special management in the shader
This commit is contained in:
Gregory Hainaut 2015-06-14 10:02:30 +02:00
parent cd4c8b5ce4
commit 8393ba56d6
9 changed files with 39 additions and 39 deletions

View File

@ -86,6 +86,7 @@ PFNGLCLIENTWAITSYNCPROC gl_ClientWaitSync = NU
PFNGLFLUSHMAPPEDBUFFERRANGEPROC gl_FlushMappedBufferRange = NULL;
PFNGLBLENDEQUATIONSEPARATEPROC gl_BlendEquationSeparate = NULL;
PFNGLBLENDFUNCSEPARATEPROC gl_BlendFuncSeparate = NULL;
PFNGLTEXPARAMETERIPROC gl_TexParameteri = NULL;
// GL4.0
PFNGLUNIFORMSUBROUTINESUIVPROC gl_UniformSubroutinesuiv = NULL;
// GL4.1
@ -126,6 +127,7 @@ PFNGLTEXTURESUBIMAGE2DPROC gl_TextureSubImage2D = NULL;
PFNGLCOPYTEXTURESUBIMAGE2DPROC gl_CopyTextureSubImage2D = NULL;
PFNGLBINDTEXTUREUNITPROC gl_BindTextureUnit = NULL;
PFNGLGETTEXTUREIMAGEPROC gl_GetTextureImage = NULL;
PFNGLTEXTUREPARAMETERIPROC gl_TextureParameteri = NULL;
PFNGLCREATEFRAMEBUFFERSPROC gl_CreateFramebuffers = NULL;
PFNGLCLEARNAMEDFRAMEBUFFERFVPROC gl_ClearNamedFramebufferfv = NULL;
@ -182,6 +184,11 @@ namespace Emulate_DSA {
glGetTexImage(GL_TEXTURE_2D, level, format, type, pixels);
}
void APIENTRY TextureParameteri (GLuint texture, GLenum pname, GLint param) {
BindTextureUnit(7, texture);
gl_TexParameteri(GL_TEXTURE_2D, pname, param);
}
// Framebuffer entry point
GLenum fb_target = 0;
void SetFramebufferTarget(GLenum target) {
@ -292,6 +299,7 @@ namespace Emulate_DSA {
gl_TextureSubImage2D = TextureSubImage;
gl_CopyTextureSubImage2D = CopyTextureSubImage;
gl_GetTextureImage = GetTexureImage;
gl_TextureParameteri = TextureParameteri;
gl_CreateFramebuffers = CreateFramebuffers;
gl_ClearNamedFramebufferfv = ClearNamedFramebufferfv;

View File

@ -205,6 +205,11 @@ typedef void (APIENTRYP PFNGLTEXTUREBARRIERPROC) (void);
typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels);
#endif /* GL_VERSION_4_5 */
// only exist in glcorearb.h
#ifndef PFNGLTEXPARAMETERIPROC
typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
#endif
extern PFNGLACTIVETEXTUREPROC gl_ActiveTexture;
extern PFNGLBLENDCOLORPROC gl_BlendColor;
@ -270,6 +275,7 @@ extern PFNGLCLIENTWAITSYNCPROC gl_ClientWaitSync;
extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC gl_FlushMappedBufferRange;
extern PFNGLBLENDEQUATIONSEPARATEPROC gl_BlendEquationSeparate;
extern PFNGLBLENDFUNCSEPARATEPROC gl_BlendFuncSeparate;
extern PFNGLTEXPARAMETERIPROC gl_TexParameteri;
// GL4.0
extern PFNGLUNIFORMSUBROUTINESUIVPROC gl_UniformSubroutinesuiv;
// GL4.1
@ -310,6 +316,7 @@ extern PFNGLTEXTURESUBIMAGE2DPROC gl_TextureSubImage2D;
extern PFNGLCOPYTEXTURESUBIMAGE2DPROC gl_CopyTextureSubImage2D;
extern PFNGLBINDTEXTUREUNITPROC gl_BindTextureUnit;
extern PFNGLGETTEXTUREIMAGEPROC gl_GetTextureImage;
extern PFNGLTEXTUREPARAMETERIPROC gl_TextureParameteri;
extern PFNGLCREATEFRAMEBUFFERSPROC gl_CreateFramebuffers;
extern PFNGLCLEARNAMEDFRAMEBUFFERFVPROC gl_ClearNamedFramebufferfv;

View File

@ -526,17 +526,16 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
ps_sel.wmt = context->CLAMP.WMT;
if (tex->m_palette) {
ps_sel.fmt = cpsm.fmt | 4;
ps_sel.ifmt = !tex->m_alpha_palette ? 0
: (context->TEX0.PSM == 0x1B) ? 3
: (context->TEX0.PSM == 0x24) ? 2
: (context->TEX0.PSM == 0x2C) ? 1
ps_sel.ifmt = !tex->m_target ? 0
: (context->TEX0.PSM == PSM_PSMT4HL) ? 2
: (context->TEX0.PSM == PSM_PSMT4HH) ? 1
: 0;
// In standard mode palette is only used when alpha channel of the RT is
// reinterpreted as an index. Star Ocean 3 uses it to emulate a stencil buffer.
// It is a very bad idea to force bilinear filtering on it.
if (ps_sel.ifmt)
bilinear = m_vt.IsLinear();
if (tex->m_target)
bilinear &= m_vt.IsLinear();
//GL_INS("Use palette with format %d and index format %d", ps_sel.fmt, ps_sel.ifmt);
} else {

View File

@ -800,7 +800,6 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
bool linear = true;
if (psm.pal > 0) {
src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
src->m_alpha_palette = true;
// Palette is used to interpret the alpha channel of the RT as an index.
// Star Ocean 3 uses it to emulate a stencil buffer.
// It is a very bad idea to force bilinear filtering on it.
@ -963,7 +962,6 @@ void GSTextureCache::Surface::Update()
GSTextureCache::Source::Source(GSRenderer* r, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, uint8* temp)
: Surface(r, temp)
, m_palette(NULL)
, m_alpha_palette(false)
, m_initpalette(true)
, m_target(false)
, m_complete(false)

View File

@ -57,7 +57,6 @@ public:
public:
GSTexture* m_palette;
bool m_alpha_palette; // in opengl palette value is either in red or alpha channel
bool m_initpalette;
uint32 m_valid[MAX_PAGES]; // each uint32 bits map to the 32 blocks of that page
uint32* m_clut;

View File

@ -257,6 +257,11 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, int format, GLuint fbo_read)
case GSTexture::DepthStencil:
gl_CreateTextures(GL_TEXTURE_2D, 1, &m_texture_id);
gl_TextureStorage2D(m_texture_id, 1+GL_TEX_LEVEL_0, m_format, m_size.x, m_size.y);
if (m_format == GL_R8) {
// Emulate DX behavior, beside it avoid special code in shader to differentiate
// palette texture from a GL_RGBA target or a GL_R texture.
gl_TextureParameteri(m_texture_id, GL_TEXTURE_SWIZZLE_A, GL_RED);
}
break;
case GSTexture::Backbuffer:
default:

View File

@ -79,6 +79,7 @@ void GSWndGL::PopulateGlFunction()
*(void**)&(gl_DeleteSync) = GetProcAddress("glDeleteSync");
*(void**)&(gl_ClientWaitSync) = GetProcAddress("glClientWaitSync");
*(void**)&(gl_FlushMappedBufferRange) = GetProcAddress("glFlushMappedBufferRange");
*(void**)&(gl_TexParameteri) = GetProcAddress("glTexParameteri");
// GL4.0
*(void**)&(gl_UniformSubroutinesuiv) = GetProcAddress("glUniformSubroutinesuiv", true);
*(void**)&(gl_BlendEquationSeparateiARB) = GetProcAddress("glBlendEquationSeparateiARB", true);
@ -129,6 +130,7 @@ void GSWndGL::PopulateGlFunction()
*(void**)&(gl_CopyTextureSubImage2D) = GetProcAddress("glCopyTextureSubImage2D", true);
*(void**)&(gl_BindTextureUnit) = GetProcAddress("glBindTextureUnit", true);
*(void**)&(gl_GetTextureImage) = GetProcAddress("glGetTextureImage", true);
*(void**)&(gl_TextureParameteri) = GetProcAddress("glTextureParameteri", true);
*(void**)&(gl_CreateFramebuffers) = GetProcAddress("glCreateFramebuffers", true);
*(void**)&(gl_ClearNamedFramebufferfv) = GetProcAddress("glClearNamedFramebufferfv", true);

View File

@ -158,6 +158,7 @@ mat4 sample_4c(vec4 uv)
{
mat4 c;
// FIXME investigate texture gather (filtering impact?)
c[0] = sample_c(uv.xy);
c[1] = sample_c(uv.zy);
c[2] = sample_c(uv.xw);
@ -171,36 +172,26 @@ uvec4 sample_4_index(vec4 uv)
vec4 c;
// Either GSdx will send a texture that contains a single channel
// in this case we must use the red channel (whereas Dx uses alpha)
// in this case the red channel is remapped as alpha channel
//
// Or we have an old RT (ie RGBA8) that contains index (4/8) in the alpha channel
#if PS_IFMT == 0
// Single channel texture
c.x = sample_c(uv.xy).r;
c.y = sample_c(uv.zy).r;
c.z = sample_c(uv.xw).r;
c.w = sample_c(uv.zw).r;
//return c * 255.0/256.0 + 0.5/256.0;
#else
// 4 channels texture
// FIXME investigate texture gather (filtering impact?)
c.x = sample_c(uv.xy).a;
c.y = sample_c(uv.zy).a;
c.z = sample_c(uv.xw).a;
c.w = sample_c(uv.zw).a;
#endif
uvec4 i = uvec4(c * 255.0f + 0.5f); // Denormalize value
//return (i/uint(16)) & uint(0xF);
#if PS_IFMT == 1
// 4HH alpha
// 4HH
return i >> 4u;
#elif PS_IFMT == 2
// 4HL alpha
// 4HL
return i & 16u;
#else
// 8 bits alpha or red
// 8 bits
return i;
#endif

View File

@ -937,6 +937,7 @@ static const char* tfx_fs_all_glsl =
"{\n"
" mat4 c;\n"
"\n"
" // FIXME investigate texture gather (filtering impact?)\n"
" c[0] = sample_c(uv.xy);\n"
" c[1] = sample_c(uv.zy);\n"
" c[2] = sample_c(uv.xw);\n"
@ -950,36 +951,26 @@ static const char* tfx_fs_all_glsl =
" vec4 c;\n"
"\n"
" // Either GSdx will send a texture that contains a single channel\n"
" // in this case we must use the red channel (whereas Dx uses alpha)\n"
" // in this case the red channel is remapped as alpha channel\n"
" //\n"
" // Or we have an old RT (ie RGBA8) that contains index (4/8) in the alpha channel\n"
"\n"
"#if PS_IFMT == 0\n"
" // Single channel texture\n"
" c.x = sample_c(uv.xy).r;\n"
" c.y = sample_c(uv.zy).r;\n"
" c.z = sample_c(uv.xw).r;\n"
" c.w = sample_c(uv.zw).r;\n"
" //return c * 255.0/256.0 + 0.5/256.0;\n"
"#else\n"
" // 4 channels texture\n"
" // FIXME investigate texture gather (filtering impact?)\n"
" c.x = sample_c(uv.xy).a;\n"
" c.y = sample_c(uv.zy).a;\n"
" c.z = sample_c(uv.xw).a;\n"
" c.w = sample_c(uv.zw).a;\n"
"#endif\n"
"\n"
" uvec4 i = uvec4(c * 255.0f + 0.5f); // Denormalize value\n"
" //return (i/uint(16)) & uint(0xF);\n"
"\n"
"#if PS_IFMT == 1\n"
" // 4HH alpha\n"
" // 4HH\n"
" return i >> 4u;\n"
"#elif PS_IFMT == 2\n"
" // 4HL alpha\n"
" // 4HL\n"
" return i & 16u;\n"
"#else\n"
" // 8 bits alpha or red\n"
" // 8 bits\n"
" return i;\n"
"#endif\n"
"\n"