Dreamcast: Simplify GPU code

This commit is contained in:
UnknownShadow200 2025-07-05 23:47:24 +10:00
parent 863906766f
commit e41c2b15fb
14 changed files with 197 additions and 262 deletions

View File

@ -11,7 +11,7 @@ endif
# Directory where object files are placed
BUILD_DIR := build/dc
# List of directories containing source code
SOURCE_DIRS := src third_party/bearssl misc/dreamcast
SOURCE_DIRS := src third_party/bearssl src/dreamcast
# Name of the final output
TARGET := ClassiCube-dc
# Additional libraries to link against
@ -81,10 +81,13 @@ $(TARGET).cdi: $(TARGET).iso
$(BUILD_DIR)/%.o: src/%.c
kos-cc $(CFLAGS) $(INCLUDES) $(DEPFLAGS) -c $< -o $@
$(BUILD_DIR)/%.o: src/dreamcast/%.c
kos-cc $(CFLAGS) $(INCLUDES) $(DEPFLAGS) -c $< -o $@
$(BUILD_DIR)/%.o: third_party/bearssl/%.c
kos-cc $(CFLAGS) $(INCLUDES) -c $< -o $@
$(BUILD_DIR)/%.o: misc/dreamcast/%.S
$(BUILD_DIR)/%.o: src/dreamcast/%.S
kos-cc $(DEPFLAGS) -c $< -o $@

View File

@ -1,8 +1,5 @@
#include "Core.h"
#if defined CC_BUILD_DREAMCAST
#include <kos.h>
#include "Audio.h"
#include "../Audio.h"
/* TODO needs way more testing, especially with sounds */
static cc_bool valid_handles[SND_STREAM_MAX];
@ -20,8 +17,8 @@ struct AudioContext {
int count, sampleRate;
};
#define AUDIO_OVERRIDE_ALLOC
#include "_AudioBase.h"
#include "Funcs.h"
#include "../_AudioBase.h"
#include "../Funcs.h"
cc_bool AudioBackend_Init(void) {
return snd_stream_init() == 0;
@ -213,5 +210,4 @@ cc_result Audio_AllocChunks(cc_uint32 size, struct AudioChunk* chunks, int numCh
void Audio_FreeChunks(struct AudioChunk* chunks, int numChunks) {
free(chunks[0].data);
}
#endif

View File

@ -1,23 +1,30 @@
#include "Core.h"
#if defined CC_BUILD_DREAMCAST
#include "_GraphicsBase.h"
#include "Errors.h"
#include "Logger.h"
#include "Window.h"
#include "../_GraphicsBase.h"
#include "../Errors.h"
#include "../Logger.h"
#include "../Window.h"
#include <malloc.h>
#include <string.h>
#include <kos.h>
#include <dc/matrix.h>
#include <dc/pvr.h>
#include "../third_party/gldc/state.c"
#include "../third_party/gldc/sh4.c"
#include "VertexSubmit.h"
static cc_bool renderingDisabled;
static cc_bool stateDirty;
#define VERTEX_BUFFER_SIZE 32 * 50000
#define PT_ALPHA_REF 0x011c
typedef struct {
uint32_t format;
void *data;
uint32_t log2_w: 4;
uint32_t log2_h: 4;
uint32_t size: 24;
} GPUTexture;
#define MAX_TEXTURE_COUNT 768
static GPUTexture tex_list[MAX_TEXTURE_COUNT];
/*########################################################################################################################*
@ -79,8 +86,6 @@ static void CommandsList_Append(struct CommandsList* list, const void* cmd) {
#define TEXMEM_RESERVED (48 * 1024)
#define TEXMEM_TO_PAGE(addr) ((cc_uint32)((addr) - texmem_base) / TEXMEM_PAGE_SIZE)
static TextureObject TEXTURE_LIST[MAX_TEXTURE_COUNT];
// Base address in VRAM for textures
static cc_uint8* texmem_base;
// Total number of pages in VRAM
@ -121,7 +126,7 @@ static int texmem_defragment(void) {
int moved_any = false;
for (int i = 0; i < MAX_TEXTURE_COUNT; i++)
{
TextureObject* tex = &TEXTURE_LIST[i];
GPUTexture* tex = &tex_list[i];
if (!tex->data) continue;
int moved = texmem_move(tex->data, tex->size);
@ -208,6 +213,14 @@ static struct CommandsList listTR;
static struct CommandsList* direct = &listPT;
static cc_bool exceeded_vram;
static const cc_bool autosort = false; // Turn off auto sorting to match traditional GPU behaviour
static const cc_bool fsaa = false;
static cc_uint8 gfx_depthTest;
static cc_uint8 gfx_depthWrite;
static cc_uint8 gfx_culling;
static cc_uint8 gfx_scissor;
static CC_INLINE struct CommandsList* ActivePolyList(void) {
if (gfx_alphaBlend) return &listTR;
if (gfx_alphaTest) return &listPT;
@ -218,16 +231,12 @@ static CC_INLINE struct CommandsList* ActivePolyList(void) {
static void no_vram_handler(uint32 code, void *data) { exceeded_vram = true; }
static void InitGPU(void) {
cc_bool autosort = false; // Turn off auto sorting to match traditional GPU behaviour
cc_bool fsaa = false;
AUTOSORT_ENABLED = autosort;
pvr_init_params_t params = {
// Opaque, punch through, translucent polygons with largest bin sizes
{ PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32 },
VERTEX_BUFFER_SIZE,
0, fsaa,
(autosort) ? 0 : 1,
autosort ? 0 : 1,
3 // extra OPBs
};
pvr_init(&params);
@ -243,13 +252,12 @@ static void InitGLState(void) {
PVR_SET(PT_ALPHA_REF, 127); // define missing from KOS
//PVR_SET(PVR_SPANSORT_CFG, 0x0);
ALPHA_TEST_ENABLED = false;
CULLING_ENABLED = false;
BLEND_ENABLED = false;
DEPTH_TEST_ENABLED = false;
DEPTH_MASK_ENABLED = true;
TEXTURES_ENABLED = false;
FOG_ENABLED = false;
gfx_alphaTest = false;
gfx_culling = false;
gfx_alphaBlend = false;
gfx_depthTest = false;
gfx_depthWrite = true;
gfx_fogEnabled = false;
stateDirty = true;
listOP.list_type = PVR_LIST_OP_POLY;
@ -287,18 +295,97 @@ void Gfx_Free(void) {
}
/*########################################################################################################################*
*------------------------------------------------------Polygon state------------------------------------------------------*
*#########################################################################################################################*/
static GPUTexture* tex_active;
static uint32_t SHADE_MODEL = PVR_SHADE_GOURAUD;
static CC_NOINLINE void BuildPolyContext(pvr_poly_hdr_t* dst, int list_type) {
GPUTexture* tex = tex_active;
int gen_culling = gfx_culling ? PVR_CULLING_CW : PVR_CULLING_SMALL;
int depth_comp = gfx_depthTest ? PVR_DEPTHCMP_GEQUAL : PVR_DEPTHCMP_ALWAYS;
int depth_write = gfx_depthWrite ? PVR_DEPTHWRITE_ENABLE : PVR_DEPTHWRITE_DISABLE;
int clip_mode = gfx_scissor ? PVR_USERCLIP_INSIDE : PVR_USERCLIP_DISABLE;
int fog_type = gfx_fogEnabled ? PVR_FOG_TABLE : PVR_FOG_DISABLE;
int use_alpha = gfx_alphaBlend || gfx_alphaTest;
int gen_alpha = use_alpha ? PVR_ALPHA_ENABLE : PVR_ALPHA_DISABLE;
int blend_src = PVR_BLEND_SRCALPHA;
int blend_dst = PVR_BLEND_INVSRCALPHA;
if (list_type == PVR_LIST_OP_POLY) {
// Opaque polygons require src=one dst=zero blend mode
blend_src = PVR_BLEND_ONE;
blend_dst = PVR_BLEND_ZERO;
} else if (list_type == PVR_LIST_PT_POLY) {
// Punch-through polygons require <= depth mode
depth_comp = PVR_DEPTHCMP_LEQUAL;
} else if (list_type == PVR_LIST_TR_POLY && autosort) {
// Autosort requires >= depth mode for translucent polygons
depth_comp = PVR_DEPTHCMP_GEQUAL;
}
int tex_enable;
if (tex && gfx_format == VERTEX_FORMAT_TEXTURED) {
tex_enable = PVR_TEXTURE_ENABLE;
} else {
tex_enable = PVR_TEXTURE_DISABLE;
}
dst->cmd = PVR_CMD_POLYHDR | (tex_enable << 3);
// Force bits 18 and 19 on to switch to 6 triangle strips
dst->cmd |= 0xC0000;
dst->cmd |= (list_type << PVR_TA_CMD_TYPE_SHIFT) & PVR_TA_CMD_TYPE_MASK;
dst->cmd |= (PVR_CLRFMT_ARGBPACKED << PVR_TA_CMD_CLRFMT_SHIFT) & PVR_TA_CMD_CLRFMT_MASK;
dst->cmd |= (SHADE_MODEL << PVR_TA_CMD_SHADE_SHIFT) & PVR_TA_CMD_SHADE_MASK;
dst->cmd |= (PVR_UVFMT_32BIT << PVR_TA_CMD_UVFMT_SHIFT) & PVR_TA_CMD_UVFMT_MASK;
dst->cmd |= (clip_mode << PVR_TA_CMD_USERCLIP_SHIFT) & PVR_TA_CMD_USERCLIP_MASK;
dst->mode1 = (depth_comp << PVR_TA_PM1_DEPTHCMP_SHIFT) & PVR_TA_PM1_DEPTHCMP_MASK;
dst->mode1 |= (gen_culling << PVR_TA_PM1_CULLING_SHIFT) & PVR_TA_PM1_CULLING_MASK;
dst->mode1 |= (depth_write << PVR_TA_PM1_DEPTHWRITE_SHIFT) & PVR_TA_PM1_DEPTHWRITE_MASK;
dst->mode1 |= (tex_enable << PVR_TA_PM1_TXRENABLE_SHIFT) & PVR_TA_PM1_TXRENABLE_MASK;
dst->mode2 = (blend_src << PVR_TA_PM2_SRCBLEND_SHIFT) & PVR_TA_PM2_SRCBLEND_MASK;
dst->mode2 |= (blend_dst << PVR_TA_PM2_DSTBLEND_SHIFT) & PVR_TA_PM2_DSTBLEND_MASK;
dst->mode2 |= (fog_type << PVR_TA_PM2_FOG_SHIFT) & PVR_TA_PM2_FOG_MASK;
dst->mode2 |= (gen_alpha << PVR_TA_PM2_ALPHA_SHIFT) & PVR_TA_PM2_ALPHA_MASK;
if (tex_enable == PVR_TEXTURE_DISABLE) {
dst->mode3 = 0;
return;
}
int tex_alpha = use_alpha ? PVR_TXRALPHA_ENABLE : PVR_TXRALPHA_DISABLE;
dst->mode2 |= (tex_alpha << PVR_TA_PM2_TXRALPHA_SHIFT) & PVR_TA_PM2_TXRALPHA_MASK;
dst->mode2 |= (PVR_FILTER_NEAREST << PVR_TA_PM2_FILTER_SHIFT) & PVR_TA_PM2_FILTER_MASK;
dst->mode2 |= (PVR_MIPBIAS_NORMAL << PVR_TA_PM2_MIPBIAS_SHIFT) & PVR_TA_PM2_MIPBIAS_MASK;
dst->mode2 |= (PVR_TXRENV_MODULATEALPHA << PVR_TA_PM2_TXRENV_SHIFT) & PVR_TA_PM2_TXRENV_MASK;
dst->mode2 |= ((tex->log2_w - 3) << PVR_TA_PM2_USIZE_SHIFT) & PVR_TA_PM2_USIZE_MASK;
dst->mode2 |= ((tex->log2_h - 3) << PVR_TA_PM2_VSIZE_SHIFT) & PVR_TA_PM2_VSIZE_MASK;
dst->mode3 = (0 << PVR_TA_PM3_MIPMAP_SHIFT) & PVR_TA_PM3_MIPMAP_MASK;
dst->mode3 |= (tex->format << PVR_TA_PM3_TXRFMT_SHIFT) & PVR_TA_PM3_TXRFMT_MASK;
dst->mode3 |= ((uint32_t)tex->data & 0x00fffff8) >> 3;
}
/*########################################################################################################################*
*-----------------------------------------------------State management----------------------------------------------------*
*#########################################################################################################################*/
static PackedCol gfx_clearColor;
void Gfx_SetFaceCulling(cc_bool enabled) {
CULLING_ENABLED = enabled;
gfx_culling = enabled;
stateDirty = true;
}
static void SetAlphaBlend(cc_bool enabled) {
BLEND_ENABLED = enabled;
stateDirty = true;
}
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
@ -318,21 +405,20 @@ static void SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a) {
}
void Gfx_SetDepthWrite(cc_bool enabled) {
if (DEPTH_MASK_ENABLED == enabled) return;
if (gfx_depthWrite == enabled) return;
DEPTH_MASK_ENABLED = enabled;
gfx_depthWrite = enabled;
stateDirty = true;
}
void Gfx_SetDepthTest(cc_bool enabled) {
if (DEPTH_TEST_ENABLED == enabled) return;
if (gfx_depthTest == enabled) return;
DEPTH_TEST_ENABLED = enabled;
gfx_depthTest = enabled;
stateDirty = true;
}
static void SetAlphaTest(cc_bool enabled) {
ALPHA_TEST_ENABLED = enabled;
stateDirty = true;
}
@ -566,13 +652,13 @@ void Gfx_DisableMipmaps(void) { }
// idx - mask = idx + one
static CC_INLINE void TwiddleCalcFactors(unsigned w, unsigned h,
unsigned* maskX, unsigned* maskY) {
w = Math_NextPowOf2(w);
h = Math_NextPowOf2(h);
*maskX = 0;
*maskY = 0;
int shift = 0;
w = Math_NextPowOf2(w);
h = Math_NextPowOf2(h);
for (; w > 1 || h > 1; w >>= 1, h >>= 1)
{
if (w > 1 && h > 1) {
@ -593,7 +679,6 @@ static CC_INLINE void TwiddleCalcFactors(unsigned w, unsigned h,
}
// B8 G8 R8 A8 > B4 G4 R4 A4
#define BGRA8_to_BGRA4(src) \
((src[0] & 0xF0) >> 4) | (src[1] & 0xF0) | ((src[2] & 0xF0) << 4) | ((src[3] & 0xF0) << 8);
@ -645,10 +730,10 @@ static CC_INLINE void ConvertTexture_Palette(cc_uint16* dst, struct Bitmap* bmp,
}
}
static TextureObject* FindFreeTexture(void) {
static GPUTexture* FindFreeTexture(void) {
for (int i = 0; i < MAX_TEXTURE_COUNT; i++)
{
TextureObject* tex = &TEXTURE_LIST[i];
GPUTexture* tex = &tex_list[i];
if (!tex->data) return tex;
}
return NULL;
@ -657,7 +742,7 @@ static TextureObject* FindFreeTexture(void) {
static int Log2Dimension(int len) { return Math_ilog2(Math_NextPowOf2(len)); }
GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
TextureObject* tex = FindFreeTexture();
GPUTexture* tex = FindFreeTexture();
if (!tex) return NULL;
BitmapCol palette[MAX_PAL_ENTRIES];
@ -669,8 +754,8 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
if (pal_count > 0) ApplyPalette(palette, pal_count, pal_index);
}
tex->log2_width = Log2Dimension(bmp->width);
tex->log2_height = Log2Dimension(bmp->height);
tex->log2_w = Log2Dimension(bmp->width);
tex->log2_h = Log2Dimension(bmp->height);
if (pal_count > 0) {
tex->format = PVR_TXRFMT_PAL4BPP | PVR_TXRFMT_4BPP_PAL(pal_index);
@ -694,16 +779,17 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
}
void Gfx_UpdateTexture(GfxResourceID texId, int originX, int originY, struct Bitmap* part, int rowWidth, cc_bool mipmaps) {
TextureObject* tex = (TextureObject*)texId;
GPUTexture* tex = (GPUTexture*)texId;
int width = part->width, height = part->height;
unsigned maskX, maskY;
unsigned X = 0, Y = 0;
TwiddleCalcFactors(1 << tex->log2_width, 1 << tex->log2_height, &maskX, &maskY);
TwiddleCalcFactors(1 << tex->log2_w, 1 << tex->log2_h, &maskX, &maskY);
// Calculate start twiddled X and Y values
for (int x = 0; x < originX; x++) { X = (X - maskX) & maskX; }
for (int y = 0; y < originY; y++) { Y = (Y - maskY) & maskY; }
unsigned startX = X;
cc_uint16* dst = tex->data;
@ -723,12 +809,12 @@ void Gfx_UpdateTexture(GfxResourceID texId, int originX, int originY, struct Bit
}
void Gfx_BindTexture(GfxResourceID texId) {
TEXTURE_ACTIVE = (TextureObject*)texId;
tex_active = (GPUTexture*)texId;
stateDirty = true;
}
void Gfx_DeleteTexture(GfxResourceID* texId) {
TextureObject* tex = (TextureObject*)(*texId);
GPUTexture* tex = (GPUTexture*)(*texId);
if (!tex) return;
texmem_free(tex->data, tex->size);
@ -743,7 +829,6 @@ void Gfx_DeleteTexture(GfxResourceID* texId) {
}
/*########################################################################################################################*
*-----------------------------------------------------State management----------------------------------------------------*
*#########################################################################################################################*/
@ -752,10 +837,9 @@ static float gfx_fogEnd = 16.0f, gfx_fogDensity = 1.0f;
static FogFunc gfx_fogMode = -1;
void Gfx_SetFog(cc_bool enabled) {
gfx_fogEnabled = enabled;
if (FOG_ENABLED == enabled) return;
if (gfx_fogEnabled == enabled) return;
FOG_ENABLED = enabled;
gfx_fogEnabled = enabled;
stateDirty = true;
}
@ -901,14 +985,14 @@ void DrawQuads(int count, void* src) {
if (!beg) return;
if (header_required) {
apply_poly_header((pvr_poly_hdr_t*)beg, list->list_type);
BuildPolyContext((pvr_poly_hdr_t*)beg, list->list_type);
stateDirty = false;
list->length++;
beg++;
}
Vertex* end;
if (TEXTURES_ENABLED) {
if (gfx_format == VERTEX_FORMAT_TEXTURED) {
end = DrawTexturedQuads(src, beg, count >> 2);
} else {
end = DrawColouredQuads(src, beg, count >> 2);
@ -924,8 +1008,6 @@ void Gfx_SetVertexFormat(VertexFormat fmt) {
if (fmt == gfx_format) return;
gfx_format = fmt;
gfx_stride = strideSizes[fmt];
TEXTURES_ENABLED = fmt == VERTEX_FORMAT_TEXTURED;
stateDirty = true;
}
@ -975,7 +1057,6 @@ void Gfx_GetApiInfo(cc_string* info) {
String_AppendConst(info, "-- Using Dreamcast --\n");
String_AppendConst(info, "GPU: PowerVR2 CLX2 100mHz\n");
String_AppendConst(info, "T&L: GLdc library (KallistiOS / Kazade)\n");
String_Format2(info, "Texture memory: %f2 MB used, %f2 MB free\n", &usedMemMB, &freeMemMB);
PrintMaxTextureInfo(info);
}
@ -1048,7 +1129,7 @@ void Gfx_SetViewport(int x, int y, int w, int h) {
}
void Gfx_SetScissor(int x, int y, int w, int h) {
SCISSOR_TEST_ENABLED = x != 0 || y != 0 || w != Game.Width || h != Game.Height;
gfx_scissor = x != 0 || y != 0 || w != Game.Width || h != Game.Height;
stateDirty = true;
struct pvr_clip_command {
@ -1069,4 +1150,4 @@ void Gfx_SetScissor(int x, int y, int w, int h) {
CommandsList_Append(&listPT, &c);
CommandsList_Append(&listTR, &c);
}
#endif

View File

@ -1,15 +1,12 @@
#include "Core.h"
#if defined CC_BUILD_DREAMCAST
#define CC_XTEA_ENCRYPTION
#include "_PlatformBase.h"
#include "Stream.h"
#include "ExtMath.h"
#include "Funcs.h"
#include "Window.h"
#include "Utils.h"
#include "Errors.h"
#include "SystemFonts.h"
#include "../_PlatformBase.h"
#include "../Stream.h"
#include "../ExtMath.h"
#include "../Funcs.h"
#include "../Window.h"
#include "../Utils.h"
#include "../Errors.h"
#include "../SystemFonts.h"
#include <errno.h>
#include <netdb.h>
@ -25,7 +22,7 @@
#include <dc/sd.h>
#include <fat/fs_fat.h>
#include <kos/dbgio.h>
#include "_PlatformConsole.h"
#include "../_PlatformConsole.h"
KOS_INIT_FLAGS(INIT_CONTROLLER | INIT_KEYBOARD | INIT_MOUSE |
INIT_VMU | INIT_CDROM | INIT_NET);
@ -741,5 +738,4 @@ static cc_result GetMachineID(cc_uint32* key) {
Mem_Copy(key, MACHINE_KEY, sizeof(MACHINE_KEY) - 1);
return 0;
}
#endif

View File

@ -1,6 +1,13 @@
#include <kos.h>
#include <dc/pvr.h>
#include "gldc.h"
typedef struct {
// Same layout as a PVR vertex
uint32_t flags;
float x, y, w;
uint32_t u, v; // really floats, but stored as uint for better load/store codegen
uint32_t bgra;
float z; // actually oargb, but repurposed since unused
} __attribute__ ((aligned (32))) Vertex;
void CC_NOINLINE SubmitCommands(Vertex* v3, int n);
#define PushVertex(src, dst) __asm__ volatile ( \
"fmov.d @%1+, dr0 ! LS, FX = *src, src += 8\n" \
@ -73,9 +80,9 @@ void SubmitCommands(Vertex* v3, int n) {
};
// Quads [0, 1, 2, 3] -> Triangles [{0, 1, 2} {2, 3, 0}]
Vertex* const v0 = v3 - 3;
Vertex* const v1 = v3 - 2;
Vertex* const v2 = v3 - 1;
Vertex* v0 = v3 - 3;
Vertex* v1 = v3 - 2;
Vertex* v2 = v3 - 1;
uint8_t mask = v3->flags & 0xFF;
// Check if all vertices visible

View File

@ -1,20 +1,18 @@
#include "Core.h"
#if defined CC_BUILD_DREAMCAST
#include "Window.h"
#include "Platform.h"
#include "Input.h"
#include "Event.h"
#include "Graphics.h"
#include "String.h"
#include "Funcs.h"
#include "Bitmap.h"
#include "Errors.h"
#include "ExtMath.h"
#include "VirtualKeyboard.h"
#include "../Window.h"
#include "../Platform.h"
#include "../Input.h"
#include "../Event.h"
#include "../Graphics.h"
#include "../String.h"
#include "../Funcs.h"
#include "../Bitmap.h"
#include "../Errors.h"
#include "../ExtMath.h"
#include "../VirtualKeyboard.h"
#include <kos.h>
static cc_bool launcherMode;
#include "VirtualCursor.h"
#include "../VirtualCursor.h"
cc_bool window_inited;
struct _DisplayData DisplayInfo;
@ -363,4 +361,3 @@ cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {
cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* args) {
return ERR_NOT_SUPPORTED;
}
#endif

View File

@ -139,8 +139,8 @@ void Gfx_FreeState(void) { }
/*########################################################################################################################*
*---------------------------------------------------------Texturing-------------------------------------------------------*
*#########################################################################################################################*/
typedef struct CCTexture_ {
cc_uint32 width, height;
typedef struct {
cc_uint8 log2_w, log2_h;
cc_uint32* pixels;
} CCTexture;
@ -171,13 +171,15 @@ static CC_INLINE void TwiddleCalcFactors(unsigned w, unsigned h,
}
}
static int Log2Dimension(int len) { return Math_ilog2(Math_NextPowOf2(len)); }
GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
int size = bmp->width * bmp->height * 4;
CCTexture* tex = Mem_Alloc(1, sizeof(CCTexture), "GPU texture");
tex->pixels = MmAllocateContiguousMemoryEx(size, 0, MAX_RAM_ADDR, 0, PAGE_WRITECOMBINE | PAGE_READWRITE);
tex->width = bmp->width;
tex->height = bmp->height;
tex->log2_w = Log2Dimension(bmp->width);
tex->log2_h = Log2Dimension(bmp->height);
cc_uint32* dst = tex->pixels;
int width = bmp->width, height = bmp->height;
@ -207,7 +209,7 @@ void Gfx_UpdateTexture(GfxResourceID texId, int originX, int originY, struct Bit
int width = part->width, height = part->height;
unsigned maskX, maskY;
unsigned X = 0, Y = 0;
TwiddleCalcFactors(tex->width, tex->height, &maskX, &maskY);
TwiddleCalcFactors(1 << tex->log2_w, 1 << tex->log2_h, &maskX, &maskY);
// Calculate start twiddled X and Y values
for (int x = 0; x < originX; x++) { X = (X - maskX) & maskX; }
@ -244,8 +246,8 @@ void Gfx_BindTexture(GfxResourceID texId) {
CCTexture* tex = (CCTexture*)texId;
if (!tex) tex = white_square;
unsigned log_u = Math_ilog2(tex->width);
unsigned log_v = Math_ilog2(tex->height);
unsigned log_u = tex->log2_w;
unsigned log_v = tex->log2_h;
uint32_t* p;
p = pb_begin();

View File

@ -1,25 +0,0 @@
BSD 2-Clause License
Copyright (c) 2018, Luke Benstead
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,27 +0,0 @@
#ifndef PRIVATE_H
#define PRIVATE_H
#include <stdint.h>
#define GLDC_FORCE_INLINE __attribute__((always_inline)) inline
#define GLDC_NO_INLINE __attribute__((noinline))
typedef struct {
/* Same 32 byte layout as pvr_vertex_t */
uint32_t flags;
float x, y, w;
uint32_t u, v; // really floats, but stored as uint for better load/store codegen
uint32_t bgra;
float z; // actually oargb, but repurposed since unused
} __attribute__ ((aligned (32))) Vertex;
typedef struct {
uint32_t format;
void *data;
uint32_t log2_width: 4;
uint32_t log2_height: 4;
uint32_t size: 24;
} TextureObject;
void GLDC_NO_INLINE SubmitCommands(Vertex* v3, int n);
#endif // PRIVATE_H

View File

@ -1,95 +0,0 @@
#include <dc/pvr.h>
#include "gldc.h"
static TextureObject* TEXTURE_ACTIVE;
static uint8_t DEPTH_TEST_ENABLED;
static uint8_t DEPTH_MASK_ENABLED;
static uint8_t CULLING_ENABLED;
static uint8_t FOG_ENABLED;
static uint8_t ALPHA_TEST_ENABLED;
static uint8_t SCISSOR_TEST_ENABLED;
static uint32_t SHADE_MODEL = PVR_SHADE_GOURAUD;
static uint8_t BLEND_ENABLED;
static uint8_t TEXTURES_ENABLED;
static uint8_t AUTOSORT_ENABLED;
static GLDC_NO_INLINE void apply_poly_header(pvr_poly_hdr_t* dst, int list_type) {
TextureObject* tx1 = TEXTURE_ACTIVE;
int gen_culling = CULLING_ENABLED ? PVR_CULLING_CW : PVR_CULLING_SMALL;
int depth_comp = DEPTH_TEST_ENABLED ? PVR_DEPTHCMP_GEQUAL : PVR_DEPTHCMP_ALWAYS;
int depth_write = DEPTH_MASK_ENABLED ? PVR_DEPTHWRITE_ENABLE : PVR_DEPTHWRITE_DISABLE;
int clip_mode = SCISSOR_TEST_ENABLED ? PVR_USERCLIP_INSIDE : PVR_USERCLIP_DISABLE;
int fog_type = FOG_ENABLED ? PVR_FOG_TABLE : PVR_FOG_DISABLE;
int gen_alpha = (BLEND_ENABLED || ALPHA_TEST_ENABLED) ? PVR_ALPHA_ENABLE : PVR_ALPHA_DISABLE;
int blend_src = PVR_BLEND_SRCALPHA;
int blend_dst = PVR_BLEND_INVSRCALPHA;
if (list_type == PVR_LIST_OP_POLY) {
/* Opaque polys are always one/zero */
blend_src = PVR_BLEND_ONE;
blend_dst = PVR_BLEND_ZERO;
} else if (list_type == PVR_LIST_PT_POLY) {
/* Punch-through polys require fixed blending and depth modes */
depth_comp = PVR_DEPTHCMP_LEQUAL;
} else if (list_type == PVR_LIST_TR_POLY && AUTOSORT_ENABLED) {
/* Autosort mode requires this mode for transparent polys */
depth_comp = PVR_DEPTHCMP_GEQUAL;
}
int txr_enable, txr_alpha;
if (!TEXTURES_ENABLED || !tx1) {
/* Disable all texturing to start with */
txr_enable = PVR_TEXTURE_DISABLE;
} else {
txr_alpha = (BLEND_ENABLED || ALPHA_TEST_ENABLED) ? PVR_TXRALPHA_ENABLE : PVR_TXRALPHA_DISABLE;
txr_enable = PVR_TEXTURE_ENABLE;
}
/* The base values for CMD */
dst->cmd = PVR_CMD_POLYHDR;
dst->cmd |= txr_enable << 3;
/* Force bits 18 and 19 on to switch to 6 triangle strips */
dst->cmd |= 0xC0000;
/* Or in the list type, shading type, color and UV formats */
dst->cmd |= (list_type << PVR_TA_CMD_TYPE_SHIFT) & PVR_TA_CMD_TYPE_MASK;
dst->cmd |= (PVR_CLRFMT_ARGBPACKED << PVR_TA_CMD_CLRFMT_SHIFT) & PVR_TA_CMD_CLRFMT_MASK;
dst->cmd |= (SHADE_MODEL << PVR_TA_CMD_SHADE_SHIFT) & PVR_TA_CMD_SHADE_MASK;
dst->cmd |= (PVR_UVFMT_32BIT << PVR_TA_CMD_UVFMT_SHIFT) & PVR_TA_CMD_UVFMT_MASK;
dst->cmd |= (clip_mode << PVR_TA_CMD_USERCLIP_SHIFT) & PVR_TA_CMD_USERCLIP_MASK;
dst->mode1 = (depth_comp << PVR_TA_PM1_DEPTHCMP_SHIFT) & PVR_TA_PM1_DEPTHCMP_MASK;
dst->mode1 |= (gen_culling << PVR_TA_PM1_CULLING_SHIFT) & PVR_TA_PM1_CULLING_MASK;
dst->mode1 |= (depth_write << PVR_TA_PM1_DEPTHWRITE_SHIFT) & PVR_TA_PM1_DEPTHWRITE_MASK;
dst->mode1 |= (txr_enable << PVR_TA_PM1_TXRENABLE_SHIFT) & PVR_TA_PM1_TXRENABLE_MASK;
dst->mode2 = (blend_src << PVR_TA_PM2_SRCBLEND_SHIFT) & PVR_TA_PM2_SRCBLEND_MASK;
dst->mode2 |= (blend_dst << PVR_TA_PM2_DSTBLEND_SHIFT) & PVR_TA_PM2_DSTBLEND_MASK;
dst->mode2 |= (fog_type << PVR_TA_PM2_FOG_SHIFT) & PVR_TA_PM2_FOG_MASK;
dst->mode2 |= (gen_alpha << PVR_TA_PM2_ALPHA_SHIFT) & PVR_TA_PM2_ALPHA_MASK;
if (txr_enable == PVR_TEXTURE_DISABLE) {
dst->mode3 = 0;
} else {
dst->mode2 |= (txr_alpha << PVR_TA_PM2_TXRALPHA_SHIFT) & PVR_TA_PM2_TXRALPHA_MASK;
dst->mode2 |= (PVR_FILTER_NEAREST << PVR_TA_PM2_FILTER_SHIFT) & PVR_TA_PM2_FILTER_MASK;
dst->mode2 |= (PVR_MIPBIAS_NORMAL << PVR_TA_PM2_MIPBIAS_SHIFT) & PVR_TA_PM2_MIPBIAS_MASK;
dst->mode2 |= (PVR_TXRENV_MODULATEALPHA << PVR_TA_PM2_TXRENV_SHIFT) & PVR_TA_PM2_TXRENV_MASK;
dst->mode2 |= ((tx1->log2_width - 3) << PVR_TA_PM2_USIZE_SHIFT) & PVR_TA_PM2_USIZE_MASK;
dst->mode2 |= ((tx1->log2_height - 3) << PVR_TA_PM2_VSIZE_SHIFT) & PVR_TA_PM2_VSIZE_MASK;
dst->mode3 = (0 << PVR_TA_PM3_MIPMAP_SHIFT) & PVR_TA_PM3_MIPMAP_MASK;
dst->mode3 |= (tx1->format << PVR_TA_PM3_TXRFMT_SHIFT) & PVR_TA_PM3_TXRFMT_MASK;
dst->mode3 |= ((uint32_t)tx1->data & 0x00fffff8) >> 3;
}
}