drm/shadertoy: add time-based animation
This commit is contained in:
parent
ae3fa0f2e6
commit
b4310b4fef
145
drm/shadertoy.c
145
drm/shadertoy.c
@ -16,6 +16,19 @@
|
||||
#include "3d_registers_bits.h"
|
||||
#include "command_processor.h"
|
||||
|
||||
static inline uint32_t rreg(void * rmmio, uint32_t offset)
|
||||
{
|
||||
uint32_t value = *((volatile uint32_t *)(((uintptr_t)rmmio) + offset));
|
||||
asm volatile ("" ::: "memory");
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline void wreg(void * rmmio, uint32_t offset, uint32_t value)
|
||||
{
|
||||
*((volatile uint32_t *)(((uintptr_t)rmmio) + offset)) = value;
|
||||
asm volatile ("" ::: "memory");
|
||||
}
|
||||
|
||||
union u32_f32 {
|
||||
uint32_t u32;
|
||||
float f32;
|
||||
@ -23,7 +36,7 @@ union u32_f32 {
|
||||
|
||||
static union u32_f32 ib[16384];
|
||||
|
||||
int indirect_buffer()
|
||||
int indirect_buffer(float time)
|
||||
{
|
||||
int ix = 0;
|
||||
|
||||
@ -437,7 +450,7 @@ int indirect_buffer()
|
||||
// fragment constants
|
||||
|
||||
const float fragment_consts[] = {
|
||||
-0.1f, 0, 0, 0,
|
||||
time, 0, 0, 0,
|
||||
};
|
||||
int fragment_consts_length = (sizeof (fragment_consts)) / (sizeof (fragment_consts[0]));
|
||||
|
||||
@ -452,7 +465,7 @@ int indirect_buffer()
|
||||
// fragment code
|
||||
|
||||
const uint32_t fragment_shader[] = {
|
||||
#include "shadertoy_circle.fs.inc"
|
||||
#include "shadertoy_sin.fs.inc"
|
||||
};
|
||||
const int fragment_shader_length = (sizeof (fragment_shader)) / (sizeof (fragment_shader[0]));
|
||||
assert(fragment_shader_length % 6 == 0);
|
||||
@ -526,18 +539,10 @@ int indirect_buffer()
|
||||
return ix;
|
||||
}
|
||||
|
||||
int main()
|
||||
int create_colorbuffer(int fd, int colorbuffer_size)
|
||||
{
|
||||
int ret;
|
||||
int fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
|
||||
|
||||
const int colorbuffer_size = 1600 * 1200 * 4;
|
||||
int colorbuffer_handle;
|
||||
void * colorbuffer_ptr;
|
||||
int flush_handle;
|
||||
|
||||
// colorbuffer
|
||||
{
|
||||
struct drm_radeon_gem_create args = {
|
||||
.size = colorbuffer_size,
|
||||
.alignment = 4096,
|
||||
@ -552,12 +557,8 @@ int main()
|
||||
}
|
||||
assert(args.handle != 0);
|
||||
|
||||
colorbuffer_handle = args.handle;
|
||||
}
|
||||
|
||||
{
|
||||
struct drm_radeon_gem_mmap mmap_args = {
|
||||
.handle = colorbuffer_handle,
|
||||
.handle = args.handle,
|
||||
.offset = 0,
|
||||
.size = colorbuffer_size,
|
||||
};
|
||||
@ -566,16 +567,57 @@ int main()
|
||||
perror("drmCommandWriteRead(DRM_RADEON_GEM_MMAP)");
|
||||
}
|
||||
|
||||
colorbuffer_ptr = mmap(0, mmap_args.size, PROT_READ|PROT_WRITE, MAP_SHARED,
|
||||
fd, mmap_args.addr_ptr);
|
||||
}
|
||||
void * ptr = mmap(0,
|
||||
colorbuffer_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
fd,
|
||||
mmap_args.addr_ptr);
|
||||
assert(ptr != MAP_FAILED);
|
||||
|
||||
{ // clear colorbuffer
|
||||
// clear colorbuffer
|
||||
for (int i = 0; i < colorbuffer_size / 4; i++) {
|
||||
((uint32_t*)colorbuffer_ptr)[i] = 0;
|
||||
((uint32_t*)ptr)[i] = 0x00000000;
|
||||
}
|
||||
asm volatile ("" ::: "memory");
|
||||
}
|
||||
|
||||
munmap(ptr, colorbuffer_size);
|
||||
|
||||
return args.handle;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// PCI resource0
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
const char * resource2_path = "/sys/bus/pci/devices/0000:01:00.0/resource2";
|
||||
int resource2_fd = open(resource2_path, O_RDWR | O_SYNC);
|
||||
assert(resource2_fd >= 0);
|
||||
|
||||
uint32_t resource2_size = 0x10000;
|
||||
void * resource2_base = mmap(0, resource2_size, PROT_READ | PROT_WRITE, MAP_SHARED, resource2_fd, 0);
|
||||
assert(resource2_base != MAP_FAILED);
|
||||
|
||||
void * rmmio = resource2_base;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// DRI card0
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int ret;
|
||||
int fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
|
||||
|
||||
const int colorbuffer_size = 1600 * 1200 * 4;
|
||||
int colorbuffer_handle[2];
|
||||
int flush_handle;
|
||||
|
||||
// colorbuffer
|
||||
colorbuffer_handle[0] = create_colorbuffer(fd, colorbuffer_size);
|
||||
colorbuffer_handle[1] = create_colorbuffer(fd, colorbuffer_size);
|
||||
|
||||
fprintf(stderr, "colorbuffer handle[0] %d\n", colorbuffer_handle[0]);
|
||||
fprintf(stderr, "colorbuffer handle[1] %d\n", colorbuffer_handle[1]);
|
||||
|
||||
// flush
|
||||
{
|
||||
@ -596,12 +638,21 @@ int main()
|
||||
flush_handle = args.handle;
|
||||
}
|
||||
|
||||
uint32_t flags[2] = {
|
||||
5, // RADEON_CS_KEEP_TILING_FLAGS | RADEON_CS_END_OF_FRAME
|
||||
0, // RADEON_CS_RING_GFX
|
||||
};
|
||||
|
||||
fprintf(stderr, "colorbuffer handle %d\n", colorbuffer_handle);
|
||||
float time = 0;
|
||||
|
||||
int ib_dwords = indirect_buffer(time);
|
||||
|
||||
int colorbuffer_ix = 0;
|
||||
|
||||
while (true) {
|
||||
struct drm_radeon_cs_reloc relocs[] = {
|
||||
{
|
||||
.handle = colorbuffer_handle,
|
||||
.handle = colorbuffer_handle[colorbuffer_ix],
|
||||
.read_domains = 4, // RADEON_GEM_DOMAIN_VRAM
|
||||
.write_domain = 4, // RADEON_GEM_DOMAIN_VRAM
|
||||
.flags = 8,
|
||||
@ -614,14 +665,6 @@ int main()
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t flags[2] = {
|
||||
5, // RADEON_CS_KEEP_TILING_FLAGS | RADEON_CS_END_OF_FRAME
|
||||
0, // RADEON_CS_RING_GFX
|
||||
};
|
||||
|
||||
int ib_dwords = indirect_buffer();
|
||||
//int ib_dwords = (sizeof (ib2)) / (sizeof (ib2[0]));
|
||||
|
||||
struct drm_radeon_cs_chunk chunks[3] = {
|
||||
{
|
||||
.chunk_id = RADEON_CHUNK_ID_IB,
|
||||
@ -659,11 +702,36 @@ int main()
|
||||
perror("drmCommandWriteRead(DRM_RADEON_CS)");
|
||||
}
|
||||
|
||||
struct drm_radeon_gem_wait_idle args = {
|
||||
.handle = flush_handle
|
||||
};
|
||||
while (drmCommandWrite(fd, DRM_RADEON_GEM_WAIT_IDLE, &args, (sizeof (struct drm_radeon_gem_wait_idle))) == -EBUSY);
|
||||
#define D1CRTC_DOUBLE_BUFFER_CONTROL 0x60ec
|
||||
#define D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110
|
||||
#define D1GRPH_UPDATE 0x6144
|
||||
#define D1GRPH_UPDATE__D1GRPH_SURFACE_UPDATE_PENDING (1 << 2)
|
||||
|
||||
uint32_t d1crtc_double_buffer_control = rreg(rmmio, D1CRTC_DOUBLE_BUFFER_CONTROL);
|
||||
printf("D1CRTC_DOUBLE_BUFFER_CONTROL: %08x\n", d1crtc_double_buffer_control);
|
||||
assert(d1crtc_double_buffer_control == (1 << 8));
|
||||
|
||||
// addresses were retrieved from /sys/kernel/debug/radeon_vram_mm
|
||||
//
|
||||
// This assumes GEM buffer allocation always starts from the lowest
|
||||
// unallocated address.
|
||||
const uint32_t colorbuffer_addresses[2] = {
|
||||
0x813000,
|
||||
0xf66000,
|
||||
};
|
||||
|
||||
wreg(rmmio, D1GRPH_PRIMARY_SURFACE_ADDRESS, colorbuffer_addresses[colorbuffer_ix]);
|
||||
while ((rreg(rmmio, D1GRPH_UPDATE) & D1GRPH_UPDATE__D1GRPH_SURFACE_UPDATE_PENDING) != 0);
|
||||
|
||||
// next state
|
||||
time += 0.01f;
|
||||
colorbuffer_ix = (colorbuffer_ix + 1) & 1;
|
||||
|
||||
// next indirect buffer
|
||||
ib_dwords = indirect_buffer(time);
|
||||
}
|
||||
|
||||
/*
|
||||
int out_fd = open("colorbuffer.data", O_RDWR|O_CREAT);
|
||||
assert(out_fd >= 0);
|
||||
ssize_t write_length = write(out_fd, colorbuffer_ptr, colorbuffer_size);
|
||||
@ -682,8 +750,7 @@ int main()
|
||||
}
|
||||
}
|
||||
close(mm_fd);
|
||||
|
||||
munmap(colorbuffer_ptr, colorbuffer_size);
|
||||
*/
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# d = length(uv)
|
||||
-- d = length(uv)
|
||||
src0.rgb = temp[0] :
|
||||
temp[0].r = DP3 src0.rg0 src0.rg0 ;
|
||||
src0.rgb = temp[0] :
|
||||
@ -6,16 +6,17 @@ src0.rgb = temp[0] :
|
||||
src0.a = temp[0] :
|
||||
temp[0].a = RCP src0.a ;
|
||||
|
||||
# d = d * 1.625 + 0
|
||||
-- d = d * 1.625 + time
|
||||
src0.a = temp[0],
|
||||
src1.a = float(61) : # 1.625
|
||||
temp[0].a = MAD src0.a src1.a src0.0 ;
|
||||
src1.a = float(61), -- 1.625
|
||||
src2.rgb = const[0] :
|
||||
temp[0].a = MAD src0.a src1.a src2.r ;
|
||||
|
||||
# d = frc(d)
|
||||
-- d = frc(d)
|
||||
src0.a = temp[0] :
|
||||
temp[0].a = FRC src0.a ;
|
||||
|
||||
# d = cos(d * 2π)
|
||||
-- d = cos(d * 2π)
|
||||
OUT TEX_SEM_WAIT
|
||||
src0.a = temp[0] :
|
||||
COS src0.a ,
|
||||
|
||||
@ -972,6 +972,10 @@ int main()
|
||||
colorbuffer_handle[1] = create_colorbuffer(fd, colorbuffer_size);
|
||||
zbuffer_handle = create_colorbuffer(fd, colorbuffer_size);
|
||||
|
||||
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;
|
||||
@ -1037,16 +1041,12 @@ int main()
|
||||
flush_handle = args.handle;
|
||||
}
|
||||
|
||||
fprintf(stderr, "colorbuffer handle[0] %d\n", colorbuffer_handle[0]);
|
||||
fprintf(stderr, "colorbuffer handle[1] %d\n", colorbuffer_handle[1]);
|
||||
|
||||
uint32_t flags[2] = {
|
||||
5, // RADEON_CS_KEEP_TILING_FLAGS | RADEON_CS_END_OF_FRAME
|
||||
0, // RADEON_CS_RING_GFX
|
||||
};
|
||||
|
||||
int ib_dwords = indirect_buffer(0);
|
||||
//int ib_dwords = (sizeof (ib2)) / (sizeof (ib2[0]));
|
||||
|
||||
int colorbuffer_ix = 0;
|
||||
float theta = 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user