From 182a82c306acbf00341b3fa4b4f83b36585713b5 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Tue, 4 Nov 2025 12:12:29 -0600 Subject: [PATCH] drm2: more generalized texture loading --- drm2/Makefile | 6 +- drm2/{r500 => drm}/buffer.c | 31 +++++++++ drm2/{r500 => drm}/buffer.h | 3 + drm2/drm/drm.c | 89 +++++++++++++++++++++++++ drm2/drm/drm.h | 22 +++++++ drm2/matrix_cubesphere.cpp | 125 ++++++------------------------------ 6 files changed, 167 insertions(+), 109 deletions(-) rename drm2/{r500 => drm}/buffer.c (69%) rename drm2/{r500 => drm}/buffer.h (60%) create mode 100644 drm2/drm/drm.c create mode 100644 drm2/drm/drm.h diff --git a/drm2/Makefile b/drm2/Makefile index 3f1c9a3..d4b3875 100644 --- a/drm2/Makefile +++ b/drm2/Makefile @@ -14,18 +14,16 @@ FRAGMENT_SHADERS = $(patsubst %.asm,%.bin,$(wildcard *.fs.asm)) SHADER_BIN = $(VERTEX_SHADERS) $(FRAGMENT_SHADERS) R500_COMMON = \ - r500/buffer.o \ r500/display_controller.o \ r500/indirect_buffer.o \ r500/shader.o \ + drm/buffer.o \ + drm/drm.o \ file.o matrix_cubesphere: $(R500_COMMON) matrix_cubesphere.o | shaders $(CXX) $(LDFLAGS) $^ -o $@ -matrix_cubesphere2: $(R500_COMMON) matrix_cubesphere2.o | shaders - $(CXX) $(LDFLAGS) $^ -o $@ - %.o: %.c $(CC) $(ARCH) $(CFLAGS) $(OPT) -c $< -o $@ diff --git a/drm2/r500/buffer.c b/drm2/drm/buffer.c similarity index 69% rename from drm2/r500/buffer.c rename to drm2/drm/buffer.c index 1bcb368..7b0401d 100644 --- a/drm2/r500/buffer.c +++ b/drm2/drm/buffer.c @@ -1,11 +1,13 @@ #include #include #include +#include #include #include #include "buffer.h" +#include "../file.h" int create_buffer(int fd, int buffer_size, void ** out_ptr) { @@ -70,3 +72,32 @@ int create_flush_buffer(int fd) assert(args.handle != 0); return args.handle; } + +int * load_textures(int fd, + const char ** textures, + int textures_length) +{ + int * texturebuffer_handle = (int *)malloc((sizeof (int)) * textures_length); + + for (int i = 0; i < textures_length; i++) { + int size = 0; + void * buf = file_read(textures[i], &size); + assert(buf != NULL); + + printf("load texture[%d]: %d\n", i, size); + + void * ptr = NULL; + int handle = create_buffer(fd, size, &ptr); + + for (int i = 0; i < size / 4; i++) { + ((uint32_t*)ptr)[i] = ((uint32_t*)buf)[i]; + } + asm volatile ("" ::: "memory"); + free(buf); + munmap(ptr, size); + + texturebuffer_handle[i] = handle; + } + + return texturebuffer_handle; +} diff --git a/drm2/r500/buffer.h b/drm2/drm/buffer.h similarity index 60% rename from drm2/r500/buffer.h rename to drm2/drm/buffer.h index 4405a87..1535132 100644 --- a/drm2/r500/buffer.h +++ b/drm2/drm/buffer.h @@ -6,6 +6,9 @@ extern "C" { int create_buffer(int fd, int buffer_size, void ** out_ptr); int create_flush_buffer(int fd); +int * load_textures(int fd, + const char ** textures, + int textures_length); #ifdef __cplusplus } diff --git a/drm2/drm/drm.c b/drm2/drm/drm.c new file mode 100644 index 0000000..14233d6 --- /dev/null +++ b/drm2/drm/drm.c @@ -0,0 +1,89 @@ +#include +#include + +#include +#include + +#include "drm.h" +#include "../r500/indirect_buffer.h" // for extern uint32_t ib[]; + +void drm_radeon_cs(int fd, + int colorbuffer_handle, + int zbuffer_handle, + int flush_handle, + int * texturebuffer_handles, + int texturebuffer_handles_length, + int ib_dwords) +{ + struct drm_radeon_cs_reloc relocs[3 + texturebuffer_handles_length]; + + relocs[COLORBUFFER_RELOC_INDEX] = (struct drm_radeon_cs_reloc){ + .handle = colorbuffer_handle, + .read_domains = 4, // RADEON_GEM_DOMAIN_VRAM + .write_domain = 4, // RADEON_GEM_DOMAIN_VRAM + .flags = 8, + }; + relocs[ZBUFFER_RELOC_INDEX] = (struct drm_radeon_cs_reloc){ + .handle = zbuffer_handle, + .read_domains = 4, // RADEON_GEM_DOMAIN_VRAM + .write_domain = 4, // RADEON_GEM_DOMAIN_VRAM + .flags = 8, + }; + relocs[FLUSH_RELOC_INDEX] = (struct drm_radeon_cs_reloc){ + .handle = flush_handle, + .read_domains = 2, // RADEON_GEM_DOMAIN_GTT + .write_domain = 2, // RADEON_GEM_DOMAIN_GTT + .flags = 0, + }; + + for (int i = 0; i < texturebuffer_handles_length; i++) { + relocs[3 + i] = (struct drm_radeon_cs_reloc){ + .handle = texturebuffer_handles[i], + .read_domains = 4, // RADEON_GEM_DOMAIN_VRAM + .write_domain = 4, // RADEON_GEM_DOMAIN_VRAM + .flags = 8, + }; + } + + const uint32_t flags[2] = { + 5, // RADEON_CS_KEEP_TILING_FLAGS | RADEON_CS_END_OF_FRAME + 0, // RADEON_CS_RING_GFX + }; + + struct drm_radeon_cs_chunk chunks[3] = { + { + .chunk_id = RADEON_CHUNK_ID_IB, + .length_dw = ib_dwords, + .chunk_data = (uint64_t)(uintptr_t)ib, + }, + { + .chunk_id = RADEON_CHUNK_ID_RELOCS, + .length_dw = (sizeof (relocs)) / (sizeof (uint32_t)), + .chunk_data = (uint64_t)(uintptr_t)relocs, + }, + { + .chunk_id = RADEON_CHUNK_ID_FLAGS, + .length_dw = (sizeof (flags)) / (sizeof (uint32_t)), + .chunk_data = (uint64_t)(uintptr_t)&flags, + }, + }; + + uint64_t chunks_array[3] = { + (uint64_t)(uintptr_t)&chunks[0], + (uint64_t)(uintptr_t)&chunks[1], + (uint64_t)(uintptr_t)&chunks[2], + }; + + struct drm_radeon_cs cs = { + .num_chunks = 3, + .cs_id = 0, + .chunks = (uint64_t)(uintptr_t)chunks_array, + .gart_limit = 0, + .vram_limit = 0, + }; + + int ret = drmCommandWriteRead(fd, DRM_RADEON_CS, &cs, (sizeof (struct drm_radeon_cs))); + if (ret != 0) { + perror("drmCommandWriteRead(DRM_RADEON_CS)"); + } +} diff --git a/drm2/drm/drm.h b/drm2/drm/drm.h new file mode 100644 index 0000000..7314dcd --- /dev/null +++ b/drm2/drm/drm.h @@ -0,0 +1,22 @@ +#pragma once + +#define COLORBUFFER_RELOC_INDEX 0 +#define ZBUFFER_RELOC_INDEX 1 +#define FLUSH_RELOC_INDEX 2 +#define TEXTURE_RELOC_INDEX 3 + +#ifdef __cplusplus +extern "C" { +#endif + +void drm_radeon_cs(int fd, + int colorbuffer_handle, + int zbuffer_handle, + int flush_handle, + int * texturebuffer_handles, + int texturebuffer_handles_length, + int ib_dwords); + +#ifdef __cplusplus +} +#endif diff --git a/drm2/matrix_cubesphere.cpp b/drm2/matrix_cubesphere.cpp index 9798a07..dafa375 100644 --- a/drm2/matrix_cubesphere.cpp +++ b/drm2/matrix_cubesphere.cpp @@ -11,18 +11,15 @@ #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 "r500/buffer.h" -#include "file.h" +#include "drm/buffer.h" +#include "drm/drm.h" #include "math/float_types.hpp" #include "math/transform.hpp" @@ -31,10 +28,6 @@ #include "../model/model2.h" #include "../model/cubesphere.h" -#define COLORBUFFER_RELOC_INDEX 0 -#define ZBUFFER_RELOC_INDEX 1 -#define TEXTURE_RELOC_INDEX 2 - #define CUBESPHERE_SHADER 0 #define CLEAR_SHADER 1 @@ -95,8 +88,8 @@ void _3d_clear(struct shaders& shaders) ); T0V(VAP_VTE_CNTL - , VAP_VTE_CNTL__VTX_XY_FMT(1) - | VAP_VTE_CNTL__VTX_Z_FMT(1) + , VAP_VTE_CNTL__VTX_XY_FMT(1) // disable W division + | VAP_VTE_CNTL__VTX_Z_FMT(1) // disable W division ); T0V(VAP_CNTL_STATUS @@ -266,8 +259,8 @@ void _3d_cube(struct shaders& shaders, | VAP_VTE_CNTL__VPORT_Y_OFFSET_ENA(1) | VAP_VTE_CNTL__VPORT_Z_SCALE_ENA(0) | VAP_VTE_CNTL__VPORT_Z_OFFSET_ENA(0) - | VAP_VTE_CNTL__VTX_XY_FMT(0) - | VAP_VTE_CNTL__VTX_Z_FMT(1) + | VAP_VTE_CNTL__VTX_XY_FMT(0) // enable W division + | VAP_VTE_CNTL__VTX_Z_FMT(1) // disable W division | VAP_VTE_CNTL__VTX_W0_FMT(1) | VAP_VTE_CNTL__SERIAL_PROC_ENA(0) ); @@ -400,6 +393,11 @@ int indirect_buffer(shaders& shaders, return ib_ix; } +const char * textures[] = { + "../texture/butterfly_1024x1024_argb8888.data", +}; +const int textures_length = (sizeof (textures)) / (sizeof (textures[0])); + int main() { struct shaders shaders = { @@ -411,18 +409,13 @@ int main() void * rmmio = map_pci_resource2(); - ////////////////////////////////////////////////////////////////////////////// - // DRI card0 - ////////////////////////////////////////////////////////////////////////////// - - int ret; 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 * texturebuffer_handle; int flush_handle; void * colorbuffer_ptr[2]; @@ -433,103 +426,25 @@ int main() 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); - // texture - { - const int texture_size = 1024 * 1024 * 4; - void * texturebuffer_ptr; - - texturebuffer_handle = create_buffer(fd, texture_size, &texturebuffer_ptr); - - void * texture_buf = file_read("../texture/butterfly_1024x1024_argb8888.data", NULL); - assert(texture_buf != NULL); - for (int i = 0; i < texture_size / 4; i++) { - ((uint32_t*)texturebuffer_ptr)[i] = ((uint32_t*)texture_buf)[i]; - } - asm volatile ("" ::: "memory"); - free(texture_buf); - munmap(texturebuffer_ptr, texture_size); - } - - uint32_t flags[2] = { - 5, // RADEON_CS_KEEP_TILING_FLAGS | RADEON_CS_END_OF_FRAME - 0, // RADEON_CS_RING_GFX - }; - int colorbuffer_ix = 0; - float theta = 0; while (true) { int ib_dwords = indirect_buffer(shaders, theta); - struct drm_radeon_cs_reloc relocs[] = { - { - .handle = colorbuffer_handle[colorbuffer_ix], - .read_domains = 4, // RADEON_GEM_DOMAIN_VRAM - .write_domain = 4, // RADEON_GEM_DOMAIN_VRAM - .flags = 8, - }, - { - .handle = zbuffer_handle, - .read_domains = 4, // RADEON_GEM_DOMAIN_VRAM - .write_domain = 4, // RADEON_GEM_DOMAIN_VRAM - .flags = 8, - }, - { - .handle = texturebuffer_handle, - .read_domains = 4, // RADEON_GEM_DOMAIN_VRAM - .write_domain = 4, // RADEON_GEM_DOMAIN_VRAM - .flags = 8, - }, - { - .handle = flush_handle, - .read_domains = 2, // RADEON_GEM_DOMAIN_GTT - .write_domain = 2, // RADEON_GEM_DOMAIN_GTT - .flags = 0, - } - }; - - struct drm_radeon_cs_chunk chunks[3] = { - { - .chunk_id = RADEON_CHUNK_ID_IB, - .length_dw = ib_dwords, - .chunk_data = (uint64_t)(uintptr_t)ib, - }, - { - .chunk_id = RADEON_CHUNK_ID_RELOCS, - .length_dw = (sizeof (relocs)) / (sizeof (uint32_t)), - .chunk_data = (uint64_t)(uintptr_t)relocs, - }, - { - .chunk_id = RADEON_CHUNK_ID_FLAGS, - .length_dw = (sizeof (flags)) / (sizeof (uint32_t)), - .chunk_data = (uint64_t)(uintptr_t)&flags, - }, - }; - - uint64_t chunks_array[3] = { - (uint64_t)(uintptr_t)&chunks[0], - (uint64_t)(uintptr_t)&chunks[1], - (uint64_t)(uintptr_t)&chunks[2], - }; - - struct drm_radeon_cs cs = { - .num_chunks = 3, - .cs_id = 0, - .chunks = (uint64_t)(uintptr_t)chunks_array, - .gart_limit = 0, - .vram_limit = 0, - }; - - ret = drmCommandWriteRead(fd, DRM_RADEON_CS, &cs, (sizeof (struct drm_radeon_cs))); - if (ret != 0) { - perror("drmCommandWriteRead(DRM_RADEON_CS)"); - } + drm_radeon_cs(fd, + colorbuffer_handle[colorbuffer_ix], + zbuffer_handle, + flush_handle, + texturebuffer_handle, + textures_length, + ib_dwords); primary_surface_address(rmmio, colorbuffer_ix);