example/testscene: draw everything

This commit is contained in:
Zack Buhman 2025-02-01 03:53:06 -06:00
parent 87f468e83a
commit 6c3aba1dc3
10 changed files with 3510 additions and 3476 deletions

View File

@ -4,7 +4,7 @@ include base.mk
include common.mk
include headers.mk
OPT = -O2
OPT = -Og
MAKEFILE_PATH := $(patsubst %/,%,$(dir $(abspath $(firstword $(MAKEFILE_LIST)))))
CFLAGS += -I$(MAKEFILE_PATH)
LIB ?= $(MAKEFILE_PATH)

View File

@ -1,4 +1,4 @@
OPT ?= -O2
OPT ?= -Og
GENERATED ?=
AARCH = --isa=sh4 --little

View File

@ -805,7 +805,13 @@ TESTSCENE_OBJ = \
holly/ta_fifo_polygon_converter.o \
holly/video_output.o \
sh7091/serial.o \
model/testscene/texture/texBrick.data.o
model/testscene/texture/texBrick.data.o \
model/testscene/texture/texFoliage.data.o \
model/testscene/texture/texGrass.data.o \
model/testscene/texture/texGrassClump.data.o \
model/testscene/texture/texRock.data.o \
model/testscene/texture/texWater.data.o
example/testscene.elf: LDSCRIPT = $(LIB)/main.lds
example/testscene.elf: $(START_OBJ) $(TESTSCENE_OBJ)

View File

@ -36,7 +36,10 @@
using vec3 = vec<3, float>;
using vec2 = vec<2, float>;
const float degree = 0.017453292519943295;
static float theta = 0;
static int frame = 0;
static bool animate_uv;
static inline vec3 transform_vertex(vec3 vec)
{
@ -44,41 +47,51 @@ static inline vec3 transform_vertex(vec3 vec)
float y9 = vec.y;
float z9 = vec.z;
float rotatetheta = degree * 220;
float x0 = x9 * cos(theta) - z9 * sin(theta);
float y0 = y9;
float z0 = x9 * sin(theta) + z9 * cos(theta);
float x1 = x0;
float y1 = y0 * cos(theta) - z0 * sin(theta);
float z1 = y0 * sin(theta) + z0 * cos(theta);
float y1 = y0 * cos(rotatetheta) - z0 * sin(rotatetheta);
float z1 = y0 * sin(rotatetheta) + z0 * cos(rotatetheta);
float x2 = x1;
float y2 = y1;
float z2 = z1 + 4.5;
float z2 = z1 + 3.5;
float x3 = x2 / z2;
float y3 = y2 / z2;
float z3 = 1.0 / z2;
float x = x3 * 240 + 320;
float y = y3 * 240 + 320;
float y = y3 * 240 + 320 - 50;
float z = z3;
return {x, y, z};
}
static uint32_t base_color = 0xffc0c000;
static inline vec2 transform_uv(vec2 uv)
{
float x = uv.x;
float y = -uv.y;
if (animate_uv)
y = y + (-1.0f * frame / 50);
return {x, y};
}
const uint32_t base_color = 0xa0000000;
static inline void transfer_triangle(const vertex_position * position,
const vertex_texture * texture,
const union triangle * triangle)
{
base_color ^= base_color << 13;
base_color ^= base_color >> 17;
base_color ^= base_color << 5;
vec3 v1 = transform_vertex(position[triangle->a.position]);
vec2 uv1 = texture[triangle->a.texture];
vec2 uv1 = transform_uv(texture[triangle->a.texture]);
*reinterpret_cast<ta_vertex_parameter::polygon_type_3 *>(store_queue) =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false),
v1.x, v1.y, v1.z,
@ -88,7 +101,7 @@ static inline void transfer_triangle(const vertex_position * position,
sq_transfer_32byte(ta_fifo_polygon_converter);
vec3 v2 = transform_vertex(position[triangle->b.position]);
vec2 uv2 = texture[triangle->a.texture];
vec2 uv2 = transform_uv(texture[triangle->a.texture]);
*reinterpret_cast<ta_vertex_parameter::polygon_type_3 *>(store_queue) =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false),
v2.x, v2.y, v2.z,
@ -98,7 +111,7 @@ static inline void transfer_triangle(const vertex_position * position,
sq_transfer_32byte(ta_fifo_polygon_converter);
vec3 v3 = transform_vertex(position[triangle->c.position]);
vec2 uv3 = texture[triangle->c.texture];
vec2 uv3 = transform_uv(texture[triangle->c.texture]);
*reinterpret_cast<ta_vertex_parameter::polygon_type_3 *>(store_queue) =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(true),
v3.x, v3.y, v3.z,
@ -112,12 +125,8 @@ static inline void transfer_quadrilateral(const vertex_position * position,
const vertex_texture * texture,
const union quadrilateral * quadrilateral)
{
base_color ^= base_color << 13;
base_color ^= base_color >> 17;
base_color ^= base_color << 5;
vec3 v1 = transform_vertex(position[quadrilateral->a.position]);
vec2 uv1 = texture[quadrilateral->a.texture];
vec2 uv1 = transform_uv(texture[quadrilateral->a.texture]);
*reinterpret_cast<ta_vertex_parameter::polygon_type_3 *>(store_queue) =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false),
v1.x, v1.y, v1.z,
@ -127,7 +136,7 @@ static inline void transfer_quadrilateral(const vertex_position * position,
sq_transfer_32byte(ta_fifo_polygon_converter);
vec3 v2 = transform_vertex(position[quadrilateral->b.position]);
vec2 uv2 = texture[quadrilateral->b.texture];
vec2 uv2 = transform_uv(texture[quadrilateral->b.texture]);
*reinterpret_cast<ta_vertex_parameter::polygon_type_3 *>(store_queue) =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false),
v2.x, v2.y, v2.z,
@ -137,7 +146,7 @@ static inline void transfer_quadrilateral(const vertex_position * position,
sq_transfer_32byte(ta_fifo_polygon_converter);
vec3 v4 = transform_vertex(position[quadrilateral->d.position]);
vec2 uv4 = texture[quadrilateral->d.texture];
vec2 uv4 = transform_uv(texture[quadrilateral->d.texture]);
*reinterpret_cast<ta_vertex_parameter::polygon_type_3 *>(store_queue) =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false),
v4.x, v4.y, v4.z,
@ -147,7 +156,7 @@ static inline void transfer_quadrilateral(const vertex_position * position,
sq_transfer_32byte(ta_fifo_polygon_converter);
vec3 v3 = transform_vertex(position[quadrilateral->c.position]);
vec2 uv3 = texture[quadrilateral->c.texture];
vec2 uv3 = transform_uv(texture[quadrilateral->c.texture]);
*reinterpret_cast<ta_vertex_parameter::polygon_type_3 *>(store_queue) =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(true),
v3.x, v3.y, v3.z,
@ -158,27 +167,31 @@ static inline void transfer_quadrilateral(const vertex_position * position,
}
static inline void transfer_triangles(const struct model * model, const struct object * object)
static inline void transfer_triangles(const struct model * model,
const struct material_descriptor * material,
const struct object * object,
const uint32_t list_type,
const uint32_t blending,
const uint32_t pixel_format)
{
if (object->triangle_count == 0)
if (object->triangle_count == 0 && object->quadrilateral_count == 0)
return;
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::opaque
| list_type
| obj_control::col_type::packed_color
| obj_control::texture;
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater
| isp_tsp_instruction_word::culling_mode::no_culling;
const uint32_t tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one
| tsp_instruction_word::dst_alpha_instr::zero
const uint32_t tsp_instruction_word = blending
| tsp_instruction_word::fog_control::no_fog
| tsp_instruction_word::texture_u_size::from_int(128)
| tsp_instruction_word::texture_v_size::from_int(128);
const uint32_t texture_address = texture_memory_alloc.texture.start;
const uint32_t texture_control_word = texture_control_word::pixel_format::_565
const uint32_t texture_address = texture_memory_alloc.texture.start + material[object->material].pixel.vram_offset;
const uint32_t texture_control_word = pixel_format
| texture_control_word::scan_order::twiddled
| texture_control_word::texture_address(texture_address / 8);
@ -203,20 +216,90 @@ static inline void transfer_triangles(const struct model * model, const struct o
void transfer_scene()
{
const struct model * model = &testscene_model;
const struct object * object = &testscene_Waterfall;
transfer_triangles(model, object);
const struct material_descriptor * material = testscene_material;
// opaque
{
animate_uv = false;
const uint32_t list_type = para_control::list_type::opaque;
const uint32_t blending = tsp_instruction_word::src_alpha_instr::one
| tsp_instruction_word::dst_alpha_instr::zero;
const uint32_t pixel_format = texture_control_word::pixel_format::_565;
transfer_triangles(model, material,
&testscene_Ground,
list_type,
blending,
pixel_format);
transfer_triangles(model, material,
&testscene_Pole,
list_type,
blending,
pixel_format);
*reinterpret_cast<ta_global_parameter::end_of_list *>(store_queue) =
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
sq_transfer_32byte(ta_fifo_polygon_converter);
}
// punch through
{
animate_uv = false;
const uint32_t list_type = para_control::list_type::punch_through;
const uint32_t blending = tsp_instruction_word::src_alpha_instr::src_alpha
| tsp_instruction_word::dst_alpha_instr::inverse_src_alpha;
const uint32_t pixel_format = texture_control_word::pixel_format::_1555;
transfer_triangles(model, material,
&testscene_Foliage,
list_type,
blending,
pixel_format);
transfer_triangles(model, material,
&testscene_Foliage_mtl_matGrassClump,
list_type,
blending,
pixel_format);
*reinterpret_cast<ta_global_parameter::end_of_list *>(store_queue) =
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
sq_transfer_32byte(ta_fifo_polygon_converter);
}
// translucent
{
animate_uv = true;
const uint32_t list_type = para_control::list_type::translucent;
const uint32_t blending = tsp_instruction_word::src_alpha_instr::src_alpha
| tsp_instruction_word::dst_alpha_instr::inverse_src_alpha
| tsp_instruction_word::use_alpha
| tsp_instruction_word::texture_shading_instruction::decal_alpha;
const uint32_t pixel_format = texture_control_word::pixel_format::_565;
transfer_triangles(model, material,
&testscene_Waterfall,
list_type,
blending,
pixel_format);
*reinterpret_cast<ta_global_parameter::end_of_list *>(store_queue) =
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
sq_transfer_32byte(ta_fifo_polygon_converter);
}
}
void transfer_ta_fifo_texture_memory_32byte(void * dst, void * src, int length)
{
sh7091.CCN.QACR0 = ((reinterpret_cast<uint32_t>(dst) >> 24) & 0b11100);
sh7091.CCN.QACR1 = ((reinterpret_cast<uint32_t>(dst) >> 24) & 0b11100);
uint32_t out_addr = (uint32_t)dst;
sh7091.CCN.QACR0 = ((reinterpret_cast<uint32_t>(out_addr) >> 24) & 0b11100);
sh7091.CCN.QACR1 = ((reinterpret_cast<uint32_t>(out_addr) >> 24) & 0b11100);
volatile uint32_t * base = &store_queue[texture_memory_alloc.texture.start / 4];
volatile uint32_t * base = &store_queue[(out_addr & 0x03ffffc0) / 4];
uint32_t * src32 = reinterpret_cast<uint32_t *>(src);
length = (length + 31) & ~31; // round up to nearest multiple of 32
@ -233,9 +316,6 @@ void transfer_ta_fifo_texture_memory_32byte(void * dst, void * src, int length)
: // output
: "r" (&base[0]) // input
: "memory");
serial::integer<uint32_t>((uint32_t)base, ' ');
serial::integer<uint32_t>((uint32_t)src32, ' ');
serial::integer<uint32_t>(length);
length -= 32;
base += 8;
src32 += 8;
@ -247,20 +327,24 @@ void transfer_textures()
system.LMMODE0 = 0; // 64-bit address space
system.LMMODE1 = 0; // 64-bit address space
void * dst = reinterpret_cast<void *>(ta_fifo_texture_memory);
void * src = reinterpret_cast<void *>(&_binary_model_testscene_texture_texBrick_data_start);
transfer_ta_fifo_texture_memory_32byte(dst, src, 128 * 128 * 2);
for (uint32_t i = 0; i < (sizeof (testscene_material)) / (sizeof (testscene_material[0])); i++) {
const struct pixel_descriptor * pixel = &testscene_material[i].pixel;
//memory::copy<volatile uint32_t>(&texture_memory64[texture_memory_alloc.texture.start / 4], reinterpret_cast<uint32_t *>(src), 128 * 128 * 2);
uint32_t offset = texture_memory_alloc.texture.start + pixel->vram_offset;
void * dst = reinterpret_cast<void *>(&ta_fifo_texture_memory[offset / 4]);
void * src = reinterpret_cast<void *>(pixel->start);
transfer_ta_fifo_texture_memory_32byte(dst, src, pixel->width * pixel->height * 2);
}
}
void main()
{
serial::init(0);
transfer_textures();
constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list
constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::_16x4byte
| ta_alloc_ctrl::tm_opb::no_list
| ta_alloc_ctrl::t_opb::no_list
| ta_alloc_ctrl::t_opb::_16x4byte
| ta_alloc_ctrl::om_opb::no_list
| ta_alloc_ctrl::o_opb::_16x4byte;
@ -269,9 +353,9 @@ void main()
{
.opaque = 16 * 4,
.opaque_modifier = 0,
.translucent = 0,
.translucent = 16 * 4,
.translucent_modifier = 0,
.punch_through = 0
.punch_through = 16 * 4
}
};
@ -296,15 +380,11 @@ void main()
texture_memory_alloc.object_list[0].start);
background_parameter2(texture_memory_alloc.background[0].start,
0xff220033);
0xff9090c0);
const float degree = 0.017453292519943295;
int frame = 0;
frame = 0;
while (1) {
base_color = 0xffc0c000;
ta_polygon_converter_init2(texture_memory_alloc.isp_tsp_parameters[0].start,
texture_memory_alloc.isp_tsp_parameters[0].end,
texture_memory_alloc.object_list[0].start,
@ -314,7 +394,7 @@ void main()
tile_width,
tile_height);
transfer_scene();
ta_wait_opaque_list();
ta_wait_translucent_list();
core_start_render2(texture_memory_alloc.region_array[0].start,
texture_memory_alloc.isp_tsp_parameters[0].start,
@ -329,9 +409,7 @@ void main()
while (spg_status::vsync(holly.SPG_STATUS));
frame += 1;
theta += degree;
if (frame > 300)
break;
theta += degree / 2;
}
serial::string("return\nreturn\nreturn\n");
}

View File

@ -143,8 +143,6 @@ void region_array_multipass(const uint32_t width, // in tile units (1 tile unit
region_array[ix].tile = REGION_ARRAY__TILE_Y_POSITION(y)
| REGION_ARRAY__TILE_X_POSITION(x);
region_array[ix].tile |= REGION_ARRAY__PRE_SORT;
if (pass == (num_render_passes - 1) && y == (height - 1) && x == (width - 1))
region_array[ix].tile |= REGION_ARRAY__LAST_REGION;

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff