GSdx: replaced switch with ifs in the shaders, kingdom hearts should be fixed

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1362 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2009-06-13 19:41:34 +00:00
parent 693bb3bdce
commit 690ef417b1
17 changed files with 362 additions and 150 deletions

View File

@ -126,9 +126,11 @@ static INT32 GSopen(void* dsp, char* title, int mt, int renderer)
case 3: s_gs = new GSRendererHW10(s_basemem, !!mt, s_irq); break; case 3: s_gs = new GSRendererHW10(s_basemem, !!mt, s_irq); break;
case 4: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDevice10()); break; case 4: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDevice10()); break;
case 5: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDevice10()); break; case 5: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDevice10()); break;
#if 0
case 6: s_gs = new GSRendererOGL(s_basemem, !!mt, s_irq); break; case 6: s_gs = new GSRendererOGL(s_basemem, !!mt, s_irq); break;
case 7: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDeviceOGL()); break; case 7: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDeviceOGL()); break;
case 8: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDeviceOGL()); break; case 8: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDeviceOGL()); break;
#endif
case 9: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDeviceNull()); break; case 9: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDeviceNull()); break;
case 10: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDeviceNull()); break; case 10: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDeviceNull()); break;
} }

View File

@ -221,7 +221,7 @@ bool GSDevice10::Create(GSWnd* wnd, bool vsync)
// //
Reset(1, 1, true); Reset(1, 1, false);
// //

View File

@ -26,7 +26,6 @@
class GSDevice10 : public GSDevice class GSDevice10 : public GSDevice
{ {
private:
ID3D10Buffer* m_vb; ID3D10Buffer* m_vb;
size_t m_vb_stride; size_t m_vb_stride;
ID3D10InputLayout* m_layout; ID3D10InputLayout* m_layout;

View File

@ -75,7 +75,7 @@ bool GSDevice7::Create(GSWnd* wnd, bool vsync)
return false; return false;
} }
Reset(1, 1, true); Reset(1, 1, false);
return true; return true;
} }

View File

@ -29,7 +29,7 @@ bool GSDeviceNull::Create(GSWnd* wnd, bool vsync)
return false; return false;
} }
Reset(1, 1, true); Reset(1, 1, false);
return true; return true;
} }

View File

@ -27,11 +27,21 @@
GSDeviceOGL::GSDeviceOGL() GSDeviceOGL::GSDeviceOGL()
: m_hDC(NULL) : m_hDC(NULL)
, m_hGLRC(NULL) , m_hGLRC(NULL)
, m_vbo(0)
, m_fbo(0)
, m_topology(-1)
{ {
m_vertices.stride = 0;
m_vertices.start = 0;
m_vertices.count = 0;
m_vertices.limit = 0;
} }
GSDeviceOGL::~GSDeviceOGL() GSDeviceOGL::~GSDeviceOGL()
{ {
if(m_vbo) glDeleteBuffers(1, &m_vbo);
if(m_fbo) glDeleteFramebuffers(1, &m_fbo);
#ifdef _WINDOWS #ifdef _WINDOWS
if(m_hGLRC) {wglMakeCurrent(NULL, NULL); wglDeleteContext(m_hGLRC);} if(m_hGLRC) {wglMakeCurrent(NULL, NULL); wglDeleteContext(m_hGLRC);}
@ -75,24 +85,40 @@ bool GSDeviceOGL::Create(GSWnd* wnd, bool vsync)
if(!m_hDC) return false; if(!m_hDC) return false;
if(!SetPixelFormat(m_hDC, ChoosePixelFormat(m_hDC, &pfd), &pfd)) if(!SetPixelFormat(m_hDC, ChoosePixelFormat(m_hDC, &pfd), &pfd))
{
return false; return false;
}
m_hGLRC = wglCreateContext(m_hDC); m_hGLRC = wglCreateContext(m_hDC);
if(!m_hGLRC) return false; if(!m_hGLRC) return false;
if(!wglMakeCurrent(m_hDC, m_hGLRC)) if(!wglMakeCurrent(m_hDC, m_hGLRC))
{
return false; return false;
}
if(WGLEW_EXT_swap_control)
{
wglSwapIntervalEXT(vsync ? 1 : 0);
}
#endif #endif
if(glewInit() != GLEW_OK)
{
return false;
}
// const char* exts = (const char*)glGetString(GL_EXTENSIONS); // const char* exts = (const char*)glGetString(GL_EXTENSIONS);
// TODO glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
// TODO: setup layout?
Reset(1, 1, true); GSVector4i r = wnd->GetClientRect();
// Reset(r.width(), r.height(), false);
return true; return true;
} }
@ -102,12 +128,12 @@ bool GSDeviceOGL::Reset(int w, int h, bool fs)
if(!__super::Reset(w, h, fs)) if(!__super::Reset(w, h, fs))
return false; return false;
m_backbuffer = new GSTextureOGL(0); // ??? m_backbuffer = new GSTextureOGL(0, GSTexture::RenderTarget, w, h);
glCullFace(GL_FRONT_AND_BACK); glCullFace(GL_FRONT_AND_BACK);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
glDisable(GL_ALPHA_TEST); glDisable(GL_ALPHA_TEST);
glDisable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
@ -116,76 +142,134 @@ bool GSDeviceOGL::Reset(int w, int h, bool fs)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
// glViewport(0, 0, ?, ?); // glViewport(0, 0, w, h);
if(m_fbo) {glDeleteFramebuffersEXT(1, &m_fbo); m_fbo = 0;}
glGenFramebuffers(1, &m_fbo);
if(m_fbo == 0) return false;
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
return true; return true;
} }
void GSDeviceOGL::Flip() void GSDeviceOGL::Flip()
{ {
// TODO #ifdef _WINDOWS
SwapBuffers(m_hDC);
#endif
} }
void GSDeviceOGL::BeginScene() void GSDeviceOGL::BeginScene()
{ {
// TODO
} }
void GSDeviceOGL::DrawPrimitive() void GSDeviceOGL::DrawPrimitive()
{ {
// TODO glDrawArrays(m_topology, m_vertices.count, m_vertices.start);
} }
void GSDeviceOGL::EndScene() void GSDeviceOGL::EndScene()
{ {
// TODO m_vertices.start += m_vertices.count;
m_vertices.count = 0;
} }
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c) void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
{ {
// TODO // TODO: disable scissor, color mask
glClearColor(c.r, c.g, c.b, c.a);
glClear(GL_COLOR_BUFFER_BIT);
} }
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c) void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c)
{ {
// TODO ClearRenderTarget(t, GSVector4(c) * (1.0f / 255));
} }
void GSDeviceOGL::ClearDepth(GSTexture* t, float c) void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
{ {
// TODO // TODO: disable scissor, depth mask
glClearDepth(c);
glClear(GL_DEPTH_BUFFER_BIT);
} }
void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c) void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
{ {
// TODO // TODO: disable scissor, depth (?) mask
glClearStencil((GLint)c);
glClear(GL_STENCIL_BUFFER_BIT);
} }
GSTexture* GSDeviceOGL::Create(int type, int w, int h, int format) GSTexture* GSDeviceOGL::Create(int type, int w, int h, int format)
{ {
// TODO GLuint texture = 0;
return NULL; switch(type)
{
case GSTexture::RenderTarget:
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
break;
case GSTexture::DepthStencil:
glGenRenderbuffersEXT(1, &texture);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, texture);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH32F_STENCIL8, w, h);
// TODO: depth textures?
break;
case GSTexture::Texture:
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
break;
case GSTexture::Offscreen:
// TODO: ???
break;
}
if(!texture) return false;
GSTextureOGL* t = new GSTextureOGL(texture, type, w, h, format);
switch(type)
{
case GSTexture::RenderTarget:
ClearRenderTarget(t, 0);
break;
case GSTexture::DepthStencil:
ClearDepth(t, 0);
break;
}
return t;
} }
GSTexture* GSDeviceOGL::CreateRenderTarget(int w, int h, int format) GSTexture* GSDeviceOGL::CreateRenderTarget(int w, int h, int format)
{ {
return __super::CreateRenderTarget(w, h, format ? format : 0); // TODO return __super::CreateRenderTarget(w, h, format ? format : GL_RGBA8);
} }
GSTexture* GSDeviceOGL::CreateDepthStencil(int w, int h, int format) GSTexture* GSDeviceOGL::CreateDepthStencil(int w, int h, int format)
{ {
return __super::CreateDepthStencil(w, h, format ? format : 0); // TODO return __super::CreateDepthStencil(w, h, format ? format : GL_DEPTH32F_STENCIL8); // TODO: GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8
} }
GSTexture* GSDeviceOGL::CreateTexture(int w, int h, int format) GSTexture* GSDeviceOGL::CreateTexture(int w, int h, int format)
{ {
return __super::CreateTexture(w, h, format ? format : 0); // TODO return __super::CreateTexture(w, h, format ? format : GL_RGBA8);
} }
GSTexture* GSDeviceOGL::CreateOffscreen(int w, int h, int format) GSTexture* GSDeviceOGL::CreateOffscreen(int w, int h, int format)
{ {
return __super::CreateOffscreen(w, h, format ? format : 0); // TODO return __super::CreateOffscreen(w, h, format ? format : GL_RGBA8);
} }
GSTexture* GSDeviceOGL::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format) GSTexture* GSDeviceOGL::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format)
@ -209,3 +293,50 @@ void GSDeviceOGL::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool lin
{ {
// TODO // TODO
} }
void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t stride, size_t count)
{
ASSERT(m_vertices.count == 0);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
if(count * stride > m_vertices.limit * m_vertices.stride)
{
m_vertices.start = 0;
m_vertices.count = 0;
m_vertices.limit = 0;
}
if(m_vertices.limit == 0)
{
m_vertices.limit = max(count * 3 / 2, 10000);
glBufferData(GL_ARRAY_BUFFER, m_vertices.limit * stride, NULL, GL_DYNAMIC_DRAW); // GL_STREAM_DRAW?
}
if(m_vertices.start + count > m_vertices.limit || stride != m_vertices.stride)
{
m_vertices.start = 0; // TODO: how to discard and not overwrite previous data?
}
if(GLvoid* v = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY))
{
GSVector4i::storent((uint8*)v + m_vertices.start * stride, vertices, count * stride);
glUnmapBuffer(GL_ARRAY_BUFFER);
}
m_vertices.count = count;
m_vertices.stride = stride;
}
void GSDeviceOGL::IASetInputLayout()
{
// TODO
}
void GSDeviceOGL::IASetPrimitiveTopology(int topology)
{
m_topology = topology;
}

View File

@ -33,9 +33,23 @@ class GSDeviceOGL : public GSDevice
#endif #endif
GLuint m_vbo;
GLuint m_fbo;
struct
{
size_t stride, start, count, limit;
} m_vertices;
int m_topology;
//
static void OnStaticCgError(CGcontext ctx, CGerror err, void* p) {((GSDeviceOGL*)p)->OnCgError(ctx, err);} static void OnStaticCgError(CGcontext ctx, CGerror err, void* p) {((GSDeviceOGL*)p)->OnCgError(ctx, err);}
void OnCgError(CGcontext ctx, CGerror err); void OnCgError(CGcontext ctx, CGerror err);
//
GSTexture* Create(int type, int w, int h, int format); GSTexture* Create(int type, int w, int h, int format);
void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c); void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c);
@ -67,4 +81,8 @@ public:
GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0); GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0);
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true); void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true);
void IASetVertexBuffer(const void* vertices, size_t stride, size_t count);
void IASetInputLayout(); // TODO
void IASetPrimitiveTopology(int topology);
}; };

View File

@ -336,16 +336,15 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
GSTextureFX10::PSConstantBuffer ps_cb; GSTextureFX10::PSConstantBuffer ps_cb;
ps_cb.FogColorAREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, (int)context->TEST.AREF) / 255; ps_cb.FogColor_AREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, (int)context->TEST.AREF) / 255;
ps_cb.TA = GSVector4((int)env.TEXA.TA0, (int)env.TEXA.TA1) / 255;
if(context->TEST.ATST == 2 || context->TEST.ATST == 5) if(context->TEST.ATST == 2 || context->TEST.ATST == 5)
{ {
ps_cb.FogColorAREF.a -= 0.9f / 255; ps_cb.FogColor_AREF.a -= 0.9f / 255;
} }
else if(context->TEST.ATST == 3 || context->TEST.ATST == 6) else if(context->TEST.ATST == 3 || context->TEST.ATST == 6)
{ {
ps_cb.FogColorAREF.a += 0.9f / 255; ps_cb.FogColor_AREF.a += 0.9f / 255;
} }
if(tex) if(tex)
@ -355,28 +354,27 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
int w = tex->m_texture->GetWidth(); int w = tex->m_texture->GetWidth();
int h = tex->m_texture->GetHeight(); int h = tex->m_texture->GetHeight();
ps_cb.WH_TA = GSVector4((int)(1 << context->TEX0.TW), (int)(1 << context->TEX0.TH), env.TEXA.TA0, env.TEXA.TA1) / GSVector4(1, 255).xxyy();
ps_cb.HalfTexel = GSVector4(-0.5f, 0.5f).xxyy() / GSVector4(w, h).xyxy();
switch(context->CLAMP.WMS) switch(context->CLAMP.WMS)
{ {
case 0: case 0:
ps_cb.MinMax.x = w - 1;
ps_cb.MinMax.z = 0;
ps_ssel.tau = 1; ps_ssel.tau = 1;
break; break;
case 1: case 1:
ps_cb.MinMax.x = 0;
ps_cb.MinMax.z = w - 1;
ps_ssel.tau = 0; ps_ssel.tau = 0;
break; break;
case 2: case 2:
ps_cb.MinMax.x = (int)context->CLAMP.MINU * w / (1 << context->TEX0.TW); ps_cb.MinMax.x = ((float)(int)context->CLAMP.MINU) / (1 << context->TEX0.TW);
ps_cb.MinMax.z = (int)context->CLAMP.MAXU * w / (1 << context->TEX0.TW); ps_cb.MinMax.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW);
ps_cb.MinMaxF.x = ((float)(int)context->CLAMP.MINU + 0.5f) / (1 << context->TEX0.TW); ps_cb.MinMaxF.x = ((float)(int)context->CLAMP.MINU + 0.5f) / (1 << context->TEX0.TW);
ps_cb.MinMaxF.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW); ps_cb.MinMaxF.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW);
ps_ssel.tau = 0; ps_ssel.tau = 0;
break; break;
case 3: case 3:
ps_cb.MinMax.x = context->CLAMP.MINU; ps_cb.MskFix.x = context->CLAMP.MINU;
ps_cb.MinMax.z = context->CLAMP.MAXU; ps_cb.MskFix.z = context->CLAMP.MAXU;
ps_ssel.tau = 1; ps_ssel.tau = 1;
break; break;
default: default:
@ -386,25 +384,21 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
switch(context->CLAMP.WMT) switch(context->CLAMP.WMT)
{ {
case 0: case 0:
ps_cb.MinMax.y = h - 1;
ps_cb.MinMax.w = 0;
ps_ssel.tav = 1; ps_ssel.tav = 1;
break; break;
case 1: case 1:
ps_cb.MinMax.y = 0;
ps_cb.MinMax.w = h - 1;
ps_ssel.tav = 0; ps_ssel.tav = 0;
break; break;
case 2: case 2:
ps_cb.MinMax.y = (int)context->CLAMP.MINV * h / (1 << context->TEX0.TH); ps_cb.MinMax.y = ((float)(int)context->CLAMP.MINV) / (1 << context->TEX0.TH);
ps_cb.MinMax.w = (int)context->CLAMP.MAXV * h / (1 << context->TEX0.TH); ps_cb.MinMax.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH);
ps_cb.MinMaxF.y = ((float)(int)context->CLAMP.MINV + 0.5f) / (1 << context->TEX0.TH); ps_cb.MinMaxF.y = ((float)(int)context->CLAMP.MINV + 0.5f) / (1 << context->TEX0.TH);
ps_cb.MinMaxF.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH); ps_cb.MinMaxF.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH);
ps_ssel.tav = 0; ps_ssel.tav = 0;
break; break;
case 3: case 3:
ps_cb.MinMax.y = context->CLAMP.MINV; ps_cb.MskFix.y = context->CLAMP.MINV;
ps_cb.MinMax.w = context->CLAMP.MAXV; ps_cb.MskFix.w = context->CLAMP.MAXV;
ps_ssel.tav = 1; ps_ssel.tav = 1;
break; break;
default: default:

View File

@ -308,17 +308,15 @@ void GSRendererHW9::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache:
GSTextureFX9::PSConstantBuffer ps_cb; GSTextureFX9::PSConstantBuffer ps_cb;
ps_cb.FogColorAREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, (int)context->TEST.AREF) / 255; ps_cb.FogColor_AREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, (int)context->TEST.AREF) / 255;
ps_cb.TA0 = (float)(int)env.TEXA.TA0 / 255;
ps_cb.TA1 = (float)(int)env.TEXA.TA1 / 255;
if(context->TEST.ATST == 2 || context->TEST.ATST == 5) if(context->TEST.ATST == 2 || context->TEST.ATST == 5)
{ {
ps_cb.FogColorAREF.a -= 0.9f / 255; ps_cb.FogColor_AREF.a -= 0.9f / 255;
} }
else if(context->TEST.ATST == 3 || context->TEST.ATST == 6) else if(context->TEST.ATST == 3 || context->TEST.ATST == 6)
{ {
ps_cb.FogColorAREF.a += 0.9f / 255; ps_cb.FogColor_AREF.a += 0.9f / 255;
} }
if(tex) if(tex)
@ -328,8 +326,8 @@ void GSRendererHW9::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache:
int w = tex->m_texture->GetWidth(); int w = tex->m_texture->GetWidth();
int h = tex->m_texture->GetHeight(); int h = tex->m_texture->GetHeight();
ps_cb.WH = GSVector2(w, h); ps_cb.WH_TA = GSVector4(w, h, env.TEXA.TA0, env.TEXA.TA1) / GSVector4(1, 255).xxyy();
ps_cb.HalfTexel = GSVector4(-0.5f / w, -0.5f / h, +0.5f / w, +0.5f / h); ps_cb.HalfTexel = GSVector4(-0.5f, 0.5f).xxyy() / GSVector4(w, h).xyxy();
switch(context->CLAMP.WMS) switch(context->CLAMP.WMS)
{ {

View File

@ -33,9 +33,11 @@ GSSetting GSSettingsDlg::g_renderers[] =
{3, "Direct3D10 (Hardware)", NULL}, {3, "Direct3D10 (Hardware)", NULL},
{4, "Direct3D10 (Software)", NULL}, {4, "Direct3D10 (Software)", NULL},
{5, "Direct3D10 (Null)", NULL}, {5, "Direct3D10 (Null)", NULL},
#if 0
{6, "OpenGL (Hardware)", NULL}, {6, "OpenGL (Hardware)", NULL},
{7, "OpenGL (Software)", NULL}, {7, "OpenGL (Software)", NULL},
{8, "OpenGL (Null)", NULL}, {8, "OpenGL (Null)", NULL},
#endif
{9, "Null (Software)", NULL}, {9, "Null (Software)", NULL},
{10, "Null (Null)", NULL}, {10, "Null (Null)", NULL},
}; };

View File

@ -77,10 +77,12 @@ public:
__declspec(align(16)) struct PSConstantBuffer __declspec(align(16)) struct PSConstantBuffer
{ {
GSVector4 FogColorAREF; GSVector4 FogColor_AREF;
GSVector4 TA; GSVector4 HalfTexel;
GSVector4i MinMax; GSVector4 WH_TA;
GSVector4 MinMax;
GSVector4 MinMaxF; GSVector4 MinMaxF;
GSVector4i MskFix;
struct PSConstantBuffer() {memset(this, 0, sizeof(*this));} struct PSConstantBuffer() {memset(this, 0, sizeof(*this));}
@ -93,13 +95,17 @@ public:
GSVector4i b1 = b[1]; GSVector4i b1 = b[1];
GSVector4i b2 = b[2]; GSVector4i b2 = b[2];
GSVector4i b3 = b[3]; GSVector4i b3 = b[3];
GSVector4i b4 = b[4];
GSVector4i b5 = b[5];
if(!((a[0] == b0) & (a[1] == b1) & (a[2] == b2) & (a[3] == b3)).alltrue()) if(!((a[0] == b0) & (a[1] == b1) & (a[2] == b2) & (a[3] == b3) & (a[4] == b4) & (a[5] == b5)).alltrue())
{ {
a[0] = b0; a[0] = b0;
a[1] = b1; a[1] = b1;
a[2] = b2; a[2] = b2;
a[3] = b3; a[3] = b3;
a[4] = b4;
a[5] = b5;
return true; return true;
} }

View File

@ -53,11 +53,9 @@ public:
struct PSConstantBuffer struct PSConstantBuffer
{ {
GSVector4 FogColorAREF; GSVector4 FogColor_AREF;
GSVector4 HalfTexel; GSVector4 HalfTexel;
GSVector2 WH; GSVector4 WH_TA;
float TA0;
float TA1;
GSVector4 MinMax; GSVector4 MinMax;
GSVector4 MinMaxF; GSVector4 MinMaxF;
GSVector4i MskFix; GSVector4i MskFix;

View File

@ -22,19 +22,29 @@
#include "stdafx.h" #include "stdafx.h"
#include "GSTextureOGL.h" #include "GSTextureOGL.h"
GSTextureOGL::GSTextureOGL(GLuint texture) GSTextureOGL::GSTextureOGL(GLuint texture, int type, int width, int height, int format)
: m_texture(texture) : m_texture(texture)
, m_type(None) , m_type(type)
, m_width(0) , m_width(width)
, m_height(0) , m_height(height)
, m_format(0) , m_format(format)
{ {
// TODO: m_type, m_format, fb/ds? }
glBindTexture(GL_TEXTURE_2D, texture); GSTextureOGL::~GSTextureOGL()
{
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &m_width); if(m_texture)
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &m_height); {
switch(m_type)
{
case DepthStencil:
glDeleteRenderbuffersEXT(1, &m_texture);
break;
default:
glDeleteTextures(1, &m_texture);
break;
}
}
} }
int GSTextureOGL::GetType() const int GSTextureOGL::GetType() const
@ -59,7 +69,7 @@ int GSTextureOGL::GetFormat() const
bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch) bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
{ {
// TODO // TODO: glTexSubImage2D looks like UpdateSubresource but does not take a pitch
return false; return false;
} }

View File

@ -33,7 +33,8 @@ class GSTextureOGL : public GSTexture
int m_format; int m_format;
public: public:
explicit GSTextureOGL(GLuint texture); GSTextureOGL(GLuint texture, int type, int width, int height, int format = 0);
virtual ~GSTextureOGL();
int GetType() const; int GetType() const;
int GetWidth() const; int GetWidth() const;

View File

@ -155,9 +155,12 @@ cbuffer cb1
{ {
float3 FogColor; float3 FogColor;
float AREF; float AREF;
float4 TA; float4 HalfTexel;
uint4 MinMax; float2 WH;
float2 TA;
float4 MinMax;
float4 MinMaxF; float4 MinMaxF;
uint4 MskFix;
}; };
struct PS_INPUT struct PS_INPUT
@ -175,15 +178,15 @@ struct PS_OUTPUT
#ifndef FST #ifndef FST
#define FST 0 #define FST 0
#define WMS 1 #define WMS 3
#define WMT 1 #define WMT 3
#define BPP 0 #define BPP 0
#define AEM 0 #define AEM 0
#define TFX 0 #define TFX 0
#define TCC 1 #define TCC 1
#define ATE 1 #define ATE 0
#define ATST 4 #define ATST 4
#define FOG 1 #define FOG 0
#define CLR1 0 #define CLR1 0
#define FBA 0 #define FBA 0
#define AOUT 0 #define AOUT 0
@ -207,58 +210,83 @@ float4 Extract16(uint i)
return f; return f;
} }
int4 wrapuv(int4 uv) float4 wrapuv(float4 uv)
{ {
// TODO: bitwise ops don't work with render target textures that were not rendered at the native resolution.
if(WMS == WMT) if(WMS == WMT)
{ {
switch(WMS) if(WMS == 0)
{ {
case 0: uv &= MinMax.xyxy; break; uv = frac(uv);
case 1: uv = clamp(uv, 0, MinMax.zwzw); break; }
case 2: uv = clamp(uv, MinMax.xyxy, MinMax.zwzw); break; else if(WMS == 1)
case 3: uv = (uv & MinMax.xyxy) | MinMax.zwzw; break; {
uv = saturate(uv);
}
else if(WMS == 2)
{
uv = clamp(uv, MinMax.xyxy, MinMax.zwzw);
}
else if(WMS == 3)
{
uv = (float4)(((int4)(uv * WH.xyxy) & MskFix.xyxy) | MskFix.zwzw) / WH.xyxy;
} }
} }
else else
{ {
switch(WMS) if(WMS == 0)
{ {
case 0: uv.xz &= MinMax.xx; break; uv.xz = frac(uv.xz);
case 1: uv.xz = clamp(uv.xz, 0, MinMax.zz); break;
case 2: uv.xz = clamp(uv.xz, MinMax.xx, MinMax.zz); break;
case 3: uv.xz = (uv.xz & MinMax.xx) | MinMax.zz; break;
} }
else if(WMS == 1)
switch(WMT)
{ {
case 0: uv.yw &= MinMax.yy; break; uv.xz = saturate(uv.xz);
case 1: uv.yw = clamp(uv.yw, 0, MinMax.ww); break; }
case 2: uv.yw = clamp(uv.yw, MinMax.yy, MinMax.ww); break; else if(WMS == 2)
case 3: uv.yw = (uv.yw & MinMax.yy) | MinMax.ww; break; {
uv.xz = clamp(uv.xz, MinMax.xx, MinMax.zz);
}
else if(WMS == 3)
{
uv.xz = (float2)(((int2)(uv * WH.xyxy).xz & MskFix.xx) | MskFix.zz) / WH;
}
if(WMT == 0)
{
uv.yw = frac(uv.yw);
}
else if(WMT == 1)
{
uv.yw = saturate(uv.yw);
}
else if(WMT == 2)
{
uv.yw = clamp(uv.yw, MinMax.yy, MinMax.ww);
}
else if(WMT == 3)
{
uv.yw = (float2)(((int2)(uv * WH.xyxy).yw & MskFix.yy) | MskFix.ww) / WH;
} }
} }
return uv; return uv;
} }
float2 clampuv(float2 tc) float2 clampuv(float2 uv)
{ {
if(WMS == 2 && WMT == 2) if(WMS == 2 && WMT == 2)
{ {
tc = clamp(tc, MinMaxF.xy, MinMaxF.zw); uv = clamp(uv, MinMaxF.xy, MinMaxF.zw);
} }
else if(WMS == 2) else if(WMS == 2)
{ {
tc.x = clamp(tc.x, MinMaxF.x, MinMaxF.z); uv.x = clamp(uv.x, MinMaxF.x, MinMaxF.z);
} }
else if(WMT == 2) else if(WMT == 2)
{ {
tc.y = clamp(tc.y, MinMaxF.y, MinMaxF.w); uv.y = clamp(uv.y, MinMaxF.y, MinMaxF.w);
} }
return tc; return uv;
} }
float4 sample(float2 tc, float w) float4 sample(float2 tc, float w)
@ -282,12 +310,11 @@ float4 sample(float2 tc, float w)
else else
{ {
float w, h; float w, h;
Texture.GetDimensions(w, h); Texture.GetDimensions(w, h);
float4 tc2 = (tc * float2(w, h)).xyxy + float4(-0.499, -0.499, 0.501, 0.501); float4 uv2 = tc.xyxy + HalfTexel;
float2 dd = frac(tc2.xy); float2 dd = frac(uv2.xy * float2(w, h));
int4 uv = wrapuv((int4)tc2); float4 uv = wrapuv(uv2);
float4 t00, t01, t10, t11; float4 t00, t01, t10, t11;
@ -295,15 +322,15 @@ float4 sample(float2 tc, float w)
{ {
float4 a; float4 a;
a.x = Texture.Load(int3(uv.xy, 0)).a; a.x = Texture.Sample(TextureSampler, uv.xy).a;
a.y = Texture.Load(int3(uv.zy, 0)).a; a.y = Texture.Sample(TextureSampler, uv.zy).a;
a.z = Texture.Load(int3(uv.xw, 0)).a; a.z = Texture.Sample(TextureSampler, uv.xw).a;
a.w = Texture.Load(int3(uv.zw, 0)).a; a.w = Texture.Sample(TextureSampler, uv.zw).a;
t00 = Palette.Load(a.x); t00 = Palette.Sample(PaletteSampler, a.x);
t01 = Palette.Load(a.y); t01 = Palette.Sample(PaletteSampler, a.y);
t10 = Palette.Load(a.z); t10 = Palette.Sample(PaletteSampler, a.z);
t11 = Palette.Load(a.w); t11 = Palette.Sample(PaletteSampler, a.w);
} }
else if(BPP == 4) // 8HP + 16-bit palette else if(BPP == 4) // 8HP + 16-bit palette
{ {
@ -313,10 +340,10 @@ float4 sample(float2 tc, float w)
{ {
float4 r; float4 r;
r.x = Texture.Load(int3(uv.xy, 0)).r; r.x = Texture.Sample(TextureSampler, uv.xy).r;
r.y = Texture.Load(int3(uv.zy, 0)).r; r.y = Texture.Sample(TextureSampler, uv.zy).r;
r.z = Texture.Load(int3(uv.xw, 0)).r; r.z = Texture.Sample(TextureSampler, uv.xw).r;
r.w = Texture.Load(int3(uv.zw, 0)).r; r.w = Texture.Sample(TextureSampler, uv.zw).r;
uint4 i = r * 65535; uint4 i = r * 65535;
@ -327,10 +354,10 @@ float4 sample(float2 tc, float w)
} }
else else
{ {
t00 = Texture.Load(int3(uv.xy, 0)); t00 = Texture.Sample(TextureSampler, uv.xy);
t01 = Texture.Load(int3(uv.zy, 0)); t01 = Texture.Sample(TextureSampler, uv.zy);
t10 = Texture.Load(int3(uv.xw, 0)); t10 = Texture.Sample(TextureSampler, uv.xw);
t11 = Texture.Load(int3(uv.zw, 0)); t11 = Texture.Sample(TextureSampler, uv.zw);
} }
if(LTF) if(LTF)

View File

@ -96,12 +96,12 @@ struct PS_INPUT
#define AEM 0 #define AEM 0
#define TFX 0 #define TFX 0
#define TCC 1 #define TCC 1
#define ATE 1 #define ATE 0
#define ATST 4 #define ATST 4
#define FOG 1 #define FOG 0
#define CLR1 0 #define CLR1 0
#define RT 0 #define RT 0
#define LTF 1 #define LTF 0
#endif #endif
sampler Texture : register(s0); sampler Texture : register(s0);
@ -113,63 +113,84 @@ float4 wrapuv(float4 uv)
{ {
if(WMS == WMT) if(WMS == WMT)
{ {
switch(WMS) if(WMS == 0)
{
uv = frac(uv);
}
else if(WMS == 1)
{
uv = saturate(uv);
}
else if(WMS == 2)
{
uv = clamp(uv, MinMax.xyxy, MinMax.zwzw);
}
else if(WMS == 3)
{ {
case 0: uv = frac(uv); break;
case 1: uv = saturate(uv); break;
case 2: uv = clamp(uv, MinMax.xyxy, MinMax.zwzw); break;
case 3:
uv.x = tex1D(UMSKFIX, uv.x); uv.x = tex1D(UMSKFIX, uv.x);
uv.y = tex1D(VMSKFIX, uv.y); uv.y = tex1D(VMSKFIX, uv.y);
uv.z = tex1D(UMSKFIX, uv.z); uv.z = tex1D(UMSKFIX, uv.z);
uv.w = tex1D(VMSKFIX, uv.w); uv.w = tex1D(VMSKFIX, uv.w);
break;
} }
} }
else else
{ {
switch(WMS) if(WMS == 0)
{
uv.xz = frac(uv.xz);
}
else if(WMS == 1)
{
uv.xz = saturate(uv.xz);
}
else if(WMS == 2)
{
uv.xz = clamp(uv.xz, MinMax.xx, MinMax.zz);
}
else if(WMS == 3)
{ {
case 0: uv.xz = frac(uv.xz); break;
case 1: uv.xz = saturate(uv.xz); break;
case 2: uv.xz = clamp(uv.xz, MinMax.xx, MinMax.zz); break;
case 3:
uv.x = tex1D(UMSKFIX, uv.x); uv.x = tex1D(UMSKFIX, uv.x);
uv.z = tex1D(UMSKFIX, uv.z); uv.z = tex1D(UMSKFIX, uv.z);
break;
} }
switch(WMT) if(WMT == 0)
{
uv.yw = frac(uv.yw);
}
else if(WMT == 1)
{
uv.yw = saturate(uv.yw);
}
else if(WMT == 2)
{
uv.yw = clamp(uv.yw, MinMax.yy, MinMax.ww);
}
else if(WMT == 3)
{ {
case 0: uv.yw = frac(uv.yw); break;
case 1: uv.yw = saturate(uv.yw); break;
case 2: uv.yw = clamp(uv.yw, MinMax.yy, MinMax.ww); break;
case 3:
uv.y = tex1D(VMSKFIX, uv.y); uv.y = tex1D(VMSKFIX, uv.y);
uv.w = tex1D(VMSKFIX, uv.w); uv.w = tex1D(VMSKFIX, uv.w);
break;
} }
} }
return uv; return uv;
} }
float2 clampuv(float2 tc) float2 clampuv(float2 uv)
{ {
if(WMS == 2 && WMT == 2) if(WMS == 2 && WMT == 2)
{ {
tc = clamp(tc, MinMaxF.xy, MinMaxF.zw); uv = clamp(uv, MinMaxF.xy, MinMaxF.zw);
} }
else if(WMS == 2) else if(WMS == 2)
{ {
tc.x = clamp(tc.x, MinMaxF.x, MinMaxF.z); uv.x = clamp(uv.x, MinMaxF.x, MinMaxF.z);
} }
else if(WMT == 2) else if(WMT == 2)
{ {
tc.y = clamp(tc.y, MinMaxF.y, MinMaxF.w); uv.y = clamp(uv.y, MinMaxF.y, MinMaxF.w);
} }
return tc; return uv;
} }
float4 sample(float2 tc, float w) float4 sample(float2 tc, float w)
@ -192,9 +213,9 @@ float4 sample(float2 tc, float w)
} }
else else
{ {
float4 tc2 = tc.xyxy + HalfTexel; float4 uv2 = tc.xyxy + HalfTexel;
float2 dd = frac(tc2.xy * WH); float2 dd = frac(uv2.xy * WH);
float4 uv = wrapuv(tc2); float4 uv = wrapuv(uv2);
float4 t00, t01, t10, t11; float4 t00, t01, t10, t11;

View File

@ -115,10 +115,15 @@ typedef signed long long int64;
// opengl // opengl
#include <GL/glew.h>
#include <GL/glut.h> #include <GL/glut.h>
#include <CG/cg.h> #include <CG/cg.h>
#include <CG/cgGL.h> #include <CG/cgGL.h>
#ifdef _WINDOWS
#include <GL/wglew.h>
#endif
// sse // sse
#if !defined(_M_SSE) && (defined(_M_AMD64) || defined(_M_IX86_FP) && _M_IX86_FP >= 2) #if !defined(_M_SSE) && (defined(_M_AMD64) || defined(_M_IX86_FP) && _M_IX86_FP >= 2)