pcsx2/plugins/gs/GSsoft/Src/Cache.c

207 lines
4.4 KiB
C

/* GSsoft
* Copyright (C) 2002-2005 GSsoft Team
*
* 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 of the License, 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
#include <string.h>
#include "Draw.h"
#include "Mem.h"
#include "Page.h"
#include "Texts.h"
#ifdef __MSCW32__
#pragma warning(disable:4244)
#endif
typedef struct {
u32 *_data;
u32 *data;
tex0Info tex0;
} Cache;
Cache *Texts;
Cache *Texture;
int TextureCount;
int CacheInit() {
Texts = (Cache*)malloc(conf.cachesize * sizeof(Cache));
memset(Texts, 0, conf.cachesize * sizeof(Cache));
TextureCount = 0;
return 0;
}
void _CacheLoadTexture32(Cache *tex) {
s32 otick;
s32 tick;
u32 *mem;
u32 *ptr;
int u, v;
#ifdef __GNUC__
__asm__ __volatile__ (
"rdtsc\n"
: "=a"(otick) :
);
#else
__asm {
rdtsc
mov otick, eax
}
#endif
ptr = tex->data;
for (v=0; v<tex->tex0.th; v++) {
for (u=0; u<tex->tex0.tw; u+=8) {
mem = &vRamUL[getPixelAddress32(u, v, tex->tex0.tbp0, tex->tex0.tbw)];
/*
* This gives the following error:
Cache.c:73: error: memory input 2 is not directly addressable
#ifdef __GNUC__
__asm__ __volatile__ (
"movsd %1, %%xmm0\n"
"movhps %2, %%xmm0\n"
"movaps %%xmm0, %0\n"
: "=m"(&ptr[0]) : "m"(mem), "m"(mem+4)
);
#else
*/
ptr[0] = mem[0]; ptr[1] = mem[1];
ptr[2] = mem[4]; ptr[3] = mem[5];
ptr[4] = mem[8]; ptr[5] = mem[9];
ptr[6] = mem[12]; ptr[7] = mem[13];
/* #endif */
ptr+= 8;
}
for (; u<tex->tex0.tw; u++) {
*ptr++ = readPixel32(u, v, tex->tex0.tbp0, tex->tex0.tbw);
}
}
#ifdef __GNUC__
__asm__ __volatile__ (
"rdtsc\n"
: "=a"(tick) :
);
#else
__asm {
rdtsc
mov tick, eax
}
#endif
printf("%d\n", tick - otick);
}
void _CacheLoadTexture(Cache *tex) {
u32 *ptr;
int u, v;
ptr = tex->data;
for (v=0; v<tex->tex0.th; v++) {
for (u=0; u<tex->tex0.tw; u++) {
*ptr++ = GetTexturePixel32(u, v);
}
}
}
void CacheLoadTexture(int i) {
Texts[i].tex0 = *tex0;
Texts[i]._data = malloc(Texts[i].tex0.th*Texts[i].tex0.tw*4+16);
Texts[i].data = _align16(Texts[i]._data);
/* if (Texts[i].tex0.psm == 0) {
_CacheLoadTexture32(&Texts[i]);
return;
}*/
_CacheLoadTexture(&Texts[i]);
}
void CacheFreeTexture(int i) {
free(Texts[i]._data); Texts[i]._data = NULL;
}
int CacheSetTexture() {
int i;
#ifdef GS_LOG
GS_LOG("CacheSetTexture\n");
#endif
if (tex0->tbp0 == gs._gsfb[0].fbp ||
tex0->tbp0 == gs._gsfb[1].fbp) {
return -1;
}
for (i=0; i<conf.cachesize; i++) {
if (Texts[i]._data == NULL) continue;
if (memcmp(&Texts[i].tex0, tex0, sizeof(tex0Info)) == 0) {
#ifdef GS_LOG
GS_LOG("CacheSetTexture found %d\n", i);
#endif
Texture = &Texts[i];
return 0;
}
}
if (i == conf.cachesize) {
i = TextureCount++;
if (TextureCount >= conf.cachesize) TextureCount = 0;
CacheFreeTexture(i);
}
#ifdef GS_LOG
GS_LOG("CacheSetTexture: %dx%d: %d\n", tex0->tw, tex0->th, i);
#endif
printf("CacheSetTexture: %x, %dx%d: %d\n", tex0->tbp0, tex0->tw, tex0->th, i);
CacheLoadTexture(i);
Texture = &Texts[i];
return 0;
}
u32 CacheGetTexturePixel32(int u, int v) {
wrapUV(&u, &v);
if (u < 0 || u >= Texture->tex0.tw) return 0;
if (v < 0 || v >= Texture->tex0.th) return 0;
#ifdef GS_LOG
// GS_LOG("CacheGetTexturePixel32 %dx%d\n", u, v);
#endif
return Texture->data[v*Texture->tex0.tw+u];
}
void CacheClear(u32 bp, int size) {
int i;
for (i=0; i<conf.cachesize; i++) {
if (Texts[i].data == NULL) break;
if (Texts[i].tex0.tbp0 == bp) {
CacheFreeTexture(i);
}
}
}
void CacheShutdown() {
int i;
for (i=0; i<conf.cachesize; i++) {
if (Texts[i].data) CacheFreeTexture(i);
}
free(Texts);
}