diff options
Diffstat (limited to 'sdl_gpu_test.c')
-rw-r--r-- | sdl_gpu_test.c | 192 |
1 files changed, 94 insertions, 98 deletions
diff --git a/sdl_gpu_test.c b/sdl_gpu_test.c index 30e6b83..e769d4c 100644 --- a/sdl_gpu_test.c +++ b/sdl_gpu_test.c @@ -13,32 +13,25 @@ SDL_Window *win; SDL_GPUDevice *gpudev; SDL_GPUGraphicsPipeline *pipeline_fill; -SDL_GPUBuffer *buf_vert; -SDL_GPUTransferBuffer *buf_vert_xfer; +SDL_GPUBuffer *ptbuf; +SDL_GPUTransferBuffer *ptbuf_xfer; -typedef struct { - float x, y; - float u, v; -} Vertex; - -Vertex vertices[] = { - { -1, -1, 0, 0, }, - { 0, -1, 1, 0, }, - { 0, 0, 1, 1, }, - - { -1, -1, 0, 0, }, - { -1, 0, 0, 1, }, - { 0, 0, 1, 1, }, +typedef enum { + PT_CLOUD, + PT_FLASH +} ParticleType; - { 0, 0, 0, 0, }, - { 1, 0, 1, 0, }, - { 1, 1, 1, 1, }, +typedef struct __attribute__((packed)) { + vec2 pos; + float radius, life; + vec3 color; + int type; +} Particle; - { 0, 0, 0, 0, }, - { 0, 1, 0, 1, }, - { 1, 1, 1, 1, }, +#define PT_MAX 65536 -}; +Particle pts[PT_MAX]; +size_t npt = 0; typedef struct { SDL_GPUShaderStage stage; @@ -85,56 +78,30 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { SDL_GPUShader *shader_vert = load_shader(gpudev, "shader/tri.vert.spv", &(ShaderDesc) { .stage = SDL_GPU_SHADERSTAGE_VERTEX, - .n_uniformbuf = 1 + .n_uniformbuf = 1, + .n_storagebuf = 1, }); CHECK(shader_vert, "load vertex shader"); SDL_GPUShader *shader_frag = load_shader(gpudev, "shader/tri.frag.spv", &(ShaderDesc) { SDL_GPU_SHADERSTAGE_FRAGMENT }); CHECK(shader_frag, "load fragment shader"); - buf_vert = SDL_CreateGPUBuffer(gpudev, &(SDL_GPUBufferCreateInfo) { - .usage = SDL_GPU_BUFFERUSAGE_VERTEX, - .size = sizeof(vertices), + ptbuf = SDL_CreateGPUBuffer(gpudev, &(SDL_GPUBufferCreateInfo) { + .usage = SDL_GPU_BUFFERUSAGE_GRAPHICS_STORAGE_READ, + .size = sizeof(pts), .props = 0 }); - CHECK(buf_vert, "vertex buffer"); + CHECK(ptbuf, "vertex buffer"); - buf_vert_xfer = SDL_CreateGPUTransferBuffer( + ptbuf_xfer = SDL_CreateGPUTransferBuffer( gpudev, &(SDL_GPUTransferBufferCreateInfo) { .usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD, - .size = sizeof(vertices), + .size = sizeof(pts), .props = 0 } ); - CHECK(buf_vert_xfer, "vertex transfer buffer"); - - void *map = SDL_MapGPUTransferBuffer(gpudev, buf_vert_xfer, false); - SDL_memcpy(map, vertices, sizeof(vertices)); - SDL_UnmapGPUTransferBuffer(gpudev, buf_vert_xfer); - - SDL_GPUCommandBuffer *cmdbuf = SDL_AcquireGPUCommandBuffer(gpudev); - CHECK(cmdbuf, "gpu command buffer acquisition"); - SDL_GPUCopyPass *copypass = SDL_BeginGPUCopyPass(cmdbuf); - CHECK(copypass, "gpu copy pass"); - - SDL_UploadToGPUBuffer( - copypass, - &(SDL_GPUTransferBufferLocation) { - .transfer_buffer = buf_vert_xfer, - .offset = 0 - }, - &(SDL_GPUBufferRegion) { - .buffer = buf_vert, - .offset = 0, - .size = sizeof(vertices) - }, - false - ); - - SDL_EndGPUCopyPass(copypass); - SDL_SubmitGPUCommandBuffer(cmdbuf); - SDL_ReleaseGPUTransferBuffer(gpudev, buf_vert_xfer); + CHECK(ptbuf_xfer, "vertex transfer buffer"); pipeline_fill = SDL_CreateGPUGraphicsPipeline(gpudev, &(SDL_GPUGraphicsPipelineCreateInfo) { .target_info = { @@ -155,30 +122,6 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { .primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, .vertex_shader = shader_vert, .fragment_shader = shader_frag, - .vertex_input_state = { - .num_vertex_buffers = 1, - .vertex_buffer_descriptions = &(SDL_GPUVertexBufferDescription) { - .slot = 0, - .pitch = sizeof(Vertex), - .input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX, - .instance_step_rate = 0, - }, - .num_vertex_attributes = 2, - .vertex_attributes = (SDL_GPUVertexAttribute[]) { - { - .location = 0, - .buffer_slot = 0, - .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2, - .offset = 0 - }, - { - .location = 1, - .buffer_slot = 0, - .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2, - .offset = sizeof(float) * 2 - } - } - }, .rasterizer_state = { .fill_mode = SDL_GPU_FILLMODE_FILL }, @@ -219,6 +162,28 @@ SDL_AppResult SDL_AppIterate(void *appstate) { SDL_GPUCommandBuffer *cmdbuf = SDL_AcquireGPUCommandBuffer(gpudev); CHECK(cmdbuf, "gpu cmd buffer acquisition"); + void *map = SDL_MapGPUTransferBuffer(gpudev, ptbuf_xfer, true); + SDL_memcpy(map, pts, sizeof(Particle) * (npt < PT_MAX ? npt : PT_MAX)); + SDL_UnmapGPUTransferBuffer(gpudev, ptbuf_xfer); + + SDL_GPUCopyPass *copypass = SDL_BeginGPUCopyPass(cmdbuf); + CHECK(copypass, "gpu copy pass"); + + SDL_UploadToGPUBuffer( + copypass, + &(SDL_GPUTransferBufferLocation) { + .transfer_buffer = ptbuf_xfer, + .offset = 0 + }, + &(SDL_GPUBufferRegion) { + .buffer = ptbuf, + .offset = 0, + .size = sizeof(pts) + }, + false + ); + SDL_EndGPUCopyPass(copypass); + SDL_GPUTexture *swapchain; Uint32 swc_width, swc_height; CHECK(SDL_WaitAndAcquireGPUSwapchainTexture(cmdbuf, win, &swapchain, &swc_width, &swc_height), "swapchain texture acquisition"); @@ -231,25 +196,54 @@ SDL_AppResult SDL_AppIterate(void *appstate) { last = now; t += dt; - float mx, my; - SDL_GetMouseState(&mx, &my); - mx -= swc_width * 0.5f; - my -= swc_height * 0.5f; - mx *= 1.0f / fminf(swc_width, swc_height); - my *= 1.0f / fminf(swc_width, swc_height); - - float rot = t; + float rot = 0; + static float rot_vel = 0; + static vec2 pos = { 0 }, vel = { 0 }; + rot += rot_vel * dt; + rot_vel *= expf(-1.0f * dt); + + const bool *kbd = SDL_GetKeyboardState(0); + float spd = 128 * dt; + if (kbd[SDL_SCANCODE_LSHIFT]) spd *= 10; + if (kbd[SDL_SCANCODE_LEFT]) vel[0] -= spd; + if (kbd[SDL_SCANCODE_RIGHT]) vel[0] += spd; + if (kbd[SDL_SCANCODE_UP]) vel[1] += spd; + if (kbd[SDL_SCANCODE_DOWN]) vel[1] -= spd; + pos[0] += vel[0] * dt; + pos[1] += vel[1] * dt; + glm_vec2_scale(vel, expf(-dt), vel); mat4 cam_mat; - static float x = 0, y = 0; - float s = sinf(-rot), c = cosf(-rot); - float dx = mx * dt * 10; - float dy = -my * dt * 10; - x += dx * c - dy * s; - y += dy * c + dx * s; - build_cam_mat(cam_mat, swc_width, swc_height, x, y, 0.1, rot); + for (int i = 0; i < npt; i++) { + pts[i].life -= dt; + if (pts[i].life < 0) { + if (i + 1 < npt) { + pts[i] = pts[--npt]; + i--; + continue; + } + } + } + + float v = hypotf(vel[0], vel[1]); + float scale = 0.1 / (1 + 0.05 * v); + static size_t npti = 0; + for (int i = 0; i < 1 + dt * v; i++) { + float sz = 1 + dt * v * 5; + vec2 ofs = { (SDL_randf()*2-1) * sz, (SDL_randf()*2-1) * sz }; + pts[npti++ % PT_MAX] = (Particle) { + .pos = { pos[0] + ofs[0], pos[1] + ofs[1] }, + .radius = SDL_randf() * 2, + .life = 10, + .color = { SDL_randf(), SDL_randf(), SDL_randf() }, + .type = PT_CLOUD + }; + npt = npti < PT_MAX ? npti : PT_MAX; + } + printf("%0.2f FPS : %zu\n", 1.0f / dt, npt); + build_cam_mat(cam_mat, swc_width, swc_height, pos[0], pos[1], scale, rot); SDL_PushGPUVertexUniformData(cmdbuf, 0, &cam_mat, sizeof(cam_mat)); SDL_GPURenderPass *render_pass = SDL_BeginGPURenderPass( cmdbuf, @@ -263,8 +257,8 @@ SDL_AppResult SDL_AppIterate(void *appstate) { NULL ); SDL_BindGPUGraphicsPipeline(render_pass, pipeline_fill); - SDL_BindGPUVertexBuffers(render_pass, 0, &(SDL_GPUBufferBinding) { .buffer = buf_vert, .offset = 0 }, 1); - SDL_DrawGPUPrimitives(render_pass, sizeof(vertices) / sizeof(Vertex), 1, 0, 0); + SDL_BindGPUVertexStorageBuffers(render_pass, 0, &ptbuf, 1); + SDL_DrawGPUPrimitives(render_pass, 6 * (npt < PT_MAX ? npt : PT_MAX), 1, 0, 0); SDL_EndGPURenderPass(render_pass); SDL_SubmitGPUCommandBuffer(cmdbuf); @@ -274,6 +268,8 @@ SDL_AppResult SDL_AppIterate(void *appstate) { void SDL_AppQuit(void *appstate, SDL_AppResult result) { (void)appstate; (void)result; + SDL_ReleaseGPUTransferBuffer(gpudev, ptbuf_xfer); + SDL_ReleaseGPUBuffer(gpudev, ptbuf); SDL_ReleaseGPUGraphicsPipeline(gpudev, pipeline_fill); SDL_ReleaseWindowFromGPUDevice(gpudev, win); SDL_DestroyGPUDevice(gpudev); |