mirror of https://github.com/PCSX2/pcsx2.git
207 lines
4.4 KiB
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);
|
|
}
|
|
|
|
|