mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-07 22:34:43 -04:00
N64: WIP on in-place vertex list
This commit is contained in:
parent
6658154f2d
commit
21b4fe79aa
@ -144,38 +144,87 @@ static inline void put_word(rspq_write_t* s, uint16_t v1, uint16_t v2)
|
|||||||
rspq_write_arg(s, v2 | (v1 << 16));
|
rspq_write_arg(s, v2 | (v1 << 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void upload_vertex(rspq_write_t* s, uint32_t index)
|
|
||||||
{
|
|
||||||
char* ptr = gpu_pointer + index * gpu_stride;
|
|
||||||
|
|
||||||
float* vtx = (float*)(ptr + 0);
|
|
||||||
put_word(s, vtx[0] * (1<<VTX_SHIFT),
|
|
||||||
vtx[1] * (1<<VTX_SHIFT));
|
|
||||||
put_word(s, vtx[2] * (1<<VTX_SHIFT),
|
|
||||||
1.0f * (1<<VTX_SHIFT));
|
|
||||||
|
|
||||||
uint32_t* col = (uint32_t*)(ptr + 12);
|
|
||||||
rspq_write_arg(s, *col);
|
|
||||||
|
|
||||||
if (gpu_texturing) {
|
struct rsp_vertex {
|
||||||
float* tex = (float*)(ptr + 16);
|
uint16_t x, y;
|
||||||
put_word(s, tex[0] * (1<<TEX_SHIFT),
|
uint16_t z, w; // w ignored
|
||||||
tex[1] * (1<<TEX_SHIFT));
|
uint32_t rgba;
|
||||||
} else {
|
uint16_t u, v;
|
||||||
put_word(s, 0,
|
};
|
||||||
0);
|
|
||||||
}
|
#define FLT_EXPONENT_BIAS 127
|
||||||
|
#define FLT_EXPONENT_SHIFT 23
|
||||||
|
#define FLT_EXPONENT_MASK 0x7F800000
|
||||||
|
|
||||||
|
static int F2I(float value, int scale) {
|
||||||
|
union IntAndFloat raw;
|
||||||
|
int e;
|
||||||
|
raw.f = value;
|
||||||
|
|
||||||
|
e = (raw.i & FLT_EXPONENT_MASK) >> FLT_EXPONENT_SHIFT;
|
||||||
|
|
||||||
|
// Ignore denormal, infinity, or large exponents
|
||||||
|
if (e <= 0 || e >= 160) return 0;
|
||||||
|
|
||||||
|
return value * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void convert_textured_vertices(GfxResourceID vb, int count) {
|
||||||
|
struct VertexTextured* src = (struct VertexTextured*)vb;
|
||||||
|
struct rsp_vertex* dst = (struct rsp_vertex*)vb;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++, src++, dst++)
|
||||||
|
{
|
||||||
|
float x = src->x, y = src->y, z = src->z;
|
||||||
|
float u = src->U, v = src->V;
|
||||||
|
PackedCol rgba = src->Col;
|
||||||
|
|
||||||
|
dst->x = F2I(x, 1<<VTX_SHIFT);
|
||||||
|
dst->y = F2I(y, 1<<VTX_SHIFT);
|
||||||
|
dst->z = F2I(z, 1<<VTX_SHIFT);
|
||||||
|
|
||||||
|
dst->u = F2I(u, 1<<TEX_SHIFT);
|
||||||
|
dst->v = F2I(v, 1<<TEX_SHIFT);
|
||||||
|
dst->rgba = rgba;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void convert_coloured_vertices(GfxResourceID vb, int count) {
|
||||||
|
struct VertexColoured* src = (struct VertexColoured*)vb;
|
||||||
|
struct rsp_vertex* dst = (struct rsp_vertex*)vb;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++, src++, dst++)
|
||||||
|
{
|
||||||
|
float x = src->x, y = src->y, z = src->z;
|
||||||
|
PackedCol rgba = src->Col;
|
||||||
|
|
||||||
|
dst->x = F2I(x, 1<<VTX_SHIFT);
|
||||||
|
dst->y = F2I(y, 1<<VTX_SHIFT);
|
||||||
|
dst->z = F2I(z, 1<<VTX_SHIFT);
|
||||||
|
|
||||||
|
dst->u = 0;
|
||||||
|
dst->v = 0;
|
||||||
|
dst->rgba = rgba;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void gpuDrawArrays(uint32_t first, uint32_t count)
|
static void gpuDrawArrays(uint32_t first, uint32_t count)
|
||||||
{
|
{
|
||||||
|
uint32_t* ptr = (uint32_t*)(gpu_pointer + first * sizeof(struct rsp_vertex));
|
||||||
for (uint32_t i = 0; i < count; i += 4)
|
for (uint32_t i = 0; i < count; i += 4)
|
||||||
{
|
{
|
||||||
rspq_write_t s = rspq_write_begin(gpup_id, GPU_CMD_DRAW_QUAD, 17);
|
rspq_write_t s = rspq_write_begin(gpup_id, GPU_CMD_DRAW_QUAD, 17);
|
||||||
rspq_write_arg(&s, 0); // padding
|
rspq_write_arg(&s, 0); // padding
|
||||||
|
|
||||||
for (uint32_t j = 0; j < 4; j++)
|
for (uint32_t j = 0; j < 4; j++)
|
||||||
{
|
{
|
||||||
upload_vertex(&s, first + i + j);
|
rspq_write_arg(&s, *ptr++);
|
||||||
|
rspq_write_arg(&s, *ptr++);
|
||||||
|
rspq_write_arg(&s, *ptr++);
|
||||||
|
rspq_write_arg(&s, *ptr++);
|
||||||
}
|
}
|
||||||
rspq_write_end(&s);
|
rspq_write_end(&s);
|
||||||
}
|
}
|
||||||
|
@ -123,9 +123,8 @@ GPUCmd_PushRDP:
|
|||||||
|
|
||||||
.func GPUCmd_MatrixLoad
|
.func GPUCmd_MatrixLoad
|
||||||
GPUCmd_MatrixLoad:
|
GPUCmd_MatrixLoad:
|
||||||
#define src s6
|
#define src t0
|
||||||
#define dst s7
|
#define dst t1
|
||||||
|
|
||||||
#define vmat0_i $v02
|
#define vmat0_i $v02
|
||||||
#define vmat1_i $v03
|
#define vmat1_i $v03
|
||||||
#define vmat2_i $v04
|
#define vmat2_i $v04
|
||||||
@ -239,14 +238,14 @@ GL_CalcScreenSpace:
|
|||||||
# GL_TnL
|
# GL_TnL
|
||||||
#
|
#
|
||||||
# Args:
|
# Args:
|
||||||
# s2 = address of the vertex in DMEM (usually within VERTEX_CACHE)
|
# a1 = address of the vertex in DMEM (usually within VERTEX_CACHE)
|
||||||
# s3 = address of the vertex in DMEM (usually within VERTEX_CACHE)
|
# a2 = address of the vertex in DMEM (usually within VERTEX_CACHE)
|
||||||
#
|
#
|
||||||
################################################################
|
################################################################
|
||||||
.func GL_TnL
|
.func GL_TnL
|
||||||
GL_TnL:
|
GL_TnL:
|
||||||
#define vtx1 s2
|
#define vtx1 a1
|
||||||
#define vtx2 s3
|
#define vtx2 a2
|
||||||
#define w e3
|
#define w e3
|
||||||
#define W e7
|
#define W e7
|
||||||
|
|
||||||
@ -335,10 +334,6 @@ GL_TnL:
|
|||||||
.align 3
|
.align 3
|
||||||
.func GPUCmd_DrawQuad
|
.func GPUCmd_DrawQuad
|
||||||
GPUCmd_DrawQuad:
|
GPUCmd_DrawQuad:
|
||||||
#define vtx_ptr a0
|
|
||||||
#define mtx_ptr s0
|
|
||||||
#define src_ptr s4
|
|
||||||
|
|
||||||
#define v___ $v01
|
#define v___ $v01
|
||||||
|
|
||||||
#define vst_i $v12
|
#define vst_i $v12
|
||||||
@ -366,7 +361,9 @@ GPUCmd_DrawQuad:
|
|||||||
#define v1_cflags t2
|
#define v1_cflags t2
|
||||||
#define v2_cflags t3
|
#define v2_cflags t3
|
||||||
#define v3_cflags t4
|
#define v3_cflags t4
|
||||||
// t5 is used by GL_ClipTriangle
|
#define mtx_ptr t5 // t5 is also used by GL_ClipTriangle
|
||||||
|
#define vtx_ptr t6
|
||||||
|
#define src_ptr t7
|
||||||
|
|
||||||
addi src_ptr, rspq_dmem_buf_ptr, %lo(RSPQ_DMEM_BUFFER) - 64
|
addi src_ptr, rspq_dmem_buf_ptr, %lo(RSPQ_DMEM_BUFFER) - 64
|
||||||
li vtx_ptr, %lo(VERTEX_CACHE)
|
li vtx_ptr, %lo(VERTEX_CACHE)
|
||||||
@ -383,6 +380,7 @@ GPUCmd_DrawQuad:
|
|||||||
lqv vmtx1_f, 0x50,mtx_ptr
|
lqv vmtx1_f, 0x50,mtx_ptr
|
||||||
lqv vmtx2_f, 0x60,mtx_ptr
|
lqv vmtx2_f, 0x60,mtx_ptr
|
||||||
lqv vmtx3_f, 0x70,mtx_ptr
|
lqv vmtx3_f, 0x70,mtx_ptr
|
||||||
|
#undef mtx_ptr
|
||||||
|
|
||||||
// ########################
|
// ########################
|
||||||
// Vertex 0 and 1 transform
|
// Vertex 0 and 1 transform
|
||||||
@ -407,10 +405,10 @@ GPUCmd_DrawQuad:
|
|||||||
vmudm vcspos_i, vcspos_i, K2048
|
vmudm vcspos_i, vcspos_i, K2048
|
||||||
vmadl vcspos_f, vcspos_f, K2048
|
vmadl vcspos_f, vcspos_f, K2048
|
||||||
|
|
||||||
li t6, %lo(GL_STATE_TEX_SIZE)
|
li tmp, %lo(GL_STATE_TEX_SIZE)
|
||||||
lqv vtexsize, 0x00, t6
|
lqv vtexsize, 0x00, tmp
|
||||||
slv vcol.e0, SCREEN_VTX_RGBA + V0_OFFSET, vtx_ptr
|
slv vcol.e0, SCREEN_VTX_RGBA + V0_OFFSET, vtx_ptr
|
||||||
lqv vtexoffset, 0x10, t6
|
lqv vtexoffset, 0x10, tmp
|
||||||
slv vcol.e2, SCREEN_VTX_RGBA + V1_OFFSET, vtx_ptr
|
slv vcol.e2, SCREEN_VTX_RGBA + V1_OFFSET, vtx_ptr
|
||||||
|
|
||||||
// Calculate and store clipping flags against CS.W.
|
// Calculate and store clipping flags against CS.W.
|
||||||
@ -529,13 +527,13 @@ GPUCmd_DrawQuad:
|
|||||||
ldv vguardscale.e0, 0, t0
|
ldv vguardscale.e0, 0, t0
|
||||||
ldv vguardscale.e4, 0, t0
|
ldv vguardscale.e4, 0, t0
|
||||||
|
|
||||||
li s2, %lo(VERTEX_CACHE) + V0_OFFSET
|
li a1, %lo(VERTEX_CACHE) + V0_OFFSET
|
||||||
jal GL_TnL
|
jal GL_TnL
|
||||||
li s3, %lo(VERTEX_CACHE) + V1_OFFSET
|
li a2, %lo(VERTEX_CACHE) + V1_OFFSET
|
||||||
|
|
||||||
li s2, %lo(VERTEX_CACHE) + V2_OFFSET
|
li a1, %lo(VERTEX_CACHE) + V2_OFFSET
|
||||||
jal GL_TnL
|
jal GL_TnL
|
||||||
li s3, %lo(VERTEX_CACHE) + V3_OFFSET
|
li a2, %lo(VERTEX_CACHE) + V3_OFFSET
|
||||||
|
|
||||||
// ########################
|
// ########################
|
||||||
// Guardband check
|
// Guardband check
|
||||||
@ -586,6 +584,7 @@ gl_draw_clipped_triangles_loop:
|
|||||||
move vtx1, s5
|
move vtx1, s5
|
||||||
lhu vtx2, 2(s1)
|
lhu vtx2, 2(s1)
|
||||||
lhu vtx3, 4(s1)
|
lhu vtx3, 4(s1)
|
||||||
|
# TODO do VP transform here
|
||||||
|
|
||||||
gl_draw_single_triangle:
|
gl_draw_single_triangle:
|
||||||
addi vtx1, SCREEN_VTX_X
|
addi vtx1, SCREEN_VTX_X
|
||||||
|
@ -18,6 +18,7 @@ CACHE_OFFSETS: .half 2,4,6,8, 10,12,14,16, 18,20
|
|||||||
|
|
||||||
.section .bss.gl_clipping
|
.section .bss.gl_clipping
|
||||||
|
|
||||||
|
.align 4
|
||||||
CLIP_CACHE: .dcb.b SCREEN_VTX_SIZE * CLIPPING_CACHE_SIZE
|
CLIP_CACHE: .dcb.b SCREEN_VTX_SIZE * CLIPPING_CACHE_SIZE
|
||||||
CLIP_CACHE_END:
|
CLIP_CACHE_END:
|
||||||
|
|
||||||
@ -50,10 +51,10 @@ GL_ClipTriangle:
|
|||||||
#define out_list s1
|
#define out_list s1
|
||||||
#define plane s2
|
#define plane s2
|
||||||
#define intersection s3
|
#define intersection s3
|
||||||
#define cur_ptr s4
|
#define cur_ptr a0
|
||||||
#define prev_ptr s5
|
#define prev_ptr a1
|
||||||
#define cur_vtx s6
|
#define cur_vtx a2
|
||||||
#define prev_vtx s7
|
#define prev_vtx a3
|
||||||
#define p0 k0
|
#define p0 k0
|
||||||
#define p1 k1
|
#define p1 k1
|
||||||
#define vtx1 a1
|
#define vtx1 a1
|
||||||
@ -99,6 +100,11 @@ GL_ClipTriangle:
|
|||||||
sh vtx4, 6(out_list)
|
sh vtx4, 6(out_list)
|
||||||
li out_count, 4*2
|
li out_count, 4*2
|
||||||
|
|
||||||
|
#undef vtx1
|
||||||
|
#undef vtx2
|
||||||
|
#undef vtx3
|
||||||
|
#undef vtx4
|
||||||
|
|
||||||
li plane, %lo(CLIP_PLANES)
|
li plane, %lo(CLIP_PLANES)
|
||||||
li plane_flag, 1
|
li plane_flag, 1
|
||||||
|
|
||||||
@ -377,9 +383,6 @@ gl_clip_return:
|
|||||||
#undef prev_vtx
|
#undef prev_vtx
|
||||||
#undef p0
|
#undef p0
|
||||||
#undef p1
|
#undef p1
|
||||||
#undef vtx1
|
|
||||||
#undef vtx2
|
|
||||||
#undef vtx3
|
|
||||||
#undef vplane
|
#undef vplane
|
||||||
#undef vpos_i
|
#undef vpos_i
|
||||||
#undef vpos_f
|
#undef vpos_f
|
||||||
|
@ -356,7 +356,7 @@ struct VertexBuffer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct VertexBuffer* gfx_vb;
|
static struct VertexBuffer* gfx_vb;
|
||||||
static int vb_size;
|
static int vb_count, vb_fmt;
|
||||||
|
|
||||||
static void VB_ClearCache(struct VertexBuffer* vb) {
|
static void VB_ClearCache(struct VertexBuffer* vb) {
|
||||||
for (int i = 0; i < MAX_CACHED_CALLS; i++)
|
for (int i = 0; i < MAX_CACHED_CALLS; i++)
|
||||||
@ -430,13 +430,23 @@ void Gfx_DeleteVb(GfxResourceID* vb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||||
vb_size = count * strideSizes[fmt];
|
vb_count = count;
|
||||||
|
vb_fmt = fmt;
|
||||||
return ((struct VertexBuffer*)vb)->vertices;
|
return ((struct VertexBuffer*)vb)->vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_UnlockVb(GfxResourceID vb) {
|
void Gfx_UnlockVb(GfxResourceID vb) {
|
||||||
VB_ClearCache(vb); // data may have changed
|
VB_ClearCache(vb); // data may have changed
|
||||||
gfx_vb = vb;
|
gfx_vb = vb;
|
||||||
|
|
||||||
|
void* ptr = ((struct VertexBuffer*)vb)->vertices;
|
||||||
|
if (vb_fmt == VERTEX_FORMAT_COLOURED) {
|
||||||
|
convert_coloured_vertices(ptr, vb_count);
|
||||||
|
data_cache_hit_writeback_invalidate(ptr, vb_count * sizeof(struct rsp_vertex));
|
||||||
|
} else {
|
||||||
|
convert_textured_vertices(ptr, vb_count);
|
||||||
|
data_cache_hit_writeback_invalidate(ptr, vb_count * sizeof(struct rsp_vertex));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user