From 6bfb5bdb63acef80c2ac59c3cc12900214716a00 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Thu, 6 Nov 2025 17:12:40 -0600 Subject: [PATCH] src: add plane --- model/plane.h | 50 +++ src/Makefile | 9 +- src/matrix_cubesphere.cpp | 3 + src/matrix_cubesphere_tiled.cpp | 3 + src/particle.cpp | 546 +++++++++++++++++++++++++++ src/particle_particle.fs.asm | 10 + src/particle_particle.fs.bin | Bin 0 -> 48 bytes src/particle_particle.vs.asm | 15 + src/particle_particle.vs.bin | Bin 0 -> 96 bytes src/particle_plane.fs.asm | 10 + src/particle_plane.fs.bin | Bin 0 -> 48 bytes src/particle_plane.vs.asm | 15 + src/particle_plane.vs.bin | Bin 0 -> 96 bytes src/r500/indirect_buffer.c | 32 +- src/r500/indirect_buffer.h | 1 + texture/particle_32x32_rgba8888.data | Bin 0 -> 4096 bytes texture/plane_32x32_rgba8888.data | Bin 0 -> 4096 bytes transfer.sh | 5 + 18 files changed, 691 insertions(+), 8 deletions(-) create mode 100644 model/plane.h create mode 100644 src/particle.cpp create mode 100644 src/particle_particle.fs.asm create mode 100644 src/particle_particle.fs.bin create mode 100644 src/particle_particle.vs.asm create mode 100644 src/particle_particle.vs.bin create mode 100644 src/particle_plane.fs.asm create mode 100644 src/particle_plane.fs.bin create mode 100644 src/particle_plane.vs.asm create mode 100644 src/particle_plane.vs.bin create mode 100644 texture/particle_32x32_rgba8888.data create mode 100644 texture/plane_32x32_rgba8888.data create mode 100755 transfer.sh diff --git a/model/plane.h b/model/plane.h new file mode 100644 index 0000000..ab21ffe --- /dev/null +++ b/model/plane.h @@ -0,0 +1,50 @@ +#pragma once + +const vec3 plane_position[] = { + {1.000000f, 1.000000f, -0.000000f}, + {1.000000f, -1.000000f, -0.000000f}, + {-1.000000f, 1.000000f, 0.000000f}, + {-1.000000f, -1.000000f, 0.000000f}, +}; + +const vec2 plane_texture[] = { + {1.000000f, 0.000000f}, + {0.000000f, 1.000000f}, + {0.000000f, 0.000000f}, + {1.000000f, 1.000000f}, +}; + +const vec3 plane_normal[] = { + {-0.0000f, -0.0000f, -1.0000f}, +}; + +const triangle_t plane_Plane_triangle[] = { + { + {1, 0, 0}, + {2, 1, 0}, + {0, 2, 0}, + }, + { + {1, 0, 0}, + {3, 3, 0}, + {2, 1, 0}, + }, +}; + +const object plane_Plane = { + .triangle = &plane_Plane_triangle[0], + .triangle_count = 2, +}; + +const object * plane_object[] = { + &plane_Plane, +}; + +const model plane_model = { + .position = plane_position, + .texture = plane_texture, + .normal = plane_normal, + .object = plane_object, + .object_count = 1 +}; + diff --git a/src/Makefile b/src/Makefile index bee8d17..5a47147 100644 --- a/src/Makefile +++ b/src/Makefile @@ -21,10 +21,7 @@ R500_COMMON = \ drm/drm.o \ file.o -matrix_cubesphere: $(R500_COMMON) matrix_cubesphere.o | shaders - $(CXX) $(LDFLAGS) $^ -o $@ - -matrix_cubesphere_tiled: $(R500_COMMON) matrix_cubesphere_tiled.o | shaders +%: $(R500_COMMON) %.o | shaders $(CXX) $(LDFLAGS) $^ -o $@ %.o: %.c @@ -48,9 +45,9 @@ matrix_cubesphere_tiled: $(R500_COMMON) matrix_cubesphere_tiled.o | shaders shaders: $(SHADER_BIN) @true -#find . -type f ! -name "*.*" -delete clean: - find . -type f -name "*.o" -delete + find . -type f -name "*.o" -delete -print + find . -type f -executable ! -name '*.*' -delete -print .SUFFIXES: .INTERMEDIATE: diff --git a/src/matrix_cubesphere.cpp b/src/matrix_cubesphere.cpp index f11e04e..43c7aa8 100644 --- a/src/matrix_cubesphere.cpp +++ b/src/matrix_cubesphere.cpp @@ -489,6 +489,9 @@ int indirect_buffer(shaders& shaders, ib_generic_initialization(); + T0V(RB3D_BLENDCNTL, 0); + T0V(RB3D_ABLENDCNTL, 0); + ib_viewport(width, height); ib_colorbuffer(COLORBUFFER_RELOC_INDEX, pitch, 0, 0); diff --git a/src/matrix_cubesphere_tiled.cpp b/src/matrix_cubesphere_tiled.cpp index 8686bb0..f1a2ec4 100644 --- a/src/matrix_cubesphere_tiled.cpp +++ b/src/matrix_cubesphere_tiled.cpp @@ -492,6 +492,9 @@ int indirect_buffer(const shaders& shaders, ib_generic_initialization(); + T0V(RB3D_BLENDCNTL, 0); + T0V(RB3D_ABLENDCNTL, 0); + ib_viewport(width, height); ib_colorbuffer(COLORBUFFER_RELOC_INDEX, pitch, 0, 0); diff --git a/src/particle.cpp b/src/particle.cpp new file mode 100644 index 0000000..394b5d5 --- /dev/null +++ b/src/particle.cpp @@ -0,0 +1,546 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "r500/3d_registers.h" +#include "r500/3d_registers_undocumented.h" +#include "r500/3d_registers_bits.h" +#include "r500/indirect_buffer.h" +#include "r500/shader.h" +#include "r500/display_controller.h" + +#include "drm/buffer.h" +#include "drm/drm.h" + +#include "math/float_types.hpp" +#include "math/transform.hpp" +#include "math/constants.hpp" + +#include "../model/model2.h" +#include "../model/plane.h" + +#define CLEAR_SHADER 0 +#define PLANE_SHADER 1 +#define PARTICLE_SHADER 2 +#define TEXTURE_TILE_SHADER 3 + +const char * vertex_shader_paths[] = { + "clear.vs.bin", + "particle_plane.vs.bin", + "particle_particle.vs.bin", + "texture_tile.vs.bin", +}; +const int vertex_shader_paths_length = (sizeof (vertex_shader_paths)) / (sizeof (vertex_shader_paths[0])); +const char * fragment_shader_paths[] = { + "clear.fs.bin", + "particle_plane.fs.bin", + "particle_particle.fs.bin", + "texture_tile.fs.bin", +}; +const int fragment_shader_paths_length = (sizeof (fragment_shader_paths)) / (sizeof (fragment_shader_paths[0])); + +#define PLANE_TEXTURE 0 +#define PARTICLE_TEXTURE 1 + +const char * textures[] = { + "../texture/plane_32x32_rgba8888.data", + "../texture/particle_32x32_rgba8888.data", +}; +const int textures_length = (sizeof (textures)) / (sizeof (textures[0])); + +struct shaders { + struct shader_offset * vertex; + struct shader_offset * fragment; + int vertex_length; + int fragment_length; +}; + +void _3d_clear(struct shaders& shaders) +{ + ib_rs_instructions(0); + + ////////////////////////////////////////////////////////////////////////////// + // VAP OUT + ////////////////////////////////////////////////////////////////////////////// + + T0V(VAP_OUT_VTX_FMT_0 + , VAP_OUT_VTX_FMT_0__VTX_POS_PRESENT(1)); + T0V(VAP_OUT_VTX_FMT_1 + , 0); + + // + + ib_zbuffer(ZBUFFER_RELOC_INDEX, 1600, 7); // always + + ib_texture__0(); + + ib_vap_stream_cntl__2(); + + // shaders + T0V(US_PIXSIZE + , US_PIXSIZE__PIX_SIZE(1) + ); + ib_ga_us(&shaders.fragment[CLEAR_SHADER]); + ib_vap_pvs(&shaders.vertex[CLEAR_SHADER]); + + ////////////////////////////////////////////////////////////////////////////// + // VAP INDEX + ////////////////////////////////////////////////////////////////////////////// + + T0V(VAP_INDEX_OFFSET, 0); + + T0V(VAP_VF_MAX_VTX_INDX + , VAP_VF_MAX_VTX_INDX__MAX_INDX(0) + ); + T0V(VAP_VF_MIN_VTX_INDX + , VAP_VF_MIN_VTX_INDX__MIN_INDX(0) + ); + + ////////////////////////////////////////////////////////////////////////////// + // VAP + ////////////////////////////////////////////////////////////////////////////// + + T0V(VAP_CLIP_CNTL + , VAP_CLIP_CNTL__CLIP_DISABLE(1) + ); + + T0V(VAP_VTE_CNTL + , VAP_VTE_CNTL__VTX_XY_FMT(1) // disable W division + | VAP_VTE_CNTL__VTX_Z_FMT(1) // disable W division + ); + + T0V(VAP_CNTL_STATUS + , VAP_CNTL_STATUS__PVS_BYPASS(0) + ); + + ////////////////////////////////////////////////////////////////////////////// + // GA POINT SIZE + ////////////////////////////////////////////////////////////////////////////// + + T0V(GA_POINT_SIZE + , GA_POINT_SIZE__HEIGHT(600 * 12) + | GA_POINT_SIZE__WIDTH(800 * 12) + ); + + ////////////////////////////////////////////////////////////////////////////// + // 3D_DRAW + ////////////////////////////////////////////////////////////////////////////// + + const int dwords_per_vtx = 2; + + T0V(VAP_VTX_SIZE + , VAP_VTX_SIZE__DWORDS_PER_VTX(dwords_per_vtx) + ); + + const float center[] = { + 800.0f, 600.0f, + }; + const int vertex_count = 1; + T3(_3D_DRAW_IMMD_2, (1 + vertex_count * dwords_per_vtx) - 1); + TU( VAP_VF_CNTL__PRIM_TYPE(1) // point list + | VAP_VF_CNTL__PRIM_WALK(3) + | VAP_VF_CNTL__INDEX_SIZE(0) + | VAP_VF_CNTL__VTX_REUSE_DIS(0) + | VAP_VF_CNTL__DUAL_INDEX_MODE(0) + | VAP_VF_CNTL__USE_ALT_NUM_VERTS(0) + | VAP_VF_CNTL__NUM_VERTICES(vertex_count) + ); + for (int i = 0; i < 2; i++) { + TF(center[i]); + } +} + +mat4x4 perspective(float low1, float high1, + float low2, float high2, + float low3, float high3) +{ + float scale2 = (high2 - low2) / (high1 - low1); + float scale3 = (high3 - low3) / (high1 - low1); + + mat4x4 m1 = mat4x4(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, -low1, + 0, 0, 0, 1 + ); + + mat4x4 m2 = mat4x4(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, scale2, low2, + 0, 0, scale3, low3 + ); + + return m2 * m1; +} + +void _3d_plane_inner(mat4x4 trans) +{ + T0V(VAP_PVS_STATE_FLUSH_REG, 0x00000000); + + ////////////////////////////////////////////////////////////////////////////// + // VAP_PVS + ////////////////////////////////////////////////////////////////////////////// + + const float consts[] = { + // 0 + trans[0][0], trans[0][1], trans[0][2], trans[0][3], + trans[1][0], trans[1][1], trans[1][2], trans[1][3], + trans[2][0], trans[2][1], trans[2][2], trans[2][3], + trans[3][0], trans[3][1], trans[3][2], trans[3][3], + }; + ib_vap_pvs_const_cntl(consts, (sizeof (consts))); + + ////////////////////////////////////////////////////////////////////////////// + // 3D_DRAW + ////////////////////////////////////////////////////////////////////////////// + + const model * model = &plane_model; + const object * obj = model->object[0]; + const int triangle_count = obj->triangle_count; + const int vertex_count = triangle_count * 3; + + const int dwords_per_vtx = 5; + + T0V(VAP_VTX_SIZE + , VAP_VTX_SIZE__DWORDS_PER_VTX(dwords_per_vtx) + ); + + T3(_3D_DRAW_IMMD_2, (1 + vertex_count * dwords_per_vtx) - 1); + TU( VAP_VF_CNTL__PRIM_TYPE(4) + | VAP_VF_CNTL__PRIM_WALK(3) + | VAP_VF_CNTL__INDEX_SIZE(0) + | VAP_VF_CNTL__VTX_REUSE_DIS(0) + | VAP_VF_CNTL__DUAL_INDEX_MODE(0) + | VAP_VF_CNTL__USE_ALT_NUM_VERTS(0) + | VAP_VF_CNTL__NUM_VERTICES(vertex_count) + ); + + for (int i = 0; i < triangle_count; i++) { + for (int j = 0; j < 3; j++) { + vec3 p = model->position[obj->triangle[i][j].position]; + vec2 t = model->texture[obj->triangle[i][j].texture]; + + TF(p.x); + TF(p.y); + TF(p.z); + TF(t.x); + TF(t.y); + } + } +} + +void _3d_plane(struct shaders& shaders, + const mat4x4& world_to_clip, + float theta) +{ + ib_rs_instructions(1); + + ////////////////////////////////////////////////////////////////////////////// + // VAP OUT + ////////////////////////////////////////////////////////////////////////////// + + T0V(VAP_OUT_VTX_FMT_0 + , VAP_OUT_VTX_FMT_0__VTX_POS_PRESENT(1)); + T0V(VAP_OUT_VTX_FMT_1 + , VAP_OUT_VTX_FMT_1__TEX_0_COMP_CNT(4)); + + // + + ib_zbuffer(ZBUFFER_RELOC_INDEX, 1600, 1); // less + + int width = 32; + int height = 32; + int macrotile = 0; + int microtile = 0; + int clamp = 0; // wrap/repeat + ib_texture__1(TEXTUREBUFFER_RELOC_INDEX + PLANE_TEXTURE, + width, height, + macrotile, microtile, + clamp); + + ib_vap_stream_cntl__32(); + + // shaders + T0V(US_PIXSIZE + , US_PIXSIZE__PIX_SIZE(4) + ); + ib_ga_us(&shaders.fragment[PLANE_SHADER]); + ib_vap_pvs(&shaders.vertex[PLANE_SHADER]); + + ////////////////////////////////////////////////////////////////////////////// + // VAP + ////////////////////////////////////////////////////////////////////////////// + + T0V(VAP_CLIP_CNTL + , VAP_CLIP_CNTL__PS_UCP_MODE(3) + ); + + T0V(VAP_VTE_CNTL + , VAP_VTE_CNTL__VPORT_X_SCALE_ENA(1) + | VAP_VTE_CNTL__VPORT_X_OFFSET_ENA(1) + | VAP_VTE_CNTL__VPORT_Y_SCALE_ENA(1) + | VAP_VTE_CNTL__VPORT_Y_OFFSET_ENA(1) + | VAP_VTE_CNTL__VPORT_Z_SCALE_ENA(1) + | VAP_VTE_CNTL__VPORT_Z_OFFSET_ENA(1) + | VAP_VTE_CNTL__VTX_XY_FMT(0) // enable W division + | VAP_VTE_CNTL__VTX_Z_FMT(0) // enable W division + | VAP_VTE_CNTL__VTX_W0_FMT(1) + | VAP_VTE_CNTL__SERIAL_PROC_ENA(0) + ); + + T0V(VAP_CNTL_STATUS + , VAP_CNTL_STATUS__PVS_BYPASS(0) + ); + + ////////////////////////////////////////////////////////////////////////////// + // matrix + ////////////////////////////////////////////////////////////////////////////// + + mat4x4 s = scale(1.0f); + mat4x4 rx = rotate_x(-PI / 2.0f); + mat4x4 local_to_world = s * rx; + + mat4x4 trans = world_to_clip * local_to_world; + + _3d_plane_inner(trans); +} + +void _3d_particle(struct shaders& shaders, + const mat4x4& world_to_clip, + float theta) +{ + // enable blending + T0V(RB3D_BLENDCNTL + , RB3D_BLENDCNTL__ALPHA_BLEND_ENABLE__ENABLE + | RB3D_BLENDCNTL__READ_ENABLE(1) + | RB3D_BLENDCNTL__SRCBLEND__GL_ONE + | RB3D_BLENDCNTL__DESTBLEND__GL_ONE + | RB3D_BLENDCNTL__SRC_ALPHA_0_NO_READ(0) + | RB3D_BLENDCNTL__SRC_ALPHA_1_NO_READ(0) + ); + + ib_rs_instructions(1); + + ////////////////////////////////////////////////////////////////////////////// + // VAP OUT + ////////////////////////////////////////////////////////////////////////////// + + T0V(VAP_OUT_VTX_FMT_0 + , VAP_OUT_VTX_FMT_0__VTX_POS_PRESENT(1)); + T0V(VAP_OUT_VTX_FMT_1 + , VAP_OUT_VTX_FMT_1__TEX_0_COMP_CNT(4)); + + // + + ib_zbuffer(ZBUFFER_RELOC_INDEX, 1600, 1); // less + + int width = 32; + int height = 32; + int macrotile = 0; + int microtile = 0; + int clamp = 0; // wrap/repeat + ib_texture__1(TEXTUREBUFFER_RELOC_INDEX + PARTICLE_TEXTURE, + width, height, + macrotile, microtile, + clamp); + + ib_vap_stream_cntl__32(); + + // shaders + T0V(US_PIXSIZE + , US_PIXSIZE__PIX_SIZE(4) + ); + ib_ga_us(&shaders.fragment[PLANE_SHADER]); + ib_vap_pvs(&shaders.vertex[PLANE_SHADER]); + + ////////////////////////////////////////////////////////////////////////////// + // VAP + ////////////////////////////////////////////////////////////////////////////// + + T0V(VAP_CLIP_CNTL + , VAP_CLIP_CNTL__PS_UCP_MODE(3) + ); + + T0V(VAP_VTE_CNTL + , VAP_VTE_CNTL__VPORT_X_SCALE_ENA(1) + | VAP_VTE_CNTL__VPORT_X_OFFSET_ENA(1) + | VAP_VTE_CNTL__VPORT_Y_SCALE_ENA(1) + | VAP_VTE_CNTL__VPORT_Y_OFFSET_ENA(1) + | VAP_VTE_CNTL__VPORT_Z_SCALE_ENA(1) + | VAP_VTE_CNTL__VPORT_Z_OFFSET_ENA(1) + | VAP_VTE_CNTL__VTX_XY_FMT(0) // enable W division + | VAP_VTE_CNTL__VTX_Z_FMT(0) // enable W division + | VAP_VTE_CNTL__VTX_W0_FMT(1) + | VAP_VTE_CNTL__SERIAL_PROC_ENA(0) + ); + + T0V(VAP_CNTL_STATUS + , VAP_CNTL_STATUS__PVS_BYPASS(0) + ); + + ////////////////////////////////////////////////////////////////////////////// + // matrix + ////////////////////////////////////////////////////////////////////////////// + + mat4x4 s = scale(1.0f); + mat4x4 local_to_world = s; + + mat4x4 trans = world_to_clip * local_to_world; + + _3d_plane_inner(trans); +} + +int indirect_buffer(shaders& shaders, + float theta) +{ + int width = 1600; + int height = 1200; + int pitch = width; + + ib_ix = 0; + + ib_generic_initialization(); + + T0V(RB3D_BLENDCNTL, 0); + T0V(RB3D_ABLENDCNTL, 0); + + ib_viewport(width, height); + ib_colorbuffer(COLORBUFFER_RELOC_INDEX, pitch, 0, 0); + + T0V(GB_ENABLE, 0); + + T0V(US_OUT_FMT_0 + , US_OUT_FMT__OUT_FMT(0) // C4_8 + | US_OUT_FMT__C0_SEL__BLUE + | US_OUT_FMT__C1_SEL__GREEN + | US_OUT_FMT__C2_SEL__RED + | US_OUT_FMT__C3_SEL__ALPHA + | US_OUT_FMT__OUT_SIGN(0) + ); + T0V(US_OUT_FMT_1 + , US_OUT_FMT__OUT_FMT(15) // render target is not used + ); + T0V(US_OUT_FMT_2 + , US_OUT_FMT__OUT_FMT(15) // render target is not used + ); + T0V(US_OUT_FMT_2 + , US_OUT_FMT__OUT_FMT(15) // render target is not used + ); + + load_pvs_shaders(shaders.vertex, shaders.vertex_length); + load_us_shaders(shaders.fragment, shaders.fragment_length); + + ////////////////////////////////////////////////////////////////////////////// + // DRAW + ////////////////////////////////////////////////////////////////////////////// + + mat4x4 aspect = scale(vec3(3.0f/4.0f, 1, 1)); + mat4x4 p = perspective(0.01f, 3.0f, + 0.001f, 0.999f, + 1.0f, 3.0f); + mat4x4 t = translate(vec3(0, 0, 1)); + mat4x4 rx = rotate_x(-PI / 8.0f); + mat4x4 ry = rotate_y(theta * 0.8f); + mat4x4 world_to_view = t * rx * ry; + + mat4x4 world_to_clip = aspect * p * world_to_view; + + _3d_clear(shaders); + _3d_plane(shaders, world_to_clip, theta); + _3d_particle(shaders, world_to_clip, theta); + //_3d_zbuffer(shaders); + + ////////////////////////////////////////////////////////////////////////////// + // padding + ////////////////////////////////////////////////////////////////////////////// + + while ((ib_ix % 8) != 0) { + TU(0x80000000); + } + + return ib_ix; +} + +int main() +{ + struct shaders shaders = { + .vertex = load_shaders(vertex_shader_paths, vertex_shader_paths_length), + .fragment = load_shaders(fragment_shader_paths, fragment_shader_paths_length), + .vertex_length = vertex_shader_paths_length, + .fragment_length = fragment_shader_paths_length, + }; + + void * rmmio = map_pci_resource2(); + + int fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC); + assert(fd != -1); + + const int colorbuffer_size = 1600 * 1200 * 4; + int colorbuffer_handle[2]; + int zbuffer_handle; + int * texturebuffer_handle; + int flush_handle; + + void * colorbuffer_ptr[2]; + void * zbuffer_ptr; + + // colorbuffer + colorbuffer_handle[0] = create_buffer(fd, colorbuffer_size, &colorbuffer_ptr[0]); + colorbuffer_handle[1] = create_buffer(fd, colorbuffer_size, &colorbuffer_ptr[1]); + zbuffer_handle = create_buffer(fd, colorbuffer_size, &zbuffer_ptr); + flush_handle = create_flush_buffer(fd); + texturebuffer_handle = load_textures(fd, textures, textures_length); + + fprintf(stderr, "colorbuffer handle[0] %d\n", colorbuffer_handle[0]); + fprintf(stderr, "colorbuffer handle[1] %d\n", colorbuffer_handle[1]); + fprintf(stderr, "zbuffer handle %d\n", zbuffer_handle); + + int colorbuffer_ix = 0; + float theta = PI * 0.5; + + while (true) { + int ib_dwords = indirect_buffer(shaders, theta); + + drm_radeon_cs(fd, + colorbuffer_handle[colorbuffer_ix], + zbuffer_handle, + flush_handle, + texturebuffer_handle, + textures_length, + ib_dwords); + + primary_surface_address(rmmio, colorbuffer_ix); + + // next state + theta += 0.01f; + colorbuffer_ix = (colorbuffer_ix + 1) & 1; + break; + } + + { + printf("colorbuffer0.data\n"); + int out_fd = open("colorbuffer0.data", O_RDWR|O_CREAT, 0644); + assert(out_fd >= 0); + ssize_t write_length = write(out_fd, colorbuffer_ptr[0], colorbuffer_size); + assert(write_length == colorbuffer_size); + close(out_fd); + } + { + printf("zbuffer.data\n"); + int out_fd = open("zbuffer.data", O_RDWR|O_CREAT, 0644); + assert(out_fd >= 0); + ssize_t write_length = write(out_fd, zbuffer_ptr, colorbuffer_size); + assert(write_length == colorbuffer_size); + close(out_fd); + } + + close(fd); +} diff --git a/src/particle_particle.fs.asm b/src/particle_particle.fs.asm new file mode 100644 index 0000000..bb7d428 --- /dev/null +++ b/src/particle_particle.fs.asm @@ -0,0 +1,10 @@ +-- temp[0]: texture coordinate + +TEX TEX_SEM_WAIT TEX_SEM_ACQUIRE + temp[0].rgba = LD tex[0].rgba temp[0].rgaa ; + +OUT TEX_SEM_WAIT +src0.a = temp[0] , +src0.rgb = temp[0] : + out[0].a = MAX src0.a src0.a , + out[0].rgb = MAX src0.rgb src0.rgb ; diff --git a/src/particle_particle.fs.bin b/src/particle_particle.fs.bin new file mode 100644 index 0000000000000000000000000000000000000000..bbfaa90109838e4c340fb53d5d938c5d4f5c5054 GIT binary patch literal 48 ocmZRtU;qLKCWbEzPe3dfU~OOrGMP9)Sb@off%!lJ11nGj0D>k2$N&HU literal 0 HcmV?d00001 diff --git a/src/particle_particle.vs.asm b/src/particle_particle.vs.asm new file mode 100644 index 0000000..4afd3d8 --- /dev/null +++ b/src/particle_particle.vs.asm @@ -0,0 +1,15 @@ +-- const[0-3]: transform matrix +-- input[0]: position coordinate +-- input[1]: texture coordinate + +-- +-- dot(m[0], v), dot(m[1], v), dot(m[2], v), dot(m[3], v) +-- + +temp[1].x = VE_DOT const[0].xyzw input[0].xyzw ; +temp[1].y = VE_DOT const[1].xyzw input[0].xyzw ; +temp[1].z = VE_DOT const[2].xyzw input[0].xyzw ; +temp[1].w = VE_DOT const[3].xyzw input[0].xyzw ; + +out[0].xyzw = VE_MAX temp[1].xyzw temp[1].xyzw ; +out[1].xyzw = VE_MAX input[1].xyzw input[1].xyzw ; diff --git a/src/particle_particle.vs.bin b/src/particle_particle.vs.bin new file mode 100644 index 0000000000000000000000000000000000000000..9dd7f9ae9ae55c6df18dca67fd7731940b6c187e GIT binary patch literal 96 zcmZQn5MW?pxX8c=!Vms4GAbxAD53Bj7@Sb}4Gc+0e0HV}3<^L#7z6dQD}7*41oFWc G$Oiy*N*X2r literal 0 HcmV?d00001 diff --git a/src/particle_plane.fs.asm b/src/particle_plane.fs.asm new file mode 100644 index 0000000..bb7d428 --- /dev/null +++ b/src/particle_plane.fs.asm @@ -0,0 +1,10 @@ +-- temp[0]: texture coordinate + +TEX TEX_SEM_WAIT TEX_SEM_ACQUIRE + temp[0].rgba = LD tex[0].rgba temp[0].rgaa ; + +OUT TEX_SEM_WAIT +src0.a = temp[0] , +src0.rgb = temp[0] : + out[0].a = MAX src0.a src0.a , + out[0].rgb = MAX src0.rgb src0.rgb ; diff --git a/src/particle_plane.fs.bin b/src/particle_plane.fs.bin new file mode 100644 index 0000000000000000000000000000000000000000..bbfaa90109838e4c340fb53d5d938c5d4f5c5054 GIT binary patch literal 48 ocmZRtU;qLKCWbEzPe3dfU~OOrGMP9)Sb@off%!lJ11nGj0D>k2$N&HU literal 0 HcmV?d00001 diff --git a/src/particle_plane.vs.asm b/src/particle_plane.vs.asm new file mode 100644 index 0000000..bd842f2 --- /dev/null +++ b/src/particle_plane.vs.asm @@ -0,0 +1,15 @@ +-- const[0-3]: transform matrix +-- input[0]: position coordinate +-- input[1]: texture coordinate + +-- +-- dot(m[0], v), dot(m[1], v), dot(m[2], v), dot(m[3], v) +-- + +temp[1].x = VE_DOT const[0].xyzw input[0].xyzw ; +temp[1].y = VE_DOT const[1].xyzw input[0].xyzw ; +temp[1].z = VE_DOT const[2].xyzw input[0].xyzw ; +temp[1].w = VE_DOT const[3].xyzw input[0].xyzw ; + +out[0].xyzw = VE_MAD temp[1].xyzw temp[1].1111 temp[1].0000 ; +out[1].xyzw = VE_MAX input[1].xyzw input[1].xyzw ; diff --git a/src/particle_plane.vs.bin b/src/particle_plane.vs.bin new file mode 100644 index 0000000000000000000000000000000000000000..bade0e5086f87d93841413e61929ffedd53b8471 GIT binary patch literal 96 zcmZQn5MW?pxX8c=!Vms4GAbxAD53Bj7@Sb}4Gc+0d={n;3<^NL!h&2zg$5NycBKyt Lia-Kc+5%+S>=?-@5thfJv?Y-9C=@QTfkSQ&Uq^uX^mEnzNSvFX~91=H}+G zT3T9uTj|T#pQ;01a<;a%MtggEbaZq?XJ_ZHMQ7(%n|OKOts%ML;^^+~j^5th=h!#bj-}m#N6CmEG#U<;^JZ<>FoUC#LJTp=TCZ(`%Z3q znw*@B+1c4xT3U+b<>gpgTZ{Ge_1M_hC?uVoUz~V(S;JS)A-SEMTo_YRQ!zh3A1f;> zvAMY!+uPf*v$GSsySuTsw^v9yJHI&b^0J1n^dh;($Uah#l-6q3%a9&zI3$%g~)vzf%NSLW9Y>7%o>ADH|5`*C!16sM=BaejUt7Z(?C zd3jk#Iy=8O@$%%ufd}`aSt#$_9dd4FNk5&beZf9EJBzEUtGK?tj+>jCxV^nCB%PgK zoOpTi;lP9Y(HSJanRAcbCG%{i^wrtg9}c{CcXx4re;*GI4~3+&^NSNNPd*%YaN$?a zBJT3pdrRDBcgkFwE&X-I_KEB9@iCsBp5poWxsY^resSXE$%g|EZn+0Iy^m#nZ>o3A z+v0w^W9Hnf>9;-FH}030mw0`BEhL?tUz~V(^5MXP3qNPzBYtnHcg@@4e(R+FoUC#LJTp2Oiw7@HcY*`cv=z=M0$3M$CVi-~DXF{m&X2_5LNl9yIFx zFW1nB?;rkh4UPEzmuoN!SwlVl|CDPm4|-AW|9{mrm`QJwyIHUQztuJ9hdT5`E%o^S rU#`LTNneIKlt}BI3owQM-B@( z%p72lG5);_Z+zysi(7uTbI5hE@XlnA2mBu!h8KQjyRaDIJ-F5$ZurdU9;_VX2G5-t z(oJd(F+;t{W4twoT^QsH|LZ=6AAIUfy3SqLT_}UKNxh2?6!sv;cn^K$EQSyM_IsOK z2Jza(UleZhu9!o57c=}r7jl4yGFUlu?jmM*t+sbD!rx+WRp=sRcxf00f_GpbhfNpv z{0y5^hGGukE|j6Xhm=8cIKsb|p}7lZb`ftfFvPd%ssns-Ih^3%VF+EsIVeNOVZ~m2 zy9<3jxXm5{L;Egj2G`t$`@PKz{7-WX+@^~e;yu7121C8c5iH%iuyVM=JIgS{L+|20 z8LT~|3?uw+OAJ;QJLT|1KBX?|XVeqkIR+Qs#buI1v&qf#A=^bi!xaA#L+dtEhWIx3 zW*BVlVvhgL4BEw2l0)d?i}!mO(r475`ojM`Ft}|OSG;H5#Soud4kp7JJJ4s8-NiRP zfnmbyxQik~nnT!w$)L}usmbtzXJDA~I_=_;_skqlGhOI2Dq(P&?{b<$%5YwJSyjrg zLLrBgA)A9TSY7CMn1o^beX`Bq<*UPBx_Hkqv~%$Cj(?XyHyQ8Yp5KcMX%4!F zBEw{}2QO3nVQ@A>+=Vg}_mDE^ZDtwjO?r94zhTJauouH#UCi+wp)P}$pX?^HIUMnM zbDNyod+>4}F-&;9-9yTd?!oLL$Dn&K7`$BJnPG4%{?^W6FNU;>X?G7^PVu;`85~_W z?V_AR*ux`x?Cm0Dn6w$Z9O0)7n!_Cmdnhx69Cl(z??Q8Ey6`f