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 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;
#if 0
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 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 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
{
private:
ID3D10Buffer* m_vb;
size_t m_vb_stride;
ID3D10InputLayout* m_layout;

View File

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

View File

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

View File

@ -27,11 +27,21 @@
GSDeviceOGL::GSDeviceOGL()
: m_hDC(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()
{
if(m_vbo) glDeleteBuffers(1, &m_vbo);
if(m_fbo) glDeleteFramebuffers(1, &m_fbo);
#ifdef _WINDOWS
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(!SetPixelFormat(m_hDC, ChoosePixelFormat(m_hDC, &pfd), &pfd))
{
return false;
}
m_hGLRC = wglCreateContext(m_hDC);
if(!m_hGLRC) return false;
if(!wglMakeCurrent(m_hDC, m_hGLRC))
{
return false;
}
if(WGLEW_EXT_swap_control)
{
wglSwapIntervalEXT(vsync ? 1 : 0);
}
#endif
if(glewInit() != GLEW_OK)
{
return false;
}
// 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;
}
@ -102,12 +128,12 @@ bool GSDeviceOGL::Reset(int w, int h, bool fs)
if(!__super::Reset(w, h, fs))
return false;
m_backbuffer = new GSTextureOGL(0); // ???
m_backbuffer = new GSTextureOGL(0, GSTexture::RenderTarget, w, h);
glCullFace(GL_FRONT_AND_BACK);
glDisable(GL_LIGHTING);
glDisable(GL_ALPHA_TEST);
glDisable(GL_SCISSOR_TEST);
glEnable(GL_SCISSOR_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@ -116,76 +142,134 @@ bool GSDeviceOGL::Reset(int w, int h, bool fs)
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;
}
void GSDeviceOGL::Flip()
{
// TODO
#ifdef _WINDOWS
SwapBuffers(m_hDC);
#endif
}
void GSDeviceOGL::BeginScene()
{
// TODO
}
void GSDeviceOGL::DrawPrimitive()
{
// TODO
glDrawArrays(m_topology, m_vertices.count, m_vertices.start);
}
void GSDeviceOGL::EndScene()
{
// TODO
m_vertices.start += m_vertices.count;
m_vertices.count = 0;
}
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)
{
// TODO
ClearRenderTarget(t, GSVector4(c) * (1.0f / 255));
}
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)
{
// 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)
{
// 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)
{
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)
{
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)
{
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)
{
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)
@ -209,3 +293,50 @@ void GSDeviceOGL::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool lin
{
// 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
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);}
void OnCgError(CGcontext ctx, CGerror err);
//
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);
@ -67,4 +81,8 @@ public:
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 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;
ps_cb.FogColorAREF = 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;
ps_cb.FogColor_AREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, (int)context->TEST.AREF) / 255;
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)
{
ps_cb.FogColorAREF.a += 0.9f / 255;
ps_cb.FogColor_AREF.a += 0.9f / 255;
}
if(tex)
@ -355,28 +354,27 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
int w = tex->m_texture->GetWidth();
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)
{
case 0:
ps_cb.MinMax.x = w - 1;
ps_cb.MinMax.z = 0;
ps_ssel.tau = 1;
break;
case 1:
ps_cb.MinMax.x = 0;
ps_cb.MinMax.z = w - 1;
ps_ssel.tau = 0;
break;
case 2:
ps_cb.MinMax.x = (int)context->CLAMP.MINU * w / (1 << context->TEX0.TW);
ps_cb.MinMax.z = (int)context->CLAMP.MAXU * w / (1 << context->TEX0.TW);
ps_cb.MinMax.x = ((float)(int)context->CLAMP.MINU) / (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.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW);
ps_ssel.tau = 0;
break;
case 3:
ps_cb.MinMax.x = context->CLAMP.MINU;
ps_cb.MinMax.z = context->CLAMP.MAXU;
ps_cb.MskFix.x = context->CLAMP.MINU;
ps_cb.MskFix.z = context->CLAMP.MAXU;
ps_ssel.tau = 1;
break;
default:
@ -386,25 +384,21 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
switch(context->CLAMP.WMT)
{
case 0:
ps_cb.MinMax.y = h - 1;
ps_cb.MinMax.w = 0;
ps_ssel.tav = 1;
break;
case 1:
ps_cb.MinMax.y = 0;
ps_cb.MinMax.w = h - 1;
ps_ssel.tav = 0;
break;
case 2:
ps_cb.MinMax.y = (int)context->CLAMP.MINV * h / (1 << context->TEX0.TH);
ps_cb.MinMax.w = (int)context->CLAMP.MAXV * h / (1 << context->TEX0.TH);
ps_cb.MinMax.y = ((float)(int)context->CLAMP.MINV) / (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.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH);
ps_ssel.tav = 0;
break;
case 3:
ps_cb.MinMax.y = context->CLAMP.MINV;
ps_cb.MinMax.w = context->CLAMP.MAXV;
ps_cb.MskFix.y = context->CLAMP.MINV;
ps_cb.MskFix.w = context->CLAMP.MAXV;
ps_ssel.tav = 1;
break;
default:

View File

@ -308,17 +308,15 @@ void GSRendererHW9::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache:
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.TA0 = (float)(int)env.TEXA.TA0 / 255;
ps_cb.TA1 = (float)(int)env.TEXA.TA1 / 255;
ps_cb.FogColor_AREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, (int)context->TEST.AREF) / 255;
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)
{
ps_cb.FogColorAREF.a += 0.9f / 255;
ps_cb.FogColor_AREF.a += 0.9f / 255;
}
if(tex)
@ -328,8 +326,8 @@ void GSRendererHW9::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache:
int w = tex->m_texture->GetWidth();
int h = tex->m_texture->GetHeight();
ps_cb.WH = GSVector2(w, h);
ps_cb.HalfTexel = GSVector4(-0.5f / w, -0.5f / h, +0.5f / w, +0.5f / h);
ps_cb.WH_TA = GSVector4(w, h, 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)
{

View File

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

View File

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

View File

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

View File

@ -22,19 +22,29 @@
#include "stdafx.h"
#include "GSTextureOGL.h"
GSTextureOGL::GSTextureOGL(GLuint texture)
GSTextureOGL::GSTextureOGL(GLuint texture, int type, int width, int height, int format)
: m_texture(texture)
, m_type(None)
, m_width(0)
, m_height(0)
, m_format(0)
, m_type(type)
, m_width(width)
, m_height(height)
, m_format(format)
{
// TODO: m_type, m_format, fb/ds?
}
glBindTexture(GL_TEXTURE_2D, texture);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &m_width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &m_height);
GSTextureOGL::~GSTextureOGL()
{
if(m_texture)
{
switch(m_type)
{
case DepthStencil:
glDeleteRenderbuffersEXT(1, &m_texture);
break;
default:
glDeleteTextures(1, &m_texture);
break;
}
}
}
int GSTextureOGL::GetType() const
@ -59,7 +69,7 @@ int GSTextureOGL::GetFormat() const
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;
}

View File

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

View File

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

View File

@ -96,12 +96,12 @@ struct PS_INPUT
#define AEM 0
#define TFX 0
#define TCC 1
#define ATE 1
#define ATE 0
#define ATST 4
#define FOG 1
#define FOG 0
#define CLR1 0
#define RT 0
#define LTF 1
#define LTF 0
#endif
sampler Texture : register(s0);
@ -113,63 +113,84 @@ float4 wrapuv(float4 uv)
{
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.y = tex1D(VMSKFIX, uv.y);
uv.z = tex1D(UMSKFIX, uv.z);
uv.w = tex1D(VMSKFIX, uv.w);
break;
}
}
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.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.w = tex1D(VMSKFIX, uv.w);
break;
}
}
return uv;
}
float2 clampuv(float2 tc)
float2 clampuv(float2 uv)
{
if(WMS == 2 && WMT == 2)
{
tc = clamp(tc, MinMaxF.xy, MinMaxF.zw);
uv = clamp(uv, MinMaxF.xy, MinMaxF.zw);
}
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)
{
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)
@ -192,9 +213,9 @@ float4 sample(float2 tc, float w)
}
else
{
float4 tc2 = tc.xyxy + HalfTexel;
float2 dd = frac(tc2.xy * WH);
float4 uv = wrapuv(tc2);
float4 uv2 = tc.xyxy + HalfTexel;
float2 dd = frac(uv2.xy * WH);
float4 uv = wrapuv(uv2);
float4 t00, t01, t10, t11;

View File

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