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 "3d_registers_bits.h"
|
||||||
#include "command_processor.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 {
|
union u32_f32 {
|
||||||
uint32_t u32;
|
uint32_t u32;
|
||||||
float f32;
|
float f32;
|
||||||
@ -23,7 +36,7 @@ union u32_f32 {
|
|||||||
|
|
||||||
static union u32_f32 ib[16384];
|
static union u32_f32 ib[16384];
|
||||||
|
|
||||||
int indirect_buffer()
|
int indirect_buffer(float time)
|
||||||
{
|
{
|
||||||
int ix = 0;
|
int ix = 0;
|
||||||
|
|
||||||
@ -437,7 +450,7 @@ int indirect_buffer()
|
|||||||
// fragment constants
|
// fragment constants
|
||||||
|
|
||||||
const float fragment_consts[] = {
|
const float fragment_consts[] = {
|
||||||
-0.1f, 0, 0, 0,
|
time, 0, 0, 0,
|
||||||
};
|
};
|
||||||
int fragment_consts_length = (sizeof (fragment_consts)) / (sizeof (fragment_consts[0]));
|
int fragment_consts_length = (sizeof (fragment_consts)) / (sizeof (fragment_consts[0]));
|
||||||
|
|
||||||
@ -452,7 +465,7 @@ int indirect_buffer()
|
|||||||
// fragment code
|
// fragment code
|
||||||
|
|
||||||
const uint32_t fragment_shader[] = {
|
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]));
|
const int fragment_shader_length = (sizeof (fragment_shader)) / (sizeof (fragment_shader[0]));
|
||||||
assert(fragment_shader_length % 6 == 0);
|
assert(fragment_shader_length % 6 == 0);
|
||||||
@ -526,18 +539,10 @@ int indirect_buffer()
|
|||||||
return ix;
|
return ix;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int create_colorbuffer(int fd, int colorbuffer_size)
|
||||||
{
|
{
|
||||||
int ret;
|
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 = {
|
struct drm_radeon_gem_create args = {
|
||||||
.size = colorbuffer_size,
|
.size = colorbuffer_size,
|
||||||
.alignment = 4096,
|
.alignment = 4096,
|
||||||
@ -552,12 +557,8 @@ int main()
|
|||||||
}
|
}
|
||||||
assert(args.handle != 0);
|
assert(args.handle != 0);
|
||||||
|
|
||||||
colorbuffer_handle = args.handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
struct drm_radeon_gem_mmap mmap_args = {
|
struct drm_radeon_gem_mmap mmap_args = {
|
||||||
.handle = colorbuffer_handle,
|
.handle = args.handle,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.size = colorbuffer_size,
|
.size = colorbuffer_size,
|
||||||
};
|
};
|
||||||
@ -566,16 +567,57 @@ int main()
|
|||||||
perror("drmCommandWriteRead(DRM_RADEON_GEM_MMAP)");
|
perror("drmCommandWriteRead(DRM_RADEON_GEM_MMAP)");
|
||||||
}
|
}
|
||||||
|
|
||||||
colorbuffer_ptr = mmap(0, mmap_args.size, PROT_READ|PROT_WRITE, MAP_SHARED,
|
void * ptr = mmap(0,
|
||||||
fd, mmap_args.addr_ptr);
|
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++) {
|
for (int i = 0; i < colorbuffer_size / 4; i++) {
|
||||||
((uint32_t*)colorbuffer_ptr)[i] = 0;
|
((uint32_t*)ptr)[i] = 0x00000000;
|
||||||
}
|
}
|
||||||
asm volatile ("" ::: "memory");
|
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
|
// flush
|
||||||
{
|
{
|
||||||
@ -596,12 +638,21 @@ int main()
|
|||||||
flush_handle = args.handle;
|
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[] = {
|
struct drm_radeon_cs_reloc relocs[] = {
|
||||||
{
|
{
|
||||||
.handle = colorbuffer_handle,
|
.handle = colorbuffer_handle[colorbuffer_ix],
|
||||||
.read_domains = 4, // RADEON_GEM_DOMAIN_VRAM
|
.read_domains = 4, // RADEON_GEM_DOMAIN_VRAM
|
||||||
.write_domain = 4, // RADEON_GEM_DOMAIN_VRAM
|
.write_domain = 4, // RADEON_GEM_DOMAIN_VRAM
|
||||||
.flags = 8,
|
.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] = {
|
struct drm_radeon_cs_chunk chunks[3] = {
|
||||||
{
|
{
|
||||||
.chunk_id = RADEON_CHUNK_ID_IB,
|
.chunk_id = RADEON_CHUNK_ID_IB,
|
||||||
@ -659,11 +702,36 @@ int main()
|
|||||||
perror("drmCommandWriteRead(DRM_RADEON_CS)");
|
perror("drmCommandWriteRead(DRM_RADEON_CS)");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drm_radeon_gem_wait_idle args = {
|
#define D1CRTC_DOUBLE_BUFFER_CONTROL 0x60ec
|
||||||
.handle = flush_handle
|
#define D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110
|
||||||
};
|
#define D1GRPH_UPDATE 0x6144
|
||||||
while (drmCommandWrite(fd, DRM_RADEON_GEM_WAIT_IDLE, &args, (sizeof (struct drm_radeon_gem_wait_idle))) == -EBUSY);
|
#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);
|
int out_fd = open("colorbuffer.data", O_RDWR|O_CREAT);
|
||||||
assert(out_fd >= 0);
|
assert(out_fd >= 0);
|
||||||
ssize_t write_length = write(out_fd, colorbuffer_ptr, colorbuffer_size);
|
ssize_t write_length = write(out_fd, colorbuffer_ptr, colorbuffer_size);
|
||||||
@ -682,8 +750,7 @@ int main()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(mm_fd);
|
close(mm_fd);
|
||||||
|
*/
|
||||||
munmap(colorbuffer_ptr, colorbuffer_size);
|
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# d = length(uv)
|
-- d = length(uv)
|
||||||
src0.rgb = temp[0] :
|
src0.rgb = temp[0] :
|
||||||
temp[0].r = DP3 src0.rg0 src0.rg0 ;
|
temp[0].r = DP3 src0.rg0 src0.rg0 ;
|
||||||
src0.rgb = temp[0] :
|
src0.rgb = temp[0] :
|
||||||
@ -6,16 +6,17 @@ src0.rgb = temp[0] :
|
|||||||
src0.a = temp[0] :
|
src0.a = temp[0] :
|
||||||
temp[0].a = RCP src0.a ;
|
temp[0].a = RCP src0.a ;
|
||||||
|
|
||||||
# d = d * 1.625 + 0
|
-- d = d * 1.625 + time
|
||||||
src0.a = temp[0],
|
src0.a = temp[0],
|
||||||
src1.a = float(61) : # 1.625
|
src1.a = float(61), -- 1.625
|
||||||
temp[0].a = MAD src0.a src1.a src0.0 ;
|
src2.rgb = const[0] :
|
||||||
|
temp[0].a = MAD src0.a src1.a src2.r ;
|
||||||
|
|
||||||
# d = frc(d)
|
-- d = frc(d)
|
||||||
src0.a = temp[0] :
|
src0.a = temp[0] :
|
||||||
temp[0].a = FRC src0.a ;
|
temp[0].a = FRC src0.a ;
|
||||||
|
|
||||||
# d = cos(d * 2π)
|
-- d = cos(d * 2π)
|
||||||
OUT TEX_SEM_WAIT
|
OUT TEX_SEM_WAIT
|
||||||
src0.a = temp[0] :
|
src0.a = temp[0] :
|
||||||
COS src0.a ,
|
COS src0.a ,
|
||||||
|
|||||||
@ -972,6 +972,10 @@ int main()
|
|||||||
colorbuffer_handle[1] = create_colorbuffer(fd, colorbuffer_size);
|
colorbuffer_handle[1] = create_colorbuffer(fd, colorbuffer_size);
|
||||||
zbuffer_handle = 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
|
// texture
|
||||||
{
|
{
|
||||||
const int texture_size = 1024 * 1024 * 4;
|
const int texture_size = 1024 * 1024 * 4;
|
||||||
@ -1037,16 +1041,12 @@ int main()
|
|||||||
flush_handle = args.handle;
|
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] = {
|
uint32_t flags[2] = {
|
||||||
5, // RADEON_CS_KEEP_TILING_FLAGS | RADEON_CS_END_OF_FRAME
|
5, // RADEON_CS_KEEP_TILING_FLAGS | RADEON_CS_END_OF_FRAME
|
||||||
0, // RADEON_CS_RING_GFX
|
0, // RADEON_CS_RING_GFX
|
||||||
};
|
};
|
||||||
|
|
||||||
int ib_dwords = indirect_buffer(0);
|
int ib_dwords = indirect_buffer(0);
|
||||||
//int ib_dwords = (sizeof (ib2)) / (sizeof (ib2[0]));
|
|
||||||
|
|
||||||
int colorbuffer_ix = 0;
|
int colorbuffer_ix = 0;
|
||||||
float theta = 0;
|
float theta = 0;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user