mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
cd4c8b5ce4
commit
8393ba56d6
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue