Path: blob/master/libmupen64plus/mupen64plus-video-z64/src/rgl_tiles.cpp
2 views
/*1* z642*3* Copyright (C) 2007 ziggy4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation; either version 2 of the License, or8* (at your option) any later version.9*10* This program is distributed in the hope that it will be useful,11* but WITHOUT ANY WARRANTY; without even the implied warranty of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13* GNU General Public License for more details.14*15* You should have received a copy of the GNU General Public License along16* with this program; if not, write to the Free Software Foundation, Inc.,17* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.18*19**/2021#include "rdp.h"22#include "rgl.h"2324#include <SDL.h>2526rglTextureHead_t freeTextures;27rglTextureHead_t texturesByCrc[256];28rglTextureHead_t texturesByUsage;2930void rglTouchTMEM()31{32rglTexCacheCounter++;33if (!rglTexCacheCounter) {34// shouldn't happen too often but let's do things correctly for the hell of it ;)35rglResetTextureCache();36}37}3839inline int crc8(uint32_t crc)40{41uint8_t res;42res = crc^(crc>>8)^(crc>>16)^(crc>>24);43return res;44}4546void rglDeleteTexture(rglTexture_t * tex)47{48//LOG("deleting texture %x\n", tex);49glDeleteTextures(1, &tex->id);50if (tex->zid)51glDeleteTextures(1, &tex->zid);52rglAssert(glGetError() == GL_NO_ERROR);53tex->id = tex->zid = 0;54CIRCLEQ_REMOVE(&texturesByUsage, tex, byUsage);55CIRCLEQ_REMOVE(&texturesByCrc[crc8(tex->crc)], tex, byCrc);56CIRCLEQ_INSERT_TAIL(rglTexture_t, &freeTextures, tex, byUsage);57}5859rglTexture_t * rglNewTexture(uint32_t crc)60{61rglTexture_t * res;6263if (CIRCLEQ_EMPTY(&freeTextures))64rglDeleteTexture(CIRCLEQ_FIRST(&texturesByUsage));6566res = CIRCLEQ_FIRST(&freeTextures);67//LOG("new texture %x %x crc %x\n", res, crc, crc8(crc));68CIRCLEQ_REMOVE(&freeTextures, res, byUsage);69CIRCLEQ_INSERT_TAIL(rglTexture_t, &texturesByUsage, res, byUsage);70CIRCLEQ_INSERT_TAIL(rglTexture_t, &texturesByCrc[crc8(crc)], res, byCrc);7172res->wt = res->ws = res->filter = 0;7374return res;75}7677void rglInitTextureCache()78{79int i;80// initialize textures lists81CIRCLEQ_INIT(rglTexture_t, &freeTextures);82CIRCLEQ_INIT(rglTexture_t, &texturesByUsage);83for (i=0; i<256; i++)84CIRCLEQ_INIT(rglTexture_t, &texturesByCrc[i]);85for (i=0; i<RGL_TEX_CACHE_SIZE; i++) {86CIRCLEQ_INSERT_TAIL(rglTexture_t, &freeTextures, rglTextures+i, byUsage);87}88}8990void rglResetTextureCache()91{92static int init;93if (!init) {94rglInitTextureCache();95init = 1;96}9798memset(rglTexCache, 0, sizeof(rglTexCache));99rglTexCacheCounter = 1;100while (!CIRCLEQ_EMPTY(&texturesByUsage))101rglDeleteTexture(CIRCLEQ_FIRST(&texturesByUsage));102103rglInitTextureCache();104}105106void rglTile(rdpTile_t & tile, rglTile_t & rtile, int recth)107{108rglTexture_t * tex;109int ws, wt;110int line = tile.line;111//int cs, ct;112int clipw = ((tile.sh - tile.sl) >>2)+1;113int cliph = ((tile.th - tile.tl) >>2)+1;114int indirect = 1;115uint8_t * from = rdpTmem;116int ow, oh;117118// if (recth && cliph == recth+1) // hack for Mario Party (not necessary if we handle filter for texrect)119// cliph = recth;120121// if (tile.ms && tile.mask_s && (2<<tile.mask_s)<clipw)122// tile.ms = 0;123// if (tile.mt && tile.mask_t && (2<<tile.mask_t)<cliph)124// tile.mt = 0;125// if (tile.ms) clipw /= 2;126// if (tile.mt) cliph /= 2;127128if (!line) line = 1;129130//tile.format = ti_format;131132if (tile.size == 3) line <<= 1; // why why WHY ?133//if (tile.size == 0) clipw *= 2;134tile.w = line << 1 >> tile.size;135//if (tile.mask_s && (1<<tile.mask_s) < tile.w*2) // HACK136if (tile.mask_s && (1<<tile.mask_s) < tile.w)137tile.w = 1<<tile.mask_s;138if (tile.cs && ((clipw+3)&~3) < tile.w) // GL wants width divisible by 4 at least ?139tile.w = ((clipw+3)&~3);140141tile.h = ((tile.th - tile.tl) >>2)+1; // FIXME why not cliph ???142//tile.h = (tile.th >>2)+1;143// if (tile.h <= 0)144// tile.h = (tile.th >>2)+1;145// FIXME remove test on mt ?146if (tile.mask_t && ((1<<tile.mask_t) < tile.h || (!tile.ct && !tile.mt)))147tile.h = 1<<tile.mask_t;148else149{150// if (tile.h < 0 || (tile.h & 3)) {151// tile.h = 1; while (tile.h<(tile.th>>2)) tile.h <<= 1;152// }153}154155// if (!tile.mask_t && !tile.ct/* && !tile.mt*/)156// tile.h = (0x1000-tile.tmem)/line;157158// if (tile.sl && !tile.mask_s) {159// printf("shifting sl %d\n", tile.sl);160// tile.tmem += tile.sl << tile.format >> 1;161// tile.tmem &= 0xfff;162// tile.sl = 0;163// }164// if (tile.tl && !tile.mask_t) {165// printf("shifting tl %d\n", tile.tl);166// tile.tmem += tile.tl * line;167// tile.tmem &= 0xfff;168// tile.tl = 0;169// }170171if (recth && tile.h == 1)172// +1 for yoshi173tile.h = recth+1;174175if (/*tile.h == 1 || */tile.w*tile.h << tile.size >> 1 > 0x1000-tile.tmem) {176DUMP("fixing tile size from %dx%d to ", tile.w, tile.h);177//tile.w = (line << 3) >> tile.size + 2;178//tile.h = 1; while (tile.h<(tile.th>>2)) tile.h <<= 1;179tile.h = (0x1000-tile.tmem)/line;180DUMP("%dx%d\n", tile.w, tile.h);181}182183// this is a warkaround for a bug in pj64 rsp plugin184// now fixed185if (0&&recth && /*tile.line == 8 && */tile.h == 1) {186//LOG("direct\n");187tile.w = rdpTiWidth << rdpTiSize >> tile.size;188tile.h = recth;189from = gfx.RDRAM + rdpTiAddress;190if (recth > 1 || rdpTiWidth > 1)191line = rdpTiWidth << rdpTiSize >> 1;192indirect = 0;193}194195{196int fromLine, stop, fromFormat, fromSize;197uint32_t address = rdpGetTmemOrigin(tile.tmem, &fromLine, &stop, &fromFormat, &fromSize);198DUMP("tmem %x rdram %x\n", tile.tmem, address);199if (address != (uint32_t)~0) {200rglRenderBuffer_t * buffer;201if (!fromLine) fromLine = line;202if (!tile.mask_t)203tile.h = (stop-tile.tmem)/line;204rtile.hiresBuffer = 0;205//while (0) {206CIRCLEQ_FOREACH(rglRenderBuffer_t, buffer, &rBufferHead, link) {207//if (buffer->flags & RGL_RB_DEPTH) continue;208if (buffer->area.xh != 8192)209buffer->addressStop = buffer->addressStart + buffer->line * ((buffer->area.yl >>2)+1);210211// conservative212// if (address + tile.h * line > buffer->addressStart &&213// address < buffer->addressStop)214if (address >= buffer->addressStart/* + buffer->line * ((buffer->area.yh >>2)+1)*/ && // oops cannot use yh, might not be initialized215address + tile.h * line <= buffer->addressStop)216DUMP("check %x --> %x with %x --> %x (%x %x %d %x)\n",217address, address + tile.h * line,218buffer->addressStart, buffer->addressStop,219fromLine, buffer->line, tile.h, line);220221// TODO store real address stop, it's not necessarily the same as222// address + tile.h * line223// conservative224// if (address + tile.h * line > buffer->addressStart &&225// address < buffer->addressStop &&226// more strict (better for LEGO racer)227// general solution would be : find all candidates, pick the one that covers228// the biggest area229if ((!rtile.hiresBuffer || buffer->addressStart > rtile.hiresBuffer->addressStart) &&230address >= buffer->addressStart/* + buffer->line * ((buffer->area.yh >>2)+1)*/ && // oops cannot use yh, might not be initialized231address + tile.h * line <= buffer->addressStop &&232(tile.h <= 1 || fromLine == buffer->line)) {233DUMP("texture buffer at %x %d x %d %d %d fmt %d fromfmt %d\n",234buffer->addressStart, tile.w, tile.h,235fromLine, buffer->line, tile.format, fromFormat);236237rtile.hiresBuffer = buffer;238rtile.hiresAddress = address;239240break;241}242}243244if (rtile.hiresBuffer) {245// FIXME current buffer could be a depth buffer, in this case246// we want the texture rendered as depth too247rtile.hiresBuffer->flags &= ~RGL_RB_DEPTH;248//rglRenderChunks(rtile.hiresBuffer);249}250251if (rglSettings.hiresFb && rtile.hiresBuffer) {252memcpy(&rtile, &tile, sizeof(tile));253return;254}255256if (rtile.hiresBuffer) {257LOG("updating rdram %x\n", address);258rglFramebuffer2Rdram(*rtile.hiresBuffer, address, address + tile.h * line);259line = fromLine;260from = gfx.RDRAM + address;261indirect = 0;262}263264}265}266rtile.hiresBuffer = 0;267268if (tile.w > 1024) tile.w = 1024;269if (tile.h > 1024) tile.h = 1024;270271ow = tile.w; oh = tile.h; // save w/h before making it a power of 2272{273int w=1, h=1;274while (w < tile.w) w*=2;275while (h < tile.h) h*=2;276tile.w = rtile.w = w;277tile.h = rtile.h = h;278}279280memcpy(&rtile, &tile, sizeof(tile));281rtile.line = line;282283// NOTE more general solutions would involve subdividing the geometry284// or writing clamping/mirroring in glsl285int badmirror_s =286tile.mask_s && tile.cs && tile.ms && (clipw/2) < (1<<tile.mask_s);287int badmirror_t =288tile.mask_t && tile.ct && tile.mt && (cliph/2) < (1<<tile.mask_t);289int clipmw = clipw, clipmh = cliph;290if (tile.ms && !badmirror_s) clipmw /= 2;291if (tile.mt && !badmirror_t) clipmh /= 2;292int badclamp_s =293tile.mask_s && tile.cs && clipmw > (1<<tile.mask_s);294int badclamp_t =295tile.mask_t && tile.ct && clipmh > (1<<tile.mask_t);296297int npot_s = (tile.w-1)&tile.w;298int npot_t = (tile.h-1)&tile.h;299300ws = GL_REPEAT;301//ws = GL_CLAMP_TO_EDGE;302if ((!tile.mask_s || tile.cs) && !badclamp_s) {303// tile.tmem += (tile.sl>>2) << tile.size >> 1;304// tile.sh -= tile.sl;305// tile.sl = 0;306ws = GL_CLAMP_TO_EDGE;307}308if (tile.ms && !badmirror_s)309ws = ((!tile.mask_s || tile.cs) && !badclamp_s)?310GL_MIRROR_CLAMP_TO_EDGE_EXT : GL_MIRRORED_REPEAT;311312wt = GL_REPEAT;313//wt = GL_CLAMP_TO_EDGE;314if ((!tile.mask_t || tile.ct) && !badclamp_t) {315// tile.tmem += (tile.tl>>2) * line;316// tile.th -= tile.tl;317// tile.tl = 0;318wt = GL_CLAMP_TO_EDGE;319}320if (tile.mt && !badmirror_t)321wt = ((!tile.mask_t || tile.ct) && !badclamp_t)?322GL_MIRROR_CLAMP_TO_EDGE_EXT : GL_MIRRORED_REPEAT;323324#if 1325if ((npot_s||npot_t) && ws != GL_CLAMP_TO_EDGE) {326//LOG("Fixup npot clamp s\n");327ws = GL_CLAMP_TO_EDGE;328}329if ((npot_t||npot_s) && wt != GL_CLAMP_TO_EDGE) {330//LOG("Fixup npot clamp t\n");331wt = GL_CLAMP_TO_EDGE;332}333#else334// ws = GL_CLAMP_TO_EDGE;335// wt = GL_CLAMP_TO_EDGE;336#endif337338rtile.ws = ws;339rtile.wt = wt;340341rglAssert(!(tile.tmem & ~ 0xfff));342if (rglTexCache[tile.tmem].counter == rglTexCacheCounter &&343rglTexCache[tile.tmem].tex->fmt == tile.format &&344rglTexCache[tile.tmem].tex->w == tile.w345&&346rglTexCache[tile.tmem].tex->h == tile.h347// rglTexCache[tile.tmem].tex->h > (tile.th>>2)348) {349tex = rglTexCache[tile.tmem].tex;350goto ok;351}352353// printf("tile #%d fmt %s sz %d w %d mask %d %dx%d (%d %d)\n", &tile-rdpTiles, rdpImageFormats[tile.format], tile.size, line, tile.mask_s, (tile.sh - tile.sl >>2)+1, (tile.th - tile.tl >>2)+1, tile.sl>>2, tile.tl>>2);354355//rglAssert(tile.w == (tile.sh - tile.sl >>2)+1);356357{358int h, i, j, x, y;359int palette = 0;360uint32_t crc = 0;361rglTextureHead_t * list;362363#if 1364if (tile.format == RDP_FORMAT_CI ||365(tile.size <= 1 && RDP_GETOM_EN_TLUT(rdpState.otherModes))) {366// tlut crc367h = tile.size? 256:16;368if (tile.size == 0) palette = (tile.palette<<4)&0xff;369for (i=0; i<h; i++)370crc = ((crc>>3)|(crc<<(32-3)))+(rdpTlut[(i+palette)*4]);371}372373for (y=0; y<oh; y++) {374uint32_t * p = (uint32_t *) &from[(tile.tmem + y*line)/*&0x3fff*/];375for (x=0; x<(line>>2); x++)376crc = ((crc>>3)|(crc<<(32-3)))+(*p++);377}378379list = texturesByCrc + crc8(crc);380CIRCLEQ_FOREACH(rglTexture_t, tex, list, byCrc) {381//LOG("comparing %x with %x\n", tex->crc, crc);382if (tex->crc == crc &&383tex->fmt == tile.format &&384tex->clipw >= clipw &&385tex->cliph >= cliph &&386tex->w == tile.w &&387tex->h >= tile.h) {388CIRCLEQ_REMOVE(&texturesByUsage, tex, byUsage);389CIRCLEQ_INSERT_TAIL(rglTexture_t, &texturesByUsage, tex, byUsage);390goto ok2;391}392// if (tex->crc == crc)393// LOG("Same CRC %x !\n", crc);394}395#endif396397tex = rglNewTexture(crc);398tex->fmt = tile.format;399tex->w = tile.w;400tex->h = tile.h;401tex->clipw = clipw;402tex->cliph = cliph;403tex->crc = crc;404glGenTextures(1, &tex->id);405rglAssert(glGetError() == GL_NO_ERROR);406407408glBindTexture(GL_TEXTURE_2D, tex->id);409rglAssert(glGetError() == GL_NO_ERROR);410uint8_t * ptr;411GLuint packed = 0;412GLuint glfmt = 0, glpixfmt = 0;413414ptr = rglTmpTex2;415416#define XOR_SWAP_BYTE 3417#define XOR_SWAP_WORD 2418#define XOR_SWAP_DWORD 2419// ugly but it works ...420if (tile.cs || !tile.mask_s) ow = tile.w;421if (tile.ct || !tile.mask_t) oh = tile.h;422#define CLAMP \423int ci = i; \424int cj = j; \425if ((tile.cs || !tile.mask_s) && ci >= clipw) ci = clipw-1; \426if ((tile.ct || !tile.mask_t) && cj >= cliph) cj = cliph-1; \427428switch (tile.size) {429case 3:430for (j=0; j<oh; j++)431for (i=0; i<ow; i++) {432CLAMP;433uint32_t *tc = (uint32_t*)from;434int taddr = ((tile.tmem/4) + ((cj) * (line/4)) + (ci)) ^ ((cj & indirect) ? XOR_SWAP_DWORD : 0);435uint32_t a = tc[taddr/*&0xfff*/];436//uint32_t a = *(uint32_t *)&from[j*line + i*4 + tile.tmem ^ ((j&1)<<1) ^ XOR_SWAP_DWORD];437*(uint32_t *)&ptr[(tile.h-1-j)*tile.w*4 + (tile.w-1-i)*4] = a;438}439break;440case 2:441for (j=0; j<oh; j++)442for (i=0; i<ow; i++) {443CLAMP;444uint16_t *tc = (uint16_t*)from;445int taddr = ((tile.tmem/2) + ((cj) * (line/2)) + (ci)) ^ ((cj & indirect) ? XOR_SWAP_WORD : 0);446uint16_t a = tc[(taddr ^ WORD_ADDR_XOR)/*&0x1fff*/];447// uint16_t a = *(uint16_t *)&from[j*line + i*2 + tile.tmem ^ ((j&1)<<2) ^ XOR_SWAP_WORD];448*(uint16_t *)&ptr[(tile.h-1-j)*tile.w*2 + (tile.w-1-i)*2] = a;449}450break;451case 1:452for (j=0; j<oh; j++)453for (i=0; i<ow; i++) {454CLAMP;455uint8_t a = *(uint8_t *)&from[((cj*line + ci + tile.tmem) ^ ((cj & indirect)<<2) ^ XOR_SWAP_BYTE)/*&0xfff*/];456*(uint8_t *)&ptr[(tile.h-1-j)*tile.w + (tile.w-1-i)] = a;457}458break;459case 0:460// FIXME461for (j=0; j<tile.h; j++)462for (i=0; i<tile.w; i+=2) {463CLAMP;464uint8_t a = *(uint8_t *)&from[((cj*line + ci/2 + tile.tmem) ^ ((cj & indirect)<<2) ^ XOR_SWAP_BYTE)/*&0x3fff*/];465*(uint8_t *)&ptr[(tile.h-1-j)*tile.w/2 + (tile.w/2-1-i/2)] = a; //(a>>4)|(a<<4);466}467break;468}469from = ptr;470471i = tile.format;472473// in Tom Clancy, they do this, using I texture with TLUT enabled474if (i != RDP_FORMAT_CI && tile.size <= 1 && RDP_GETOM_EN_TLUT(rdpState.otherModes)) {475LOG("fixing %s-%d tile to CI\n", rdpImageFormats[i], tile.size);476i = RDP_FORMAT_CI;477}478479if (tile.size <= 1 && i == RDP_FORMAT_RGBA) {480LOG("fixing RGBA tile to I\n");481i = RDP_FORMAT_I;482}483484switch (i) {485case RDP_FORMAT_CI: {486if (!RDP_GETOM_TLUT_TYPE(rdpState.otherModes)) {487glfmt = GL_RGBA;488packed = GL_UNSIGNED_SHORT_5_5_5_1;489} else {490glfmt = GL_RGBA;491glpixfmt = GL_LUMINANCE_ALPHA;492//glfmt = GL_LUMINANCE_ALPHA;493packed = GL_UNSIGNED_BYTE;494}495switch (tile.size) {496case 0:497ptr = rglTmpTex;498for (i=0; i<tile.w*tile.h/2; i++) {499uint16_t a = rdpTlut[((from[i]&0xf) + palette/* ^ WORD_ADDR_XOR*/)*4];500uint16_t b = rdpTlut[((from[i]>>4) + palette/* ^ WORD_ADDR_XOR*/)*4];501if (RDP_GETOM_TLUT_TYPE(rdpState.otherModes)) {502a = (a>>8)|(a<<8);503b = (b>>8)|(b<<8);504}505*(uint16_t *)&ptr[i*4] = a;506*(uint16_t *)&ptr[i*4+2] = b;507}508break;509case 1:510ptr = rglTmpTex;511//rdpTlut[palette] = 0;512for (i=0; i<tile.w*tile.h; i++) {513uint16_t a = rdpTlut[(from[i] + palette/* ^ WORD_ADDR_XOR*/)*4];514if (RDP_GETOM_TLUT_TYPE(rdpState.otherModes))515a = (a>>8)|(a<<8);516*(uint16_t *)&ptr[i*2] = a;517}518break;519}520break;521}522case RDP_FORMAT_RGBA: {523glfmt = GL_RGBA;524switch (tile.size) {525case 2:526//packed = GL_UNSIGNED_SHORT_4_4_4_4_REV;527packed = GL_UNSIGNED_SHORT_5_5_5_1;528break;529case 3:530packed = GL_UNSIGNED_INT_8_8_8_8;531break;532}533break;534}535case RDP_FORMAT_IA: {536glfmt = GL_RGBA;537glpixfmt = GL_LUMINANCE_ALPHA;538//if (tile.size == 0) line *= 2;539switch (tile.size) {540case 0: {541packed = GL_UNSIGNED_BYTE;542ptr = rglTmpTex;543for (i=0; i<tile.h*tile.w/2; i++) {544uint32_t a = (from[i]&0xe0) >> 5;545int8_t b = (from[i]&0x10) >> 4;546ptr[i*4+2] = (a<<5) | (a<<2) | (a>>1);547ptr[i*4+3] = -b;548a = (from[i]&0xe) >> 1;549b = (from[i]&0x1);550ptr[i*4+0] = (a<<5) | (a<<2) | (a>>1);551ptr[i*4+1] = -b;552}553break;554}555case 1: {556packed = GL_UNSIGNED_BYTE;557ptr = rglTmpTex;558for (i=0; i<tile.h*tile.w; i++) {559uint32_t a = from[i]&0xF0;560a = a | (a>>4);561ptr[i*2] = a | (a>>4);562a = from[i]&0x0F;563a = a | (a<<4);564ptr[i*2+1] = a;565}566break;567}568case 2:569packed = GL_UNSIGNED_BYTE;570ptr = rglTmpTex;571for (i=0; i<tile.h*tile.w*2; i+=2) {572ptr[i] = from[i+1];573ptr[i+1] = from[i];574}575break;576}577break;578}579case RDP_FORMAT_I: {580glfmt = GL_INTENSITY;581// if (RDP_GETOM_ALPHA_CVG_SELECT(rdpState.otherModes))582// glfmt = GL_LUMINANCE;583glpixfmt = GL_LUMINANCE;584switch (tile.size) {585case 0: {586packed = GL_UNSIGNED_BYTE;587ptr = rglTmpTex;588for (i=0; i<tile.h*tile.w/2; i++) {589uint32_t a = from[i]&0xF0;590ptr[i*2+1] = a | (a>>4);591a = from[i]&0x0F;592ptr[i*2] = a | (a<<4);593}594break;595}596case 1: {597packed = GL_UNSIGNED_BYTE;598break;599}600}601break;602}603}604605if (packed) {606DUMP("loading texture %dx%d fmt %s size %x (%x %x %x %p)\n", tile.w, tile.h, rdpImageFormats[tile.format], tile.size, glfmt, glpixfmt, packed, ptr);607// printf("cycle type = %d\n", chunk.rdpState.otherModes.cycle_type);608if (!glpixfmt)609glpixfmt = glfmt;610rglAssert(glGetError() == GL_NO_ERROR);611glTexImage2D(GL_TEXTURE_2D, 0, glfmt, tile.w, tile.h, 0, glpixfmt, packed,612ptr);613rglAssert(glGetError() == GL_NO_ERROR);614615616#if 0617if (1||RDP_GETOM_CYCLE_TYPE(rdpState.otherModes) == RDP_CYCLE_TYPE_COPY) {618uint32_t * pixels = (uint32_t *) malloc(tile.w*tile.h*4);619// 0x1902 is another constant meaning GL_DEPTH_COMPONENT620// (but isn't defined in gl's headers !!)621if (1/*fmt != GL_DEPTH_COMPONENT && fmt != 0x1902*/) {622glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);623ilTexImage(tile.w, tile.h, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, pixels);624} else {625glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, pixels);626int i;627for (i=0; i<tile.w*tile.h; i++)628((unsigned char *)ptr)[i] = ((unsigned short *)pixels)[i]/256;629ilTexImage(tile.w, tile.h, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, ptr);630}631char name[128];632// sprintf(name, "mkdir -p dump ; rm -f dump/tex%04d.png", i);633// system(name);634static int num;635sprintf(name, "dump/tex%04d-%s-%d-%d-%d.png", num++, rdpImageFormats[tile.format], tile.size, &tile - rdpTiles, tile.tmem);636fprintf(stderr, "Writing '%s'\n", name);637ilSaveImage(name);638639free(pixels);640}641#endif642}643if (!packed) {644LOGERROR("unsuported format %s size %d\n", rdpImageFormats[tile.format], tile.size);645}646647648}649ok2:650rglTexCache[tile.tmem].counter = rglTexCacheCounter;651rglTexCache[tile.tmem].tex = tex;652653ok:654rtile.tex = tex;655656{657GLuint filter;658if (recth) {659switch (RDP_GETOM_SAMPLE_TYPE(rdpState.otherModes)) {660case 0:661filter = GL_NEAREST;662break;663default:664filter = GL_LINEAR;665break;666}667} else668filter = GL_LINEAR;669670rtile.filter = filter;671// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);672// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);673}674}675676677678