gsdx-ogl: implement the wildhack on the GPU

Likely much faster for opengl and much easier to implement

Note: hopefully UserHacks_round_sprite_offset will replace it
This commit is contained in:
Gregory Hainaut 2015-04-13 18:34:43 +02:00
parent 50bac01d89
commit 418f2e69a8
7 changed files with 23 additions and 49 deletions

View File

@ -659,6 +659,7 @@ GLuint GSDeviceOGL::CompileVS(VSSelector sel)
+ format("#define VS_LOGZ %d\n", sel.logz)
+ format("#define VS_TME %d\n", sel.tme)
+ format("#define VS_FST %d\n", sel.fst)
+ format("#define VS_WILDHACK %d\n", sel.wildhack)
;
return m_shader->Compile("tfx.glsl", "vs_main", GL_VERTEX_SHADER, tfx_glsl, macro);
@ -1063,16 +1064,6 @@ void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t count)
m_va->UploadVB(vertices, count);
}
bool GSDeviceOGL::IAMapVertexBuffer(void** vertex, size_t stride, size_t count)
{
return m_va->MapVB(vertex, count);
}
void GSDeviceOGL::IAUnmapVertexBuffer()
{
m_va->UnmapVB();
}
void GSDeviceOGL::IASetIndexBuffer(const void* index, size_t count)
{
m_va->UploadIB(index, count);

View File

@ -273,6 +273,7 @@ class GSDeviceOGL : public GSDevice
{
struct
{
uint32 wildhack:1;
uint32 bppz:2;
uint32 logz:1;
// Next param will be handle by subroutine
@ -283,12 +284,12 @@ class GSDeviceOGL : public GSDevice
uint32 key;
};
operator uint32() {return key & 0x3f;}
operator uint32() {return key & 0x7f;}
VSSelector() : key(0) {}
VSSelector(uint32 k) : key(k) {}
static uint32 size() { return 1 << 5; }
static uint32 size() { return 1 << 6; }
};
__aligned(struct, 32) PSConstantBuffer
@ -516,7 +517,7 @@ class GSDeviceOGL : public GSDevice
float bf; // blend factor
} m_state;
GLuint m_vs[1<<5];
GLuint m_vs[1<<6];
GLuint m_gs;
GLuint m_ps_ss[1<<3];
GSDepthStencilOGL* m_om_dss[1<<6];
@ -599,8 +600,6 @@ class GSDeviceOGL : public GSDevice
void IASetPrimitiveTopology(GLenum topology);
void IASetVertexBuffer(const void* vertices, size_t count);
bool IAMapVertexBuffer(void** vertex, size_t stride, size_t count);
void IAUnmapVertexBuffer();
void IASetIndexBuffer(const void* index, size_t count);
void PSSetShaderResource(GLuint sr);

View File

@ -122,28 +122,7 @@ void GSRendererOGL::SetupIA()
if (!GLLoader::found_geometry_shader)
EmulateGS();
void* ptr = NULL;
if(UserHacks_WildHack && !isPackedUV_HackFlag) {
// FIXME: why not put it on the Vertex shader
if(dev->IAMapVertexBuffer(&ptr, sizeof(GSVertex), m_vertex.next))
{
GSVector4i::storent(ptr, m_vertex.buff, sizeof(GSVertex) * m_vertex.next);
GSVertex* RESTRICT d = (GSVertex*)ptr;
for(unsigned int i = 0; i < m_vertex.next; i++)
{
if(PRIM->TME && PRIM->FST) d[i].UV &= 0x3FEF3FEF;
}
dev->IAUnmapVertexBuffer();
}
} else {
// By default use the common path (in case it can be made faster)
dev->IASetVertexBuffer(m_vertex.buff, m_vertex.next);
}
dev->IASetVertexBuffer(m_vertex.buff, m_vertex.next);
dev->IASetIndexBuffer(m_index.buff, m_index.tail);
GLenum t = 0;
@ -284,6 +263,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
vs_sel.tme = PRIM->TME;
vs_sel.fst = PRIM->FST;
vs_sel.logz = m_logz ? 1 : 0;
vs_sel.wildhack = (UserHacks_WildHack && !isPackedUV_HackFlag) ? 1 : 0;
// The real GS appears to do no masking based on the Z buffer format and writing larger Z values
// than the buffer supports seems to be an error condition on the real GS, causing it to crash.

View File

@ -328,10 +328,6 @@ public:
#endif
}
bool MapVB(void **pointer, size_t count) { return m_vb->Map(pointer, count); }
void UnmapVB() { m_vb->Unmap(); }
~GSVertexBufferStateOGL()
{
gl_DeleteVertexArrays(1, &m_va);

View File

@ -359,14 +359,14 @@ static const char* merge_glsl =
"void ps_main0()\n"
"{\n"
" vec4 c = texture(TextureSampler, PSin_t);\n"
" c.a = min(c.a * 2.0, 1.0);\n"
" c.a = min(c.a * 2.0, 1.0);\n"
" SV_Target0 = c;\n"
"}\n"
"\n"
"void ps_main1()\n"
"{\n"
" vec4 c = texture(TextureSampler, PSin_t);\n"
" c.a = BGColor.a;\n"
" c.a = BGColor.a;\n"
" SV_Target0 = c;\n"
"}\n"
"\n"
@ -458,8 +458,8 @@ static const char* tfx_glsl =
"#define FMT_16 2\n"
"#define FMT_PAL 4 /* flag bit */\n"
"\n"
"// APITRACE_DEBUG allows to force pixel output to easily detect \n"
"// the fragment computed by primitive \n"
"// APITRACE_DEBUG allows to force pixel output to easily detect\n"
"// the fragment computed by primitive\n"
"#define APITRACE_DEBUG 0\n"
"// TEX_COORD_DEBUG output the uv coordinate as color. It is useful\n"
"// to detect bad sampling due to upscaling\n"
@ -582,7 +582,11 @@ static const char* tfx_glsl =
" {\n"
" if(VS_FST != 0)\n"
" {\n"
" VSout_t.xy = vec2(i_uv) * TextureScale;\n"
" if (VS_WILDHACK == 1) {\n"
" VSout_t.xy = vec2(i_uv & uvec2(0x3FEF, 0x3FEF)) * TextureScale;\n"
" } else {\n"
" VSout_t.xy = vec2(i_uv) * TextureScale;\n"
" }\n"
" VSout_t.w = 1.0f;\n"
" }\n"
" else\n"

View File

@ -33,14 +33,14 @@ layout(binding = 0) uniform sampler2D TextureSampler;
void ps_main0()
{
vec4 c = texture(TextureSampler, PSin_t);
c.a = min(c.a * 2.0, 1.0);
c.a = min(c.a * 2.0, 1.0);
SV_Target0 = c;
}
void ps_main1()
{
vec4 c = texture(TextureSampler, PSin_t);
c.a = BGColor.a;
c.a = BGColor.a;
SV_Target0 = c;
}

View File

@ -131,7 +131,11 @@ void texture_coord()
{
if(VS_FST != 0)
{
VSout_t.xy = vec2(i_uv) * TextureScale;
if (VS_WILDHACK == 1) {
VSout_t.xy = vec2(i_uv & uvec2(0x3FEF, 0x3FEF)) * TextureScale;
} else {
VSout_t.xy = vec2(i_uv) * TextureScale;
}
VSout_t.w = 1.0f;
}
else