pcsx2/plugins/GSdx/GSVertexSW.cpp

169 lines
3.4 KiB
C++

/*
* Copyright (C) 2007-2009 Gabest
* http://www.gabest.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "stdafx.h"
#include "GSVertexSW.h"
using namespace Xbyak;
GSVertexTrace::GSVertexTraceCodeGenerator::GSVertexTraceCodeGenerator(DWORD key, void* ptr, size_t maxsize)
: CodeGenerator(maxsize, ptr)
{
#if _M_AMD64
#error TODO
#endif
const int params = 0;
DWORD primclass = (key >> 0) & 3;
DWORD iip = (key >> 2) & 1;
DWORD tme = (key >> 3) & 1;
DWORD tfx = (key >> 4) & 3;
DWORD color = !(tme && tfx == TFX_DECAL);
int n = 1;
switch(primclass)
{
case GS_POINT_CLASS:
n = 1;
break;
case GS_LINE_CLASS:
case GS_SPRITE_CLASS:
n = 2;
break;
case GS_TRIANGLE_CLASS:
n = 3;
break;
}
const int _v = params + 4;
const int _count = params + 8;
const int _min = params + 12;
const int _max = params + 16;
//
static const float fmin = -FLT_MAX;
static const float fmax = FLT_MAX;
movss(xmm0, xmmword[&fmax]);
shufps(xmm0, xmm0, _MM_SHUFFLE(0, 0, 0, 0));
movss(xmm1, xmmword[&fmin]);
shufps(xmm1, xmm1, _MM_SHUFFLE(0, 0, 0, 0));
if(color)
{
// min.c = FLT_MAX;
// max.c = -FLT_MAX;
movaps(xmm2, xmm0);
movaps(xmm3, xmm1);
}
// min.p = FLT_MAX;
// max.p = -FLT_MAX;
movaps(xmm4, xmm0);
movaps(xmm5, xmm1);
if(tme)
{
// min.t = FLT_MAX;
// max.t = -FLT_MAX;
movaps(xmm6, xmm0);
movaps(xmm7, xmm1);
}
// for(int i = 0; i < count; i += step) {
mov(edx, dword[esp + _v]);
mov(ecx, dword[esp + _count]);
align(16);
L("loop");
for(int j = 0; j < n; j++)
{
if(color && (iip || j == n - 1))
{
// min.c = min.c.minv(v[i + j].c);
// max.c = max.c.maxv(v[i + j].c);
movaps(xmm0, xmmword[edx + j * sizeof(GSVertexSW)]);
minps(xmm2, xmm0);
maxps(xmm3, xmm0);
}
// min.p = min.p.minv(v[i + j].p);
// max.p = max.p.maxv(v[i + j].p);
movaps(xmm0, xmmword[edx + j * sizeof(GSVertexSW) + 16]);
minps(xmm4, xmm0);
maxps(xmm5, xmm0);
if(tme)
{
// min.t = min.t.minv(v[i + j].t);
// max.t = max.t.maxv(v[i + j].t);
movaps(xmm0, xmmword[edx + j * sizeof(GSVertexSW) + 32]);
minps(xmm6, xmm0);
maxps(xmm7, xmm0);
}
}
add(edx, n * sizeof(GSVertexSW));
sub(ecx, n);
jg("loop");
// }
mov(eax, dword[esp + _min]);
mov(edx, dword[esp + _max]);
if(color)
{
movaps(xmmword[eax], xmm2);
movaps(xmmword[edx], xmm3);
}
movaps(xmmword[eax + 16], xmm4);
movaps(xmmword[edx + 16], xmm5);
if(tme)
{
movaps(xmmword[eax + 32], xmm6);
movaps(xmmword[edx + 32], xmm7);
}
ret();
}