mirror of https://github.com/PCSX2/pcsx2.git
gsdx-tc: GPU accelerate 8 bits texture conversion
Only native is supported currently
This commit is contained in:
parent
a8bcc760b4
commit
d29e375f72
|
@ -498,7 +498,7 @@ class GSDeviceOGL : public GSDevice
|
|||
|
||||
struct {
|
||||
GLuint vs; // program object
|
||||
GLuint ps[14]; // program object
|
||||
GLuint ps[15]; // program object
|
||||
GLuint ln; // sampler object
|
||||
GLuint pt; // sampler object
|
||||
GSDepthStencilOGL* dss;
|
||||
|
|
|
@ -139,7 +139,10 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
|||
uint32 t_psm = (t->m_dirty_alpha) ? t->m_TEX0.PSM & ~0x1 : t->m_TEX0.PSM;
|
||||
|
||||
if (GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0, t_psm)) {
|
||||
if (psm == PSM_PSMT8) {
|
||||
if (!IsOpenGL() && (psm == PSM_PSMT8)) {
|
||||
// OpenGL can convert the texture directly in the GPU. Not sure we want to keep this
|
||||
// code for DX. It fixes effect but it is slow (MGS3)
|
||||
|
||||
// It is a complex to convert the code in shader. As a reference, let's do it on the CPU, it will
|
||||
// be slow but
|
||||
// 1/ it just works :)
|
||||
|
@ -808,9 +811,18 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||
{
|
||||
// TODO: clean up this mess
|
||||
|
||||
// Shader 11 convert depth to color
|
||||
// Shader 14 convert 32 bits color to 8 bits color
|
||||
int shader = dst->m_type != RenderTarget ? 11 : 0;
|
||||
|
||||
if (TEX0.PSM == PSM_PSMT8) {
|
||||
GL_INS("Reading RT as a packed-indexed 8 bits format");
|
||||
shader = 14; // ask a conversion to 8 bits format
|
||||
}
|
||||
|
||||
#ifdef ENABLE_OGL_DEBUG
|
||||
if (TEX0.PSM == PSM_PSMT8 || TEX0.PSM == PSM_PSMT4) {
|
||||
GL_INS("ERROR: Reading RT as a packed-indexed (0x%x) format is not supported", TEX0.PSM);
|
||||
if (TEX0.PSM == PSM_PSMT4) {
|
||||
GL_INS("ERROR: Reading RT as a packed-indexed 4 bits format is not supported");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -902,6 +914,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||
// Try to extract a texture bigger than the RT. Current solution is to rescale the size
|
||||
// of the texture to fit in the RT. In my opinion, it would be better to increase the size of
|
||||
// the RT
|
||||
// TODO investigate this code is correct (maybe linked to custom resolution?)
|
||||
if(w > dstsize.x)
|
||||
{
|
||||
scale.x = (float)dstsize.x / tw;
|
||||
|
@ -920,6 +933,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||
|
||||
GSTexture* sTex = src->m_texture ? src->m_texture : dst->m_texture;
|
||||
GSTexture* dTex = m_renderer->m_dev->CreateRenderTarget(w, h, false);
|
||||
|
||||
// GH: by default (m_paltex == 0) GSdx converts texture to the 32 bit format
|
||||
// However it is different here. We want to reuse a Render Target as a texture.
|
||||
// Because the texture is already on the GPU, CPU can't convert it.
|
||||
|
@ -952,14 +966,12 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||
// copy. Likely a speed boost and memory usage reduction.
|
||||
bool linear = (TEX0.PSM == PSM_PSMCT32 || TEX0.PSM == PSM_PSMCT24);
|
||||
|
||||
int shader = dst->m_type != RenderTarget ? 11 : 0;
|
||||
|
||||
if(!src->m_texture)
|
||||
{
|
||||
src->m_texture = dTex;
|
||||
}
|
||||
|
||||
if((sRect == dRect).alltrue() && !shader)
|
||||
if ((sRect == dRect).alltrue() && !shader)
|
||||
{
|
||||
if (half_right) {
|
||||
// You typically hit this code in snow engine game. Dstsize is the size of of Dx/GL RT
|
||||
|
|
|
@ -196,6 +196,70 @@ void ps_main13()
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main14
|
||||
void ps_main14()
|
||||
{
|
||||
// Convert a RGBA texture into a 8 bits packed texture
|
||||
// Input column: 8x2 RGBA pixels
|
||||
// 0: 8 RGBA
|
||||
// 1: 8 RGBA
|
||||
// Output column: 16x4 Index pixels
|
||||
// 0: 8 R | 8 B
|
||||
// 1: 8 R | 8 B
|
||||
// 2: 8 G | 8 A
|
||||
// 3: 8 G | 8 A
|
||||
|
||||
float c;
|
||||
|
||||
uvec2 sel = uvec2(gl_FragCoord.xy) % uvec2(16u, 16u);
|
||||
ivec2 tb = ((ivec2(gl_FragCoord.xy) & ~ivec2(15, 3)) >> 1u);
|
||||
|
||||
int ty = tb.y | (int(gl_FragCoord.y) & 1);
|
||||
int txN = tb.x | (int(gl_FragCoord.x) & 7);
|
||||
int txH = tb.x | ((int(gl_FragCoord.x) + 4) & 7);
|
||||
|
||||
vec4 cN = texelFetch(TextureSampler, ivec2(txN, ty), 0);
|
||||
vec4 cH = texelFetch(TextureSampler, ivec2(txH, ty), 0);
|
||||
|
||||
// Potential speed optimization. There is a high probability that
|
||||
// game only want to extract a single channel (blue). It will allow
|
||||
// to remove the sel.x condition check
|
||||
|
||||
if ((sel.y & 4u) == 0u) {
|
||||
// Column 0 and 2
|
||||
if ((sel.y & 3u) < 2u) {
|
||||
// first 2 lines of the col
|
||||
if (sel.x < 8u)
|
||||
c = cN.r;
|
||||
else
|
||||
c = cN.b;
|
||||
} else {
|
||||
if (sel.x < 8u)
|
||||
c = cH.g;
|
||||
else
|
||||
c = cH.a;
|
||||
}
|
||||
} else {
|
||||
// Column 1 and 3
|
||||
if ((sel.y & 3u) < 2u) {
|
||||
// first 2 lines of the col
|
||||
if (sel.x < 8u)
|
||||
c = cH.r;
|
||||
else
|
||||
c = cH.b;
|
||||
} else {
|
||||
if (sel.x < 8u)
|
||||
c = cN.g;
|
||||
else
|
||||
c = cN.a;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SV_Target0 = vec4(c);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main7
|
||||
void ps_main7()
|
||||
{
|
||||
|
|
|
@ -221,6 +221,70 @@ static const char* convert_glsl =
|
|||
"}\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#ifdef ps_main14\n"
|
||||
"void ps_main14()\n"
|
||||
"{\n"
|
||||
" // Convert a RGBA texture into a 8 bits packed texture\n"
|
||||
" // Input column: 8x2 RGBA pixels\n"
|
||||
" // 0: 8 RGBA\n"
|
||||
" // 1: 8 RGBA\n"
|
||||
" // Output column: 16x4 Index pixels\n"
|
||||
" // 0: 8 R | 8 B\n"
|
||||
" // 1: 8 R | 8 B\n"
|
||||
" // 2: 8 G | 8 A\n"
|
||||
" // 3: 8 G | 8 A\n"
|
||||
"\n"
|
||||
" float c;\n"
|
||||
"\n"
|
||||
" uvec2 sel = uvec2(gl_FragCoord.xy) % uvec2(16u, 16u);\n"
|
||||
" ivec2 tb = ((ivec2(gl_FragCoord.xy) & ~ivec2(15, 3)) >> 1u);\n"
|
||||
"\n"
|
||||
" int ty = tb.y | (int(gl_FragCoord.y) & 1);\n"
|
||||
" int txN = tb.x | (int(gl_FragCoord.x) & 7);\n"
|
||||
" int txH = tb.x | ((int(gl_FragCoord.x) + 4) & 7);\n"
|
||||
"\n"
|
||||
" vec4 cN = texelFetch(TextureSampler, ivec2(txN, ty), 0);\n"
|
||||
" vec4 cH = texelFetch(TextureSampler, ivec2(txH, ty), 0);\n"
|
||||
"\n"
|
||||
" // Potential speed optimization. There is a high probability that\n"
|
||||
" // game only want to extract a single channel (blue). It will allow\n"
|
||||
" // to remove the sel.x condition check\n"
|
||||
"\n"
|
||||
" if ((sel.y & 4u) == 0u) {\n"
|
||||
" // Column 0 and 2\n"
|
||||
" if ((sel.y & 3u) < 2u) {\n"
|
||||
" // first 2 lines of the col\n"
|
||||
" if (sel.x < 8u)\n"
|
||||
" c = cN.r;\n"
|
||||
" else\n"
|
||||
" c = cN.b;\n"
|
||||
" } else {\n"
|
||||
" if (sel.x < 8u)\n"
|
||||
" c = cH.g;\n"
|
||||
" else\n"
|
||||
" c = cH.a;\n"
|
||||
" }\n"
|
||||
" } else {\n"
|
||||
" // Column 1 and 3\n"
|
||||
" if ((sel.y & 3u) < 2u) {\n"
|
||||
" // first 2 lines of the col\n"
|
||||
" if (sel.x < 8u)\n"
|
||||
" c = cH.r;\n"
|
||||
" else\n"
|
||||
" c = cH.b;\n"
|
||||
" } else {\n"
|
||||
" if (sel.x < 8u)\n"
|
||||
" c = cN.g;\n"
|
||||
" else\n"
|
||||
" c = cN.a;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" SV_Target0 = vec4(c);\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#ifdef ps_main7\n"
|
||||
"void ps_main7()\n"
|
||||
"{\n"
|
||||
|
|
Loading…
Reference in New Issue