#pragma once #include #include #include #include "gl_assert.h" #define MEMSET(dst, v, size) memset((dst), (v), (size)) typedef enum GPUAlpha { GPU_ALPHA_DISABLE = 0, GPU_ALPHA_ENABLE = 1 } GPUAlpha; typedef enum GPUTexture { GPU_TEXTURE_DISABLE = 0, GPU_TEXTURE_ENABLE = 1 } GPUTexture; typedef enum GPUTextureAlpha { GPU_TXRALPHA_DISABLE = 1, GPU_TXRALPHA_ENABLE = 0 } GPUTextureAlpha; typedef enum GPUList { GPU_LIST_OP_POLY = 0, GPU_LIST_OP_MOD = 1, GPU_LIST_TR_POLY = 2, GPU_LIST_TR_MOD = 3, GPU_LIST_PT_POLY = 4 } GPUList; typedef enum GPUBlend { GPU_BLEND_ZERO = 0, GPU_BLEND_ONE = 1, GPU_BLEND_DESTCOLOR = 2, GPU_BLEND_INVDESTCOLOR = 3, GPU_BLEND_SRCALPHA = 4, GPU_BLEND_INVSRCALPHA = 5, GPU_BLEND_DESTALPHA = 6, GPU_BLEND_INVDESTALPHA = 7 } GPUBlend; typedef enum GPUDepthCompare { GPU_DEPTHCMP_NEVER = 0, GPU_DEPTHCMP_LESS = 1, GPU_DEPTHCMP_EQUAL = 2, GPU_DEPTHCMP_LEQUAL = 3, GPU_DEPTHCMP_GREATER = 4, GPU_DEPTHCMP_NOTEQUAL = 5, GPU_DEPTHCMP_GEQUAL = 6, GPU_DEPTHCMP_ALWAYS = 7 } GPUDepthCompare; typedef enum GPUTextureFormat { GPU_TXRFMT_NONE, GPU_TXRFMT_VQ_DISABLE = (0 << 30), GPU_TXRFMT_VQ_ENABLE = (1 << 30), GPU_TXRFMT_ARGB1555 = (0 << 27), GPU_TXRFMT_RGB565 = (1 << 27), GPU_TXRFMT_ARGB4444 = (2 << 27), GPU_TXRFMT_YUV422 = (3 << 27), GPU_TXRFMT_BUMP = (4 << 27), GPU_TXRFMT_PAL4BPP = (5 << 27), GPU_TXRFMT_PAL8BPP = (6 << 27), GPU_TXRFMT_TWIDDLED = (0 << 26), GPU_TXRFMT_NONTWIDDLED = (1 << 26), GPU_TXRFMT_NOSTRIDE = (0 << 21), GPU_TXRFMT_STRIDE = (1 << 21) } GPUTextureFormat; static inline uint32_t GPUPaletteSelect8BPP(uint32_t x) { return x << 25; } static inline uint32_t GPUPaletteSelect4BPP(uint32_t x) { return x << 21; } typedef enum GPUCulling { GPU_CULLING_NONE = 0, GPU_CULLING_SMALL = 1, GPU_CULLING_CCW = 2, GPU_CULLING_CW = 3 } GPUCulling; typedef enum GPUUVFlip { GPU_UVFLIP_NONE = 0, GPU_UVFLIP_V = 1, GPU_UVFLIP_U = 2, GPU_UVFLIP_UV = 3 } GPUUVFlip; typedef enum GPUUVClamp { GPU_UVCLAMP_NONE = 0, GPU_UVCLAMP_V = 1, GPU_UVCLAMP_U = 2, GPU_UVCLAMP_UV = 3 } GPUUVClamp; typedef enum GPUColorClamp { GPU_CLRCLAMP_DISABLE = 0, GPU_CLRCLAMP_ENABLE = 1 } GPUColorClamp; typedef enum GPUFilter { GPU_FILTER_NEAREST = 0, GPU_FILTER_BILINEAR = 2, GPU_FILTER_TRILINEAR1 = 4, GPU_FILTER_TRILINEAR2 = 6 } GPUFilter; typedef enum GPUDepthWrite { GPU_DEPTHWRITE_ENABLE = 0, GPU_DEPTHWRITE_DISABLE = 1 } GPUDepthWrite; typedef enum GPUUserClip { GPU_USERCLIP_DISABLE = 0, GPU_USERCLIP_INSIDE = 2, GPU_USERCLIP_OUTSIDE = 3 } GPUUserClip; typedef enum GPUColorFormat { GPU_CLRFMT_ARGBPACKED = 0, GPU_CLRFMT_4FLOATS = 1, GPU_CLRFMT_INTENSITY = 2, GPU_CLRFMT_INTENSITY_PREV = 3 } GPUColorFormat; typedef enum GPUUVFormat { GPU_UVFMT_32BIT = 0, GPU_UVFMT_16BIT = 1 } GPUUVFormat; typedef enum GPUPaletteFormat { GPU_PAL_ARGB1555 = 0, GPU_PAL_RGB565 = 1, GPU_PAL_ARGB4444 = 2, GPU_PAL_ARGB8888 = 3 } GPUPaletteFormat; typedef enum GPUFog { GPU_FOG_TABLE = 0, GPU_FOG_VERTEX = 1, GPU_FOG_DISABLE = 2, GPU_FOG_TABLE2 = 3 } GPUFog; typedef enum GPUShade { GPU_SHADE_FLAT = 0, GPU_SHADE_GOURAUD = 1 } GPUShade; typedef enum GPUTextureEnv { GPU_TXRENV_REPLACE = 0, GPU_TXRENV_MODULATE = 1, GPU_TXRENV_DECAL = 2, GPU_TXRENV_MODULATEALPHA = 3 } GPUTextureEnv; typedef struct VideoMode { uint16_t width; uint16_t height; } VideoMode; const VideoMode* GetVideoMode(); /* Duplication of pvr_poly_cxt_t from KOS so that we can * compile on non-KOS platforms for testing */ typedef struct { GPUList list_type; struct { int alpha; int shading; int fog_type; int culling; int color_clamp; int clip_mode; int modifier_mode; int specular; int alpha2; int fog_type2; int color_clamp2; } gen; struct { int src; int dst; int src_enable; int dst_enable; int src2; int dst2; int src_enable2; int dst_enable2; } blend; struct { int color; int uv; int modifier; } fmt; struct { int comparison; int write; } depth; struct { int enable; int filter; int mipmap; int mipmap_bias; int uv_flip; int uv_clamp; int alpha; int env; int width; int height; int format; void* base; } txr; struct { int enable; int filter; int mipmap; int mipmap_bias; int uv_flip; int uv_clamp; int alpha; int env; int width; int height; int format; void* base; } txr2; } PolyContext; typedef struct { uint32_t cmd; uint32_t mode1; uint32_t mode2; uint32_t mode3; uint32_t d1; uint32_t d2; uint32_t d3; uint32_t d4; } PolyHeader; enum GPUCommand { GPU_CMD_POLYHDR = 0x80840000, GPU_CMD_VERTEX = 0xe0000000, GPU_CMD_VERTEX_EOL = 0xf0000000, GPU_CMD_USERCLIP = 0x20000000, GPU_CMD_MODIFIER = 0x80000000, GPU_CMD_SPRITE = 0xA0000000 }; typedef float Matrix4x4[16]; void SceneBegin(); void SceneListBegin(GPUList list); void SceneListSubmit(void* src, int n); void SceneListFinish(); void SceneFinish(); #define GPU_TA_CMD_TYPE_SHIFT 24 #define GPU_TA_CMD_TYPE_MASK (7 << GPU_TA_CMD_TYPE_SHIFT) #define GPU_TA_CMD_USERCLIP_SHIFT 16 #define GPU_TA_CMD_USERCLIP_MASK (3 << GPU_TA_CMD_USERCLIP_SHIFT) #define GPU_TA_CMD_CLRFMT_SHIFT 4 #define GPU_TA_CMD_CLRFMT_MASK (7 << GPU_TA_CMD_CLRFMT_SHIFT) #define GPU_TA_CMD_SPECULAR_SHIFT 2 #define GPU_TA_CMD_SPECULAR_MASK (1 << GPU_TA_CMD_SPECULAR_SHIFT) #define GPU_TA_CMD_SHADE_SHIFT 1 #define GPU_TA_CMD_SHADE_MASK (1 << GPU_TA_CMD_SHADE_SHIFT) #define GPU_TA_CMD_UVFMT_SHIFT 0 #define GPU_TA_CMD_UVFMT_MASK (1 << GPU_TA_CMD_UVFMT_SHIFT) #define GPU_TA_CMD_MODIFIER_SHIFT 7 #define GPU_TA_CMD_MODIFIER_MASK (1 << GPU_TA_CMD_MODIFIER_SHIFT) #define GPU_TA_CMD_MODIFIERMODE_SHIFT 6 #define GPU_TA_CMD_MODIFIERMODE_MASK (1 << GPU_TA_CMD_MODIFIERMODE_SHIFT) #define GPU_TA_PM1_DEPTHCMP_SHIFT 29 #define GPU_TA_PM1_DEPTHCMP_MASK (7 << GPU_TA_PM1_DEPTHCMP_SHIFT) #define GPU_TA_PM1_CULLING_SHIFT 27 #define GPU_TA_PM1_CULLING_MASK (3 << GPU_TA_PM1_CULLING_SHIFT) #define GPU_TA_PM1_DEPTHWRITE_SHIFT 26 #define GPU_TA_PM1_DEPTHWRITE_MASK (1 << GPU_TA_PM1_DEPTHWRITE_SHIFT) #define GPU_TA_PM1_TXRENABLE_SHIFT 25 #define GPU_TA_PM1_TXRENABLE_MASK (1 << GPU_TA_PM1_TXRENABLE_SHIFT) #define GPU_TA_PM1_MODIFIERINST_SHIFT 29 #define GPU_TA_PM1_MODIFIERINST_MASK (3 << GPU_TA_PM1_MODIFIERINST_SHIFT) #define GPU_TA_PM2_SRCBLEND_SHIFT 29 #define GPU_TA_PM2_SRCBLEND_MASK (7 << GPU_TA_PM2_SRCBLEND_SHIFT) #define GPU_TA_PM2_DSTBLEND_SHIFT 26 #define GPU_TA_PM2_DSTBLEND_MASK (7 << GPU_TA_PM2_DSTBLEND_SHIFT) #define GPU_TA_PM2_SRCENABLE_SHIFT 25 #define GPU_TA_PM2_SRCENABLE_MASK (1 << GPU_TA_PM2_SRCENABLE_SHIFT) #define GPU_TA_PM2_DSTENABLE_SHIFT 24 #define GPU_TA_PM2_DSTENABLE_MASK (1 << GPU_TA_PM2_DSTENABLE_SHIFT) #define GPU_TA_PM2_FOG_SHIFT 22 #define GPU_TA_PM2_FOG_MASK (3 << GPU_TA_PM2_FOG_SHIFT) #define GPU_TA_PM2_CLAMP_SHIFT 21 #define GPU_TA_PM2_CLAMP_MASK (1 << GPU_TA_PM2_CLAMP_SHIFT) #define GPU_TA_PM2_ALPHA_SHIFT 20 #define GPU_TA_PM2_ALPHA_MASK (1 << GPU_TA_PM2_ALPHA_SHIFT) #define GPU_TA_PM2_TXRALPHA_SHIFT 19 #define GPU_TA_PM2_TXRALPHA_MASK (1 << GPU_TA_PM2_TXRALPHA_SHIFT) #define GPU_TA_PM2_UVFLIP_SHIFT 17 #define GPU_TA_PM2_UVFLIP_MASK (3 << GPU_TA_PM2_UVFLIP_SHIFT) #define GPU_TA_PM2_UVCLAMP_SHIFT 15 #define GPU_TA_PM2_UVCLAMP_MASK (3 << GPU_TA_PM2_UVCLAMP_SHIFT) #define GPU_TA_PM2_FILTER_SHIFT 12 #define GPU_TA_PM2_FILTER_MASK (7 << GPU_TA_PM2_FILTER_SHIFT) #define GPU_TA_PM2_MIPBIAS_SHIFT 8 #define GPU_TA_PM2_MIPBIAS_MASK (15 << GPU_TA_PM2_MIPBIAS_SHIFT) #define GPU_TA_PM2_TXRENV_SHIFT 6 #define GPU_TA_PM2_TXRENV_MASK (3 << GPU_TA_PM2_TXRENV_SHIFT) #define GPU_TA_PM2_USIZE_SHIFT 3 #define GPU_TA_PM2_USIZE_MASK (7 << GPU_TA_PM2_USIZE_SHIFT) #define GPU_TA_PM2_VSIZE_SHIFT 0 #define GPU_TA_PM2_VSIZE_MASK (7 << GPU_TA_PM2_VSIZE_SHIFT) #define GPU_TA_PM3_MIPMAP_SHIFT 31 #define GPU_TA_PM3_MIPMAP_MASK (1 << GPU_TA_PM3_MIPMAP_SHIFT) #define GPU_TA_PM3_TXRFMT_SHIFT 0 #define GPU_TA_PM3_TXRFMT_MASK 0xffffffff static inline int DimensionFlag(const int w) { switch(w) { case 16: return 1; case 32: return 2; case 64: return 3; case 128: return 4; case 256: return 5; case 512: return 6; case 1024: return 7; case 8: default: return 0; } } /* Compile a polygon context into a polygon header */ static inline void CompilePolyHeader(PolyHeader *dst, const PolyContext *src) { uint32_t txr_base; /* Basically we just take each parameter, clip it, shift it into place, and OR it into the final result. */ /* The base values for CMD */ dst->cmd = GPU_CMD_POLYHDR; dst->cmd |= src->txr.enable << 3; /* Or in the list type, shading type, color and UV formats */ dst->cmd |= (src->list_type << GPU_TA_CMD_TYPE_SHIFT) & GPU_TA_CMD_TYPE_MASK; dst->cmd |= (src->fmt.color << GPU_TA_CMD_CLRFMT_SHIFT) & GPU_TA_CMD_CLRFMT_MASK; dst->cmd |= (src->gen.shading << GPU_TA_CMD_SHADE_SHIFT) & GPU_TA_CMD_SHADE_MASK; dst->cmd |= (src->fmt.uv << GPU_TA_CMD_UVFMT_SHIFT) & GPU_TA_CMD_UVFMT_MASK; dst->cmd |= (src->gen.clip_mode << GPU_TA_CMD_USERCLIP_SHIFT) & GPU_TA_CMD_USERCLIP_MASK; dst->cmd |= (src->fmt.modifier << GPU_TA_CMD_MODIFIER_SHIFT) & GPU_TA_CMD_MODIFIER_MASK; dst->cmd |= (src->gen.modifier_mode << GPU_TA_CMD_MODIFIERMODE_SHIFT) & GPU_TA_CMD_MODIFIERMODE_MASK; dst->cmd |= (src->gen.specular << GPU_TA_CMD_SPECULAR_SHIFT) & GPU_TA_CMD_SPECULAR_MASK; /* Polygon mode 1 */ dst->mode1 = (src->depth.comparison << GPU_TA_PM1_DEPTHCMP_SHIFT) & GPU_TA_PM1_DEPTHCMP_MASK; dst->mode1 |= (src->gen.culling << GPU_TA_PM1_CULLING_SHIFT) & GPU_TA_PM1_CULLING_MASK; dst->mode1 |= (src->depth.write << GPU_TA_PM1_DEPTHWRITE_SHIFT) & GPU_TA_PM1_DEPTHWRITE_MASK; dst->mode1 |= (src->txr.enable << GPU_TA_PM1_TXRENABLE_SHIFT) & GPU_TA_PM1_TXRENABLE_MASK; /* Polygon mode 2 */ dst->mode2 = (src->blend.src << GPU_TA_PM2_SRCBLEND_SHIFT) & GPU_TA_PM2_SRCBLEND_MASK; dst->mode2 |= (src->blend.dst << GPU_TA_PM2_DSTBLEND_SHIFT) & GPU_TA_PM2_DSTBLEND_MASK; dst->mode2 |= (src->blend.src_enable << GPU_TA_PM2_SRCENABLE_SHIFT) & GPU_TA_PM2_SRCENABLE_MASK; dst->mode2 |= (src->blend.dst_enable << GPU_TA_PM2_DSTENABLE_SHIFT) & GPU_TA_PM2_DSTENABLE_MASK; dst->mode2 |= (src->gen.fog_type << GPU_TA_PM2_FOG_SHIFT) & GPU_TA_PM2_FOG_MASK; dst->mode2 |= (src->gen.color_clamp << GPU_TA_PM2_CLAMP_SHIFT) & GPU_TA_PM2_CLAMP_MASK; dst->mode2 |= (src->gen.alpha << GPU_TA_PM2_ALPHA_SHIFT) & GPU_TA_PM2_ALPHA_MASK; if(src->txr.enable == GPU_TEXTURE_DISABLE) { dst->mode3 = 0; } else { dst->mode2 |= (src->txr.alpha << GPU_TA_PM2_TXRALPHA_SHIFT) & GPU_TA_PM2_TXRALPHA_MASK; dst->mode2 |= (src->txr.uv_flip << GPU_TA_PM2_UVFLIP_SHIFT) & GPU_TA_PM2_UVFLIP_MASK; dst->mode2 |= (src->txr.uv_clamp << GPU_TA_PM2_UVCLAMP_SHIFT) & GPU_TA_PM2_UVCLAMP_MASK; dst->mode2 |= (src->txr.filter << GPU_TA_PM2_FILTER_SHIFT) & GPU_TA_PM2_FILTER_MASK; dst->mode2 |= (src->txr.mipmap_bias << GPU_TA_PM2_MIPBIAS_SHIFT) & GPU_TA_PM2_MIPBIAS_MASK; dst->mode2 |= (src->txr.env << GPU_TA_PM2_TXRENV_SHIFT) & GPU_TA_PM2_TXRENV_MASK; dst->mode2 |= (DimensionFlag(src->txr.width) << GPU_TA_PM2_USIZE_SHIFT) & GPU_TA_PM2_USIZE_MASK; dst->mode2 |= (DimensionFlag(src->txr.height) << GPU_TA_PM2_VSIZE_SHIFT) & GPU_TA_PM2_VSIZE_MASK; /* Polygon mode 3 */ dst->mode3 = (src->txr.mipmap << GPU_TA_PM3_MIPMAP_SHIFT) & GPU_TA_PM3_MIPMAP_MASK; dst->mode3 |= (src->txr.format << GPU_TA_PM3_TXRFMT_SHIFT) & GPU_TA_PM3_TXRFMT_MASK; /* Convert the texture address */ txr_base = (uint32_t) src->txr.base; txr_base = (txr_base & 0x00fffff8) >> 3; dst->mode3 |= txr_base; } if(src->fmt.modifier && src->gen.modifier_mode) { /* If we're affected by a modifier volume, silently promote the header to the one that is affected by a modifier volume. */ dst->d1 = dst->mode2; dst->d2 = dst->mode3; } else { dst->d1 = dst->d2 = 0xffffffff; } dst->d3 = dst->d4 = 0xffffffff; } #ifdef BACKEND_KOSPVR #include "platforms/sh4.h" #else #include "platforms/software.h" #endif