main: draw rotating cube
This commit is contained in:
parent
74d3b5183b
commit
744dc8645a
2
Makefile
2
Makefile
@ -5,4 +5,4 @@
|
|||||||
python gen/rgb_txt.py $< > $@
|
python gen/rgb_txt.py $< > $@
|
||||||
|
|
||||||
main: main.c bear.rgb565.inc panda.rgb565.inc
|
main: main.c bear.rgb565.inc panda.rgb565.inc
|
||||||
gcc -g -Og -std=c23 $< -o $@
|
gcc -g -Og -lm -std=gnu23 $< -o $@
|
||||||
|
226
main.c
226
main.c
@ -6,6 +6,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "voodoo2.h"
|
#include "voodoo2.h"
|
||||||
#include "voodoo2_bits.h"
|
#include "voodoo2_bits.h"
|
||||||
@ -16,7 +17,27 @@
|
|||||||
static inline bool _wait_graphics_busy(voodoo2_reg * voodoo2)
|
static inline bool _wait_graphics_busy(voodoo2_reg * voodoo2)
|
||||||
{
|
{
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
for (int i = 0; i < 4096; i++) {
|
for (int i = 0; i < 128; i++) {
|
||||||
|
if (voodoo2->status & STATUS__CHUCK_BUSY) {
|
||||||
|
//if (voodoo2->status & STATUS__PCI_FIFO_FREESPACE(0x3f)) {
|
||||||
|
cnt = 0;
|
||||||
|
} else {
|
||||||
|
cnt += 1;
|
||||||
|
}
|
||||||
|
if (cnt >= 5)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//fprintf(stderr, "voodoo2 status %08x\n", voodoo2->status);
|
||||||
|
//return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define wait_graphics_busy(voodoo2) assert(_wait_graphics_busy(voodoo2));
|
||||||
|
|
||||||
|
static inline bool _wait_graphics_busy2(voodoo2_reg * voodoo2)
|
||||||
|
{
|
||||||
|
int cnt = 0;
|
||||||
|
while (true) {
|
||||||
if (voodoo2->status & STATUS__CHUCK_BUSY) {
|
if (voodoo2->status & STATUS__CHUCK_BUSY) {
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -28,7 +49,7 @@ static inline bool _wait_graphics_busy(voodoo2_reg * voodoo2)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define wait_graphics_busy(voodoo2) assert(_wait_graphics_busy(voodoo2));
|
#define wait_graphics_busy2(voodoo2) assert(_wait_graphics_busy2(voodoo2));
|
||||||
|
|
||||||
static inline void dac_data_read(voodoo2_reg * voodoo2,
|
static inline void dac_data_read(voodoo2_reg * voodoo2,
|
||||||
int data,
|
int data,
|
||||||
@ -137,6 +158,93 @@ void write_fd_u32(int fd, uint32_t offset, uint32_t value)
|
|||||||
assert(len == 4);
|
assert(len == 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct vec3 {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
} vec3;
|
||||||
|
|
||||||
|
static const vec3 cube_vertex_position[] = {
|
||||||
|
{ 1.0f, 1.0f, -1.0f },
|
||||||
|
{ 1.0f, -1.0f, -1.0f },
|
||||||
|
{ 1.0f, 1.0f, 1.0f },
|
||||||
|
{ 1.0f, -1.0f, 1.0f },
|
||||||
|
{ -1.0f, 1.0f, -1.0f },
|
||||||
|
{ -1.0f, -1.0f, -1.0f },
|
||||||
|
{ -1.0f, 1.0f, 1.0f },
|
||||||
|
{ -1.0f, -1.0f, 1.0f },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint32_t cube_vertex_color[] = {
|
||||||
|
0xff0000, // red
|
||||||
|
0x00ff00, // green
|
||||||
|
0x0000ff, // blue
|
||||||
|
0xffff00, // yellow
|
||||||
|
0x00ffff, // cyan
|
||||||
|
0xff00ff, // magenta
|
||||||
|
0xff7f00, // orange
|
||||||
|
0x7f00ff, // violet
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct face {
|
||||||
|
int a;
|
||||||
|
int b;
|
||||||
|
int c;
|
||||||
|
} face;
|
||||||
|
|
||||||
|
static const face cube_faces[] = {
|
||||||
|
{4, 2, 0},
|
||||||
|
{2, 7, 3},
|
||||||
|
{6, 5, 7},
|
||||||
|
{1, 7, 5},
|
||||||
|
{0, 3, 1},
|
||||||
|
{4, 1, 5},
|
||||||
|
{4, 6, 2},
|
||||||
|
{2, 6, 7},
|
||||||
|
{6, 4, 5},
|
||||||
|
{1, 3, 7},
|
||||||
|
{0, 2, 3},
|
||||||
|
{4, 0, 1},
|
||||||
|
};
|
||||||
|
static const int cube_faces_length = (sizeof (cube_faces)) / (sizeof (cube_faces[0]));
|
||||||
|
|
||||||
|
static float theta = 0;
|
||||||
|
|
||||||
|
static inline vec3 vertex_rotate(vec3 v)
|
||||||
|
{
|
||||||
|
// to make the cube's appearance more interesting, rotate the vertex on two
|
||||||
|
// axes
|
||||||
|
|
||||||
|
float x0 = v.x;
|
||||||
|
float y0 = v.y;
|
||||||
|
float z0 = v.z;
|
||||||
|
|
||||||
|
float x1 = x0 * cos(theta) - z0 * sin(theta);
|
||||||
|
float y1 = y0;
|
||||||
|
float z1 = x0 * sin(theta) + z0 * cos(theta);
|
||||||
|
|
||||||
|
float x2 = x1;
|
||||||
|
float y2 = y1 * cos(theta) - z1 * sin(theta);
|
||||||
|
float z2 = y1 * sin(theta) + z1 * cos(theta);
|
||||||
|
|
||||||
|
return (vec3){x2, y2, z2};
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline vec3 vertex_perspective_divide(vec3 v)
|
||||||
|
{
|
||||||
|
float w = 1.0f / (v.z + 3.0f);
|
||||||
|
return (vec3){v.x * w, v.y * w, w};
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline vec3 vertex_screen_space(vec3 v)
|
||||||
|
{
|
||||||
|
return (vec3){
|
||||||
|
v.x * 300.f + 400.f,
|
||||||
|
v.y * 300.f + 300.f,
|
||||||
|
v.z,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
const char * config_path = "/sys/bus/pci/devices/0000:02:0a.0/config";
|
const char * config_path = "/sys/bus/pci/devices/0000:02:0a.0/config";
|
||||||
@ -180,6 +288,8 @@ int main()
|
|||||||
|
|
||||||
int init_enable;
|
int init_enable;
|
||||||
|
|
||||||
|
goto draw;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// reset
|
// reset
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
@ -283,6 +393,7 @@ int main()
|
|||||||
| FBIINIT2__ENABLE_GENERATED_DRAM_OE_SIGNAL
|
| FBIINIT2__ENABLE_GENERATED_DRAM_OE_SIGNAL
|
||||||
| FBIINIT2__VIDEO_BUFFER_OFFSET(247)
|
| FBIINIT2__VIDEO_BUFFER_OFFSET(247)
|
||||||
| FBIINIT2__ENABLE_DRAM_READ_AHEAD_FIFO
|
| FBIINIT2__ENABLE_DRAM_READ_AHEAD_FIFO
|
||||||
|
| FBIINIT2__ENABLE_DRAM_BANKING
|
||||||
| FBIINIT2__REFRESH_ENABLE
|
| FBIINIT2__REFRESH_ENABLE
|
||||||
| FBIINIT2__REFRESH_LOAD_VALUE(0x30)
|
| FBIINIT2__REFRESH_LOAD_VALUE(0x30)
|
||||||
;
|
;
|
||||||
@ -360,6 +471,7 @@ int main()
|
|||||||
wait_graphics_busy(voodoo2);
|
wait_graphics_busy(voodoo2);
|
||||||
|
|
||||||
if (0) {
|
if (0) {
|
||||||
|
/*
|
||||||
static const uint16_t panda[] __attribute__((aligned(4))) = {
|
static const uint16_t panda[] __attribute__((aligned(4))) = {
|
||||||
#include "panda.rgb565.inc"
|
#include "panda.rgb565.inc"
|
||||||
};
|
};
|
||||||
@ -388,23 +500,123 @@ int main()
|
|||||||
}
|
}
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// triangle
|
// triangle
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
draw:
|
||||||
|
voodoo2->fbzMode
|
||||||
|
= FBZMODE__DEPTH_BUFFER_FUNCTION__LESS_THAN
|
||||||
|
| FBZMODE__ENABLE_DEPTH_BUFFERING
|
||||||
|
| FBZMODE__FLOATING_POINT_DEPTH_BUFFER
|
||||||
|
| FBZMODE__RGB_BUFFER_WRITE_MASK
|
||||||
|
| FBZMODE__DEPTH_ALPHA_BUFFER_WRITE_MASK
|
||||||
|
| FBZMODE__DRAW_BUFFER__BACK_BUFFER
|
||||||
|
;
|
||||||
|
wait_graphics_busy(voodoo2);
|
||||||
|
|
||||||
|
voodoo2->lfbMode
|
||||||
|
= LFBMODE__LINEAR_FRAME_BUFFER__WRITE_FORMAT__RGB565
|
||||||
|
| LFBMODE__LINEAR_FRAME_BUFFER__WRITE_BUFFER_SELECT__BACK_BUFFER
|
||||||
|
| LFBMODE__LINEAR_FRAME_BUFFER__READ_BUFFER_SELECT__FRONT_BUFFER
|
||||||
|
| LFBMODE__LINEAR_FRAME_BUFFER__ENABLE_PIXEL_PIPELINE_WRITES
|
||||||
|
| LFBMODE__LINEAR_FRAME_BUFFER__RGBA_LANES__ARGB
|
||||||
|
;
|
||||||
|
wait_graphics_busy(voodoo2);
|
||||||
|
|
||||||
voodoo2->sSetupMode
|
voodoo2->sSetupMode
|
||||||
= SSETUPMODE__SETUP_RED_GREEN_BLUE
|
= SSETUPMODE__SETUP_RED_GREEN_BLUE
|
||||||
|
| SSETUPMODE__SETUP_WB
|
||||||
|
;
|
||||||
|
wait_graphics_busy(voodoo2);
|
||||||
|
|
||||||
|
//
|
||||||
|
voodoo2->clipLeftRight
|
||||||
|
= CLIPLEFTRIGHT__RIGHT(800)
|
||||||
|
| CLIPLEFTRIGHT__LEFT(0);
|
||||||
|
wait_graphics_busy(voodoo2);
|
||||||
|
|
||||||
|
voodoo2->clipLowYHighY
|
||||||
|
= CLIPLOWYHIGHY__HIGH_Y(600)
|
||||||
|
| CLIPLOWYHIGHY__LOW_Y(0);
|
||||||
|
wait_graphics_busy(voodoo2);
|
||||||
|
|
||||||
|
voodoo2->color1 = 0xff008080;
|
||||||
|
wait_graphics_busy(voodoo2);
|
||||||
|
|
||||||
|
voodoo2->zaColor
|
||||||
|
= ZACOLOR__DEPTH(0xffff)
|
||||||
|
| ZACOLOR__ALPHA(0xff)
|
||||||
;
|
;
|
||||||
|
|
||||||
voodoo2->sBeginTriCMD = 1;
|
for (int i = 0; i < 601; i++) {
|
||||||
|
/*
|
||||||
|
volatile uint16_t * framebuffer
|
||||||
|
= (volatile uint16_t * )(((ptrdiff_t)resource0_base) + 0x0400000);
|
||||||
|
|
||||||
voodoo2->sVx = 10;
|
for (int i = 0; i < 1024 * 800 * 2 / 2; i++) {
|
||||||
voodoo2->sVy = 10;
|
framebuffer[i] = 0;
|
||||||
voodoo2->sVy = 10;
|
}
|
||||||
|
wait_graphics_busy(voodoo2);
|
||||||
|
*/
|
||||||
|
|
||||||
voodoo2->sDrawTriCMD = 1;
|
voodoo2->fastfillCMD = 0;
|
||||||
|
wait_graphics_busy2(voodoo2);
|
||||||
|
|
||||||
|
for (int face_ix = 0; face_ix < cube_faces_length; face_ix++) {
|
||||||
|
int ia = cube_faces[face_ix].a;
|
||||||
|
int ib = cube_faces[face_ix].b;
|
||||||
|
int ic = cube_faces[face_ix].c;
|
||||||
|
|
||||||
|
vec3 va = vertex_screen_space(
|
||||||
|
vertex_perspective_divide(
|
||||||
|
vertex_rotate(cube_vertex_position[ia])));
|
||||||
|
|
||||||
|
vec3 vb = vertex_screen_space(
|
||||||
|
vertex_perspective_divide(
|
||||||
|
vertex_rotate(cube_vertex_position[ib])));
|
||||||
|
|
||||||
|
vec3 vc = vertex_screen_space(
|
||||||
|
vertex_perspective_divide(
|
||||||
|
vertex_rotate(cube_vertex_position[ic])));
|
||||||
|
|
||||||
|
uint32_t va_color = cube_vertex_color[ia];
|
||||||
|
uint32_t vb_color = cube_vertex_color[ib];
|
||||||
|
uint32_t vc_color = cube_vertex_color[ic];
|
||||||
|
|
||||||
|
voodoo2->sVx = va.x;
|
||||||
|
voodoo2->sVy = va.y;
|
||||||
|
voodoo2->sWb = va.z;
|
||||||
|
voodoo2->sARGB = va_color;
|
||||||
|
voodoo2->sBeginTriCMD = 1;
|
||||||
|
wait_graphics_busy(voodoo2);
|
||||||
|
|
||||||
|
voodoo2->sVx = vb.x;
|
||||||
|
voodoo2->sVy = vb.y;
|
||||||
|
voodoo2->sWb = vb.z;
|
||||||
|
voodoo2->sARGB = vb_color;
|
||||||
|
voodoo2->sDrawTriCMD = 1;
|
||||||
|
wait_graphics_busy(voodoo2);
|
||||||
|
|
||||||
|
voodoo2->sVx = vc.x;
|
||||||
|
voodoo2->sVy = vc.y;
|
||||||
|
voodoo2->sWb = vc.z;
|
||||||
|
voodoo2->sARGB = vc_color;
|
||||||
|
voodoo2->sDrawTriCMD = 1;
|
||||||
|
wait_graphics_busy(voodoo2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// swap front/back buffers
|
||||||
|
voodoo2->swapbufferCMD = 1;
|
||||||
|
//wait_graphics_busy(voodoo2);
|
||||||
|
//asdf
|
||||||
|
|
||||||
|
while (voodoo2->status & STATUS__SWAP_BUFFERS_PENDING(0x7));
|
||||||
|
|
||||||
|
theta += 0.01f;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// cleanup
|
// cleanup
|
||||||
|
Loading…
x
Reference in New Issue
Block a user