2017-02-09 04:30:25 +01:00
|
|
|
#include "internal.h"
|
2014-12-20 21:34:19 +01:00
|
|
|
|
2016-05-03 08:41:05 +02:00
|
|
|
// Return bits per pixel
|
2014-12-20 21:34:19 +01:00
|
|
|
static inline size_t fmtSize(GPU_TEXCOLOR fmt)
|
|
|
|
{
|
|
|
|
switch (fmt)
|
|
|
|
{
|
|
|
|
case GPU_RGBA8:
|
2016-05-03 08:41:05 +02:00
|
|
|
return 32;
|
2014-12-20 21:34:19 +01:00
|
|
|
case GPU_RGB8:
|
2016-05-03 08:41:05 +02:00
|
|
|
return 24;
|
2014-12-20 21:34:19 +01:00
|
|
|
case GPU_RGBA5551:
|
|
|
|
case GPU_RGB565:
|
|
|
|
case GPU_RGBA4:
|
2016-04-04 00:10:06 +02:00
|
|
|
case GPU_LA8:
|
|
|
|
case GPU_HILO8:
|
2016-05-03 08:41:05 +02:00
|
|
|
return 16;
|
2016-04-04 00:10:06 +02:00
|
|
|
case GPU_L8:
|
|
|
|
case GPU_A8:
|
|
|
|
case GPU_LA4:
|
2016-05-03 08:41:05 +02:00
|
|
|
case GPU_ETC1A4:
|
|
|
|
return 8;
|
|
|
|
case GPU_L4:
|
|
|
|
case GPU_A4:
|
|
|
|
case GPU_ETC1:
|
|
|
|
return 4;
|
2014-12-20 21:34:19 +01:00
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-28 15:51:07 +01:00
|
|
|
static inline bool addrIsVRAM(const void* addr)
|
|
|
|
{
|
|
|
|
u32 vaddr = (u32)addr;
|
|
|
|
return vaddr >= 0x1F000000 && vaddr < 0x1F600000;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool C3Di_TexInitCommon(C3D_Tex* tex, int width, int height, GPU_TEXCOLOR format, void* (*texAlloc)(size_t))
|
2014-12-20 21:34:19 +01:00
|
|
|
{
|
|
|
|
if (tex->data) return false;
|
|
|
|
|
2015-07-23 22:22:28 +02:00
|
|
|
u32 size = fmtSize(format);
|
|
|
|
if (!size) return false;
|
2016-05-03 08:41:05 +02:00
|
|
|
size *= width * height / 8;
|
2014-12-20 21:34:19 +01:00
|
|
|
|
2015-11-28 15:51:07 +01:00
|
|
|
tex->data = texAlloc(size);
|
2014-12-20 21:34:19 +01:00
|
|
|
if (!tex->data) return false;
|
|
|
|
|
|
|
|
tex->width = width;
|
|
|
|
tex->height = height;
|
|
|
|
tex->param = GPU_TEXTURE_MAG_FILTER(GPU_NEAREST) | GPU_TEXTURE_MIN_FILTER(GPU_NEAREST);
|
2016-05-03 08:41:05 +02:00
|
|
|
if (format == GPU_ETC1)
|
|
|
|
tex->param |= GPU_TEXTURE_ETC1_PARAM;
|
2014-12-20 21:34:19 +01:00
|
|
|
tex->fmt = format;
|
2015-07-23 22:22:28 +02:00
|
|
|
tex->size = size;
|
2014-12-20 21:34:19 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-11-28 15:51:07 +01:00
|
|
|
bool C3D_TexInit(C3D_Tex* tex, int width, int height, GPU_TEXCOLOR format)
|
|
|
|
{
|
|
|
|
return C3Di_TexInitCommon(tex, width, height, format, linearAlloc);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool C3D_TexInitVRAM(C3D_Tex* tex, int width, int height, GPU_TEXCOLOR format)
|
|
|
|
{
|
|
|
|
return C3Di_TexInitCommon(tex, width, height, format, vramAlloc);
|
|
|
|
}
|
|
|
|
|
2014-12-20 21:34:19 +01:00
|
|
|
void C3D_TexUpload(C3D_Tex* tex, const void* data)
|
|
|
|
{
|
2015-11-28 15:51:07 +01:00
|
|
|
if (tex->data && !addrIsVRAM(tex->data))
|
2014-12-20 21:34:19 +01:00
|
|
|
memcpy(tex->data, data, tex->size);
|
|
|
|
}
|
|
|
|
|
|
|
|
void C3D_TexSetFilter(C3D_Tex* tex, GPU_TEXTURE_FILTER_PARAM magFilter, GPU_TEXTURE_FILTER_PARAM minFilter)
|
|
|
|
{
|
|
|
|
tex->param &= ~(GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR));
|
|
|
|
tex->param |= GPU_TEXTURE_MAG_FILTER(magFilter) | GPU_TEXTURE_MIN_FILTER(minFilter);
|
|
|
|
}
|
|
|
|
|
|
|
|
void C3D_TexSetWrap(C3D_Tex* tex, GPU_TEXTURE_WRAP_PARAM wrapS, GPU_TEXTURE_WRAP_PARAM wrapT)
|
|
|
|
{
|
|
|
|
tex->param &= ~(GPU_TEXTURE_WRAP_S(3) | GPU_TEXTURE_WRAP_T(3));
|
|
|
|
tex->param |= GPU_TEXTURE_WRAP_S(wrapS) | GPU_TEXTURE_WRAP_T(wrapT);
|
|
|
|
}
|
|
|
|
|
|
|
|
void C3D_TexBind(int unitId, C3D_Tex* tex)
|
|
|
|
{
|
|
|
|
C3D_Context* ctx = C3Di_GetContext();
|
|
|
|
|
|
|
|
if (!(ctx->flags & C3DiF_Active))
|
|
|
|
return;
|
|
|
|
|
|
|
|
ctx->flags |= C3DiF_Tex(unitId);
|
|
|
|
ctx->tex[unitId] = tex;
|
|
|
|
}
|
|
|
|
|
|
|
|
void C3D_TexFlush(C3D_Tex* tex)
|
|
|
|
{
|
2015-11-28 15:51:07 +01:00
|
|
|
if (tex->data && !addrIsVRAM(tex->data))
|
2015-09-06 22:08:28 +02:00
|
|
|
GSPGPU_FlushDataCache(tex->data, tex->size);
|
2014-12-20 21:34:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void C3D_TexDelete(C3D_Tex* tex)
|
|
|
|
{
|
|
|
|
if (!tex->data) return;
|
|
|
|
|
2015-11-28 15:51:07 +01:00
|
|
|
if (addrIsVRAM(tex->data))
|
|
|
|
vramFree(tex->data);
|
|
|
|
else
|
|
|
|
linearFree(tex->data);
|
|
|
|
|
2014-12-20 21:34:19 +01:00
|
|
|
tex->data = NULL;
|
|
|
|
}
|