From 59f8c1b3ff6fb9645ee951df3c28234b8e899034 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Sun, 17 Dec 2023 17:04:34 +0800 Subject: [PATCH] cube: a perspective cube --- common.mk | 2 +- example/cube.cpp | 189 ++++++++++++++++++++++++++++++++++++++++- example/example.mk | 5 +- example/macaw.cpp | 14 +-- holly/core.cpp | 7 +- holly/region_array.cpp | 2 - holly/ta_parameter.hpp | 9 +- 7 files changed, 207 insertions(+), 21 deletions(-) diff --git a/common.mk b/common.mk index 3145c60..1380afc 100644 --- a/common.mk +++ b/common.mk @@ -2,7 +2,7 @@ MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) DIR := $(dir $(MAKEFILE_PATH)) LIB ?= . -OPT ?= -O3 +OPT ?= -Os DEBUG ?= -g -gdwarf-4 GENERATED ?= diff --git a/example/cube.cpp b/example/cube.cpp index 879df23..c1524a6 100644 --- a/example/cube.cpp +++ b/example/cube.cpp @@ -1,12 +1,197 @@ #include +#include "align.hpp" #include "vga.hpp" + +#include "holly/texture_memory_alloc.hpp" +#include "holly.hpp" +#include "holly/core.hpp" +#include "holly/core_bits.hpp" +#include "holly/ta_fifo_polygon_converter.hpp" +#include "holly/ta_parameter.hpp" +#include "holly/ta_bits.hpp" +#include "holly/region_array.hpp" +#include "holly/background.hpp" #include "memorymap.hpp" -#include "rgb.hpp" + +#include "serial.hpp" + +#include "macaw.hpp" + +struct vertex { + float x; + float y; + float z; + float u; + float v; +}; + +vertex cube_faces[][4] = { + { // front + { -1.0f, -1.0f, 1.0f, 0.f, 0.f}, + { -1.0f, 1.0f, 1.0f, 0.f, 1.f}, + { 1.0f, -1.0f, 1.0f, 1.f, 0.f}, + { 1.0f, 1.0f, 1.0f, 1.f, 1.f}, + }, + { // back + { -1.0f, -1.0f, -1.0f, 1.f, 0.f}, + { -1.0f, 1.0f, -1.0f, 1.f, 1.f}, + { 1.0f, -1.0f, -1.0f, 0.f, 0.f}, + { 1.0f, 1.0f, -1.0f, 0.f, 1.f}, + }, + { // right side + { 1.0f, -1.0f, 1.0f, 0.f, 0.f}, + { 1.0f, 1.0f, 1.0f, 0.f, 1.f}, + { 1.0f, -1.0f, -1.0f, 1.f, 0.f}, + { 1.0f, 1.0f, -1.0f, 1.f, 1.f}, + }, + { // left side + { -1.0f, -1.0f, 1.0f, 1.f, 0.f}, + { -1.0f, 1.0f, 1.0f, 1.f, 1.f}, + { -1.0f, -1.0f, -1.0f, 0.f, 0.f}, + { -1.0f, 1.0f, -1.0f, 0.f, 1.f}, + }, +}; +constexpr uint32_t num_faces = (sizeof (cube_faces)) / (sizeof (cube_faces[0])); + +constexpr uint32_t color = 0xffff00ff; + +static float theta = 0; +constexpr float half_degree = 0.01745329f / 2.f; + +void transform(ta_parameter_writer& parameter, + const vertex * strip_vertices, + const uint32_t strip_length) +{ + uint32_t texture_address = (offsetof (struct texture_memory_alloc, texture)); + parameter.append() = global_polygon_type_0(texture_address); + + for (uint32_t i = 0; i < strip_length; i++) { + bool end_of_strip = i == strip_length - 1; + + float x = strip_vertices[i].x; + float y = strip_vertices[i].y; + float z = strip_vertices[i].z; + float t; + + t = y * __builtin_cosf(theta) - z * __builtin_sinf(theta); + z = y * __builtin_sinf(theta) + z * __builtin_cosf(theta); + y = t; + + float theta2 = 3.14 * __builtin_sinf(theta / 2); + + t = x * __builtin_cosf(theta2) - z * __builtin_sinf(theta2); + z = x * __builtin_sinf(theta2) + z * __builtin_cosf(theta2); + x = t; + + z += 3; + + // perspective + x = x / z; + y = y / z; + + x *= 240.f; + y *= 240.f; + x += 320.f; + y += 240.f; + + + z = 1 / z; + + parameter.append() = + vertex_polygon_type_3(x, y, z, + strip_vertices[i].u, + strip_vertices[i].v, + color, + end_of_strip); + } +} + +void init_texture_memory(const struct opb_size& opb_size) +{ + volatile texture_memory_alloc * mem = reinterpret_cast(texture_memory); + + background_parameter(mem->background); + + region_array2(mem->region_array, + (offsetof (struct texture_memory_alloc, object_list)), + 640 / 32, // width + 480 / 32, // height + opb_size + ); +} + +void copy_macaw_texture() +{ + auto src = reinterpret_cast(&_binary_macaw_data_start); + auto size = reinterpret_cast(&_binary_macaw_data_size); + auto mem = reinterpret_cast(0xa400'0000); + for (uint32_t px = 0; px < size / 3; px++) { + uint8_t r = src[px * 3 + 0]; + uint8_t g = src[px * 3 + 1]; + uint8_t b = src[px * 3 + 2]; + + uint16_t rgb565 = ((r / 8) << 11) | ((g / 4) << 5) | ((b / 8) << 0); + mem->texture[px] = rgb565; + } +} + +uint32_t _ta_parameter_buf[((32 * (5 * 6 + 1)) + 32) / 4]; void main() { vga(); + copy_macaw_texture(); - while (1); + // The address of `ta_parameter_buf` must be a multiple of 32 bytes. + // This is mandatory for ch2-dma to the ta fifo polygon converter. + uint32_t * ta_parameter_buf = align_32byte(_ta_parameter_buf); + + constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list + | ta_alloc_ctrl::tm_opb::no_list + | ta_alloc_ctrl::t_opb::no_list + | ta_alloc_ctrl::om_opb::no_list + | ta_alloc_ctrl::o_opb::_16x4byte; + + constexpr struct opb_size opb_size = { .opaque = 16 * 4 + , .opaque_modifier = 0 + , .translucent = 0 + , .translucent_modifier = 0 + , .punch_through = 0 + }; + + constexpr uint32_t tiles = (640 / 32) * (320 / 32); + + holly.SOFTRESET = softreset::pipeline_soft_reset + | softreset::ta_soft_reset; + holly.SOFTRESET = 0; + + core_init(); + init_texture_memory(opb_size); + + uint32_t frame_ix = 0; + constexpr uint32_t num_frames = 1; + + while (1) { + ta_polygon_converter_init(opb_size.total() * tiles, ta_alloc); + + auto parameter = ta_parameter_writer(ta_parameter_buf); + for (uint32_t i = 0; i < num_faces; i++) { + transform(parameter, cube_faces[i], 4); + } + parameter.append() = global_end_of_list(); + + ta_polygon_converter_transfer(ta_parameter_buf, parameter.offset); + + ta_wait_opaque_list(); + + core_start_render(frame_ix, num_frames); + + v_sync_out(); + v_sync_in(); + core_wait_end_of_render_video(frame_ix, num_frames); + + theta += half_degree; + frame_ix += 1; + } } diff --git a/example/example.mk b/example/example.mk index 55f2cdd..e05f576 100644 --- a/example/example.mk +++ b/example/example.mk @@ -74,7 +74,10 @@ CUBE_OBJ = \ example/cube.o \ vga.o \ holly/core.o \ - holly/ta_fifo_polygon_converter.o + holly/region_array.o \ + holly/background.o \ + holly/ta_fifo_polygon_converter.o \ + macaw.data.o example/cube.elf: LDSCRIPT = $(LIB)/alt.lds example/cube.elf: $(START_OBJ) $(CUBE_OBJ) diff --git a/example/macaw.cpp b/example/macaw.cpp index 71a957a..3799fd4 100644 --- a/example/macaw.cpp +++ b/example/macaw.cpp @@ -89,12 +89,8 @@ void init_texture_memory(const struct opb_size& opb_size) ); } -uint32_t _ta_parameter_buf[((32 * (strip_length + 2)) + 32) / 4]; - -void main() +void copy_macaw_texture() { - vga(); - auto src = reinterpret_cast(&_binary_macaw_data_start); auto size = reinterpret_cast(&_binary_macaw_data_size); auto mem = reinterpret_cast(0xa400'0000); @@ -106,6 +102,14 @@ void main() uint16_t rgb565 = ((r / 8) << 11) | ((g / 4) << 5) | ((b / 8) << 0); mem->texture[px] = rgb565; } +} + +uint32_t _ta_parameter_buf[((32 * (strip_length + 2)) + 32) / 4]; + +void main() +{ + vga(); + copy_macaw_texture(); // The address of `ta_parameter_buf` must be a multiple of 32 bytes. // This is mandatory for ch2-dma to the ta fifo polygon converter. diff --git a/holly/core.cpp b/holly/core.cpp index 4853f82..89d8d58 100644 --- a/holly/core.cpp +++ b/holly/core.cpp @@ -13,14 +13,13 @@ void core_init() { - holly.ISP_FEED_CFG = isp_feed_cfg::cache_size_for_translucency(0x200) - | isp_feed_cfg::pre_sort_mode; + holly.ISP_FEED_CFG = isp_feed_cfg::cache_size_for_translucency(0x200); holly.FPU_SHAD_SCALE = fpu_shad_scale::scale_factor_for_shadows(1); holly.FPU_CULL_VAL = _i(1.f); holly.FPU_PERP_VAL = _i(0.f); - holly.SPAN_SORT_CFG = span_sort_cfg::span_sort_enable - | span_sort_cfg::offset_sort_enable; + holly.SPAN_SORT_CFG = 0; /*span_sort_cfg::span_sort_enable + | span_sort_cfg::offset_sort_enable;*/ holly.FOG_COL_RAM = fog_col_ram::red(127) | fog_col_ram::green(127) diff --git a/holly/region_array.cpp b/holly/region_array.cpp index 71806f5..fa808d7 100644 --- a/holly/region_array.cpp +++ b/holly/region_array.cpp @@ -95,8 +95,6 @@ void region_array2(volatile uint32_t * buf, region_array[ix].tile |= REGION_ARRAY__LAST_REGION; uint32_t tile_index = y * width + x; - constexpr uint32_t opaque_list_opb_size = 16 * 4; // in bytes; this must match O_OPB in TA_ALLOC_CTRL - constexpr uint32_t translucent_list_opb_size = 16 * 4; // in bytes; this must match O_OPB in TA_ALLOC_CTRL region_array[ix].opaque_list_pointer = (opb_size.opaque == 0) ? REGION_ARRAY__LIST_POINTER__EMPTY : (ol_base + (opb_size.opaque * tile_index) ); diff --git a/holly/ta_parameter.hpp b/holly/ta_parameter.hpp index a397542..beb33d9 100644 --- a/holly/ta_parameter.hpp +++ b/holly/ta_parameter.hpp @@ -174,17 +174,14 @@ struct global_polygon_type_0 { // untextured global_polygon_type_0() : parameter_control_word( para_control::para_type::polygon_or_modifier_volume - | para_control::list_type::translucent - | obj_control::col_type::packed_color - | obj_control::gouraud ) + | obj_control::col_type::packed_color ) , isp_tsp_instruction_word( isp_tsp_instruction_word::depth_compare_mode::always | isp_tsp_instruction_word::culling_mode::no_culling ) , tsp_instruction_word( tsp_instruction_word::src_alpha_instr::src_alpha | tsp_instruction_word::dst_alpha_instr::inverse_src_alpha - | tsp_instruction_word::fog_control::no_fog - | tsp_instruction_word::use_alpha ) + | tsp_instruction_word::fog_control::no_fog ) , texture_control_word( 0 ) @@ -201,7 +198,7 @@ struct global_polygon_type_0 { | obj_control::col_type::packed_color | obj_control::texture ) - , isp_tsp_instruction_word( isp_tsp_instruction_word::depth_compare_mode::always + , isp_tsp_instruction_word( isp_tsp_instruction_word::depth_compare_mode::greater | isp_tsp_instruction_word::culling_mode::no_culling ) // Because a value of "0.0" is invalid for [MIP-Map] D [adjust], it must not be specified.