Skip to content

Commit ed3967d

Browse files
committed
GPU uses improved queue for commands
1 parent fb1270e commit ed3967d

File tree

5 files changed

+138
-122
lines changed

5 files changed

+138
-122
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ include_directories(lib/)
1111
include_directories(src/)
1212

1313
add_executable(main src/main.c src/glad.c src/window.c src/shader.c src/camera.c src/block.c src/chunk.c src/world.c src/player.c src/direction.c
14-
src/atlas.c src/gpu.c src/hashtable.c src/stack.c src/fixed_array.c src/queue.c src/frustum.c src/chunk_mesh.c)
14+
src/atlas.c src/gpu.c src/hashtable.c src/stack.c src/fixed_array.c src/queue_og.c src/frustum.c src/chunk_mesh.c src/queue.c)
1515
set_property(TARGET main PROPERTY C_STANDARD 11)
1616

1717
if( WIN32 )

src/gpu.c

+101-102
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ void _gpu_create_command(gpu * gpu, enum command_types type, void * args){
230230
assert(com);
231231
com->type = type;
232232
com->args = args;
233-
queue_enqueue(gpu->command_queue, (void *) com);
233+
queue_produce(gpu->command_queue, (void *) com);
234234
}
235235

236236
void gpu_set_VAO(gpu* gpu, uint64_t vao_index){
@@ -478,108 +478,107 @@ void* render_thread_init(void * thread_args){
478478
printf("render thread looping\n");
479479
bool running = true;
480480
while(running){
481-
if(!queue_is_empty(gpu->command_queue)){
482-
gpu_command *command = queue_dequeue(gpu->command_queue);
483-
switch (command->type)
484-
{
485-
case COMMAND_UPLOAD:
486-
{
487-
struct gpu_command_upload * args = command->args;
488-
_gpu_upload(gpu, args->chunk_index, args->c);
489-
break;
490-
}
491-
case COMMAND_DRAW_CHUNK:
492-
{
493-
struct gpu_command_draw_chunk * args = command->args;
494-
_gpu_draw_chunk(gpu, args);
495-
break;
496-
}
497-
case COMMAND_SCREEN_CLEAR:
498-
{
499-
_gpu_clear_screen(gpu);
500-
break;
501-
}
502-
case COMMAND_DRAW_END:
503-
{
504-
glfwSwapBuffers(*th_args->window_handle);
505-
glfwPollEvents();
506-
pthread_mutex_unlock(&gpu->draw_mutex);
507-
break;
508-
}
509-
case COMMAND_DRAW_START:
510-
{
511-
pthread_mutex_lock(&gpu->draw_mutex);
512-
break;
513-
}
514-
case COMMAND_SHADER_INIT:
515-
{
516-
struct gpu_command_shader_init * args = command->args;
517-
_gpu_shader_init(gpu, args);
518-
break;
519-
}
520-
case COMMAND_SHADER_USE:
521-
{
522-
struct gpu_command_shader_init * args = command->args;
523-
_gpu_shader_use(gpu, args);
524-
break;
525-
}
526-
case COMMAND_DRAW_SKYBOX:
527-
{
528-
struct gpu_command_draw_skybox * args = command->args;
529-
_gpu_draw_skybox(gpu, args);
530-
break;
531-
}
532-
case COMMAND_SHADER_SET_M4:
533-
{
534-
struct gpu_command_shader_mat4 * args = command->args;
535-
_gpu_shader_set_m4(gpu, args);
536-
break;
537-
}
538-
case COMMAND_SHADER_SET_TRANSFORM_MAT:
539-
{
540-
struct gpu_command_shader_transform_mat * args = command->args;
541-
_gpu_shader_set_transform_matrices(gpu, args);
542-
break;
543-
}
544-
case COMMAND_SHADER_SET_FLOAT:
545-
{
546-
struct gpu_command_shader_float * args = command->args;
547-
_gpu_shader_set_float(gpu, args);
548-
break;
549-
}
550-
case COMMAND_SHADER_SET_FLOAT4:
551-
{
552-
struct gpu_command_shader_vec4 * args = command->args;
553-
_gpu_shader_set_float4(gpu, args);
554-
break;
555-
}
556-
case COMMAND_SHADER_CLEANUP:
557-
{
558-
struct gpu_command_shader_init * args = command->args;
559-
_gpu_shader_cleanup(gpu, args);
560-
break;
561-
}
562-
case COMMAND_SHADER_RELOAD:
563-
{
564-
_gpu_shader_reload(gpu);
565-
break;
566-
}
567-
case COMMAND_WIREFRAME:
568-
{
569-
_gpu_cycle_wireframe(gpu);
570-
break;
571-
}
572-
case COMMAND_CLEANUP:
573-
{
574-
running = false;
575-
break;
576-
}
577-
default:
578-
break;
579-
}
580-
free(command->args);
581-
free(command);
481+
gpu_command *command = queue_consume(gpu->command_queue);
482+
483+
switch (command->type)
484+
{
485+
case COMMAND_UPLOAD:
486+
{
487+
struct gpu_command_upload * args = command->args;
488+
_gpu_upload(gpu, args->chunk_index, args->c);
489+
break;
490+
}
491+
case COMMAND_DRAW_CHUNK:
492+
{
493+
struct gpu_command_draw_chunk * args = command->args;
494+
_gpu_draw_chunk(gpu, args);
495+
break;
496+
}
497+
case COMMAND_SCREEN_CLEAR:
498+
{
499+
_gpu_clear_screen(gpu);
500+
break;
501+
}
502+
case COMMAND_DRAW_END:
503+
{
504+
glfwSwapBuffers(*th_args->window_handle);
505+
glfwPollEvents();
506+
pthread_mutex_unlock(&gpu->draw_mutex);
507+
break;
508+
}
509+
case COMMAND_DRAW_START:
510+
{
511+
pthread_mutex_lock(&gpu->draw_mutex);
512+
break;
513+
}
514+
case COMMAND_SHADER_INIT:
515+
{
516+
struct gpu_command_shader_init * args = command->args;
517+
_gpu_shader_init(gpu, args);
518+
break;
519+
}
520+
case COMMAND_SHADER_USE:
521+
{
522+
struct gpu_command_shader_init * args = command->args;
523+
_gpu_shader_use(gpu, args);
524+
break;
525+
}
526+
case COMMAND_DRAW_SKYBOX:
527+
{
528+
struct gpu_command_draw_skybox * args = command->args;
529+
_gpu_draw_skybox(gpu, args);
530+
break;
531+
}
532+
case COMMAND_SHADER_SET_M4:
533+
{
534+
struct gpu_command_shader_mat4 * args = command->args;
535+
_gpu_shader_set_m4(gpu, args);
536+
break;
537+
}
538+
case COMMAND_SHADER_SET_TRANSFORM_MAT:
539+
{
540+
struct gpu_command_shader_transform_mat * args = command->args;
541+
_gpu_shader_set_transform_matrices(gpu, args);
542+
break;
543+
}
544+
case COMMAND_SHADER_SET_FLOAT:
545+
{
546+
struct gpu_command_shader_float * args = command->args;
547+
_gpu_shader_set_float(gpu, args);
548+
break;
549+
}
550+
case COMMAND_SHADER_SET_FLOAT4:
551+
{
552+
struct gpu_command_shader_vec4 * args = command->args;
553+
_gpu_shader_set_float4(gpu, args);
554+
break;
555+
}
556+
case COMMAND_SHADER_CLEANUP:
557+
{
558+
struct gpu_command_shader_init * args = command->args;
559+
_gpu_shader_cleanup(gpu, args);
560+
break;
561+
}
562+
case COMMAND_SHADER_RELOAD:
563+
{
564+
_gpu_shader_reload(gpu);
565+
break;
566+
}
567+
case COMMAND_WIREFRAME:
568+
{
569+
_gpu_cycle_wireframe(gpu);
570+
break;
571+
}
572+
case COMMAND_CLEANUP:
573+
{
574+
running = false;
575+
break;
576+
}
577+
default:
578+
break;
582579
}
580+
free(command->args);
581+
free(command);
583582
}
584583

585584
return 0;

src/queue_og.h

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#pragma once
2+
3+
#include <stdint.h>
4+
#include <stdbool.h>
5+
#include <pthread.h>
6+
7+
typedef struct queue_og {
8+
void ** container;
9+
uint64_t size;
10+
uint64_t front;
11+
uint64_t count;
12+
uint64_t back;
13+
pthread_mutex_t mutex;
14+
} queue_og;
15+
16+
17+
queue_og * queue_og_init(uint64_t intial_size);
18+
void queue_og_enqueue_og(queue_og* q, void* value);
19+
void *queue_og_dequeue_og(queue_og* q);
20+
bool queue_og_is_empty(queue_og* q);
21+
bool queue_og_is_full(queue_og* q);
22+
void queue_og_cleanup(queue_og* q);

src/world.c

+12-17
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ world * world_init(gpu * gpu){
2121
world * w = malloc(sizeof(*w));
2222
assert(w);
2323
w->gpu = gpu;
24-
w->chunk_to_acquire = queue_init(2*TOTAL_CHUNKS*20);
24+
w->chunk_to_acquire = queue_og_init(2*TOTAL_CHUNKS*20);
2525
w->loaded_chunks = fixray_init(TOTAL_CHUNKS);
2626
w->cache = htb_init(100000);
27-
// Enqueues all the starting chunks in a kind of spiral pattern (square radius increasing until render distance)
27+
// Enqueue_ogs all the starting chunks in a kind of spiral pattern (square radius increasing until render distance)
2828
for(int square_radius = 0; square_radius <= RENDER_DISTANCE; square_radius++){
2929
for (int z = -square_radius ; z < square_radius+1 ; z++){
3030
for (int x = -square_radius; x < square_radius+1; x++){
@@ -35,8 +35,8 @@ world * world_init(gpu * gpu){
3535
gpu_upload(w->gpu, chunk_index, c);
3636
c->ready = true;
3737
}else{
38-
queue_enqueue(w->chunk_to_acquire, (void*)(intptr_t)x);
39-
queue_enqueue(w->chunk_to_acquire, (void*)(intptr_t)z);
38+
queue_og_enqueue_og(w->chunk_to_acquire, (void*)(intptr_t)x);
39+
queue_og_enqueue_og(w->chunk_to_acquire, (void*)(intptr_t)z);
4040
}
4141
}
4242
}
@@ -195,11 +195,11 @@ void world_update_acquired(world * w, int *acquired){
195195
// create a thread that generate said chunk, including its mesh data then fixray and upload
196196
x = acquired[index*2 + 0];
197197
z = acquired[index*2 + 1];
198-
queue_enqueue(w->chunk_to_acquire, (void*)(intptr_t)x);
199-
queue_enqueue(w->chunk_to_acquire, (void*)(intptr_t)z);
198+
queue_og_enqueue_og(w->chunk_to_acquire, (void*)(intptr_t)x);
199+
queue_og_enqueue_og(w->chunk_to_acquire, (void*)(intptr_t)z);
200200
index++;
201201
}
202-
printf("Acquired %d\n", index);
202+
// printf("Acquired %d\n", index);
203203
}
204204

205205
bool chunk_in_range(chunk *c, int center_x, int center_z){
@@ -218,13 +218,12 @@ bool world_update_position(world * w, float x, float z){
218218
static int acquired[TOTAL_CHUNKS*2+1]; //x0,y0,x1,y1 INT_MAX terminated;
219219
acquired[0] = INT_MAX;
220220

221-
222221
// printf("center chunk faces %u, total sizeof in bytes : %zu\n", w->center_chunk->faces_count, chunk_sizeof(w->center_chunk));
223222
// get last chunk
224223
int count = 0;
225-
while (!queue_is_empty(w->chunk_to_acquire) && count < CHUNK_LOAD_PER_FRAME){
226-
int x = (int)(intptr_t)queue_dequeue(w->chunk_to_acquire);
227-
int z = (int)(intptr_t)queue_dequeue(w->chunk_to_acquire);
224+
while (!queue_og_is_empty(w->chunk_to_acquire) && count < CHUNK_LOAD_PER_FRAME){
225+
int x = (int)(intptr_t)queue_og_dequeue_og(w->chunk_to_acquire);
226+
int z = (int)(intptr_t)queue_og_dequeue_og(w->chunk_to_acquire);
228227
if (x >= (new_center_x - (RENDER_DISTANCE)) &&
229228
z >= (new_center_z - (RENDER_DISTANCE)) &&
230229
x < (new_center_x + (RENDER_DISTANCE)) &&
@@ -252,13 +251,9 @@ bool world_update_position(world * w, float x, float z){
252251
printf("new center chunk %d,%d (previous %d,%d)\n", new_center_x, new_center_z, w->center_chunk->x, w->center_chunk->z);
253252

254253
// Find the chunks that were discarded
255-
// ToDo : just like the acquired chunks this could be computed by a function instead of looping
256-
257254
world_compute_acquired_chunks(w->center_chunk->x, new_center_x, w->center_chunk->z, new_center_z, acquired);
258-
259255
world_update_acquired(w, acquired);
260256

261-
262257
w->center_chunk = world_get_loaded_chunk(w, new_center_x, new_center_z);
263258
// Force the chunk generation
264259
if (!w->center_chunk){
@@ -269,7 +264,7 @@ bool world_update_position(world * w, float x, float z){
269264
w->center_chunk = world_get_loaded_chunk(w, new_center_x, new_center_z);
270265
}
271266
assert(w->center_chunk);
272-
printf("chunk cache bucket used %zu, total entries %zu\n", w->cache->used_buckets, w->cache->total_entries);
267+
// printf("chunk cache bucket used %zu, total entries %zu\n", w->cache->used_buckets, w->cache->total_entries);
273268
return true;
274269
}
275270
return false;
@@ -325,7 +320,7 @@ void world_cleanup(world * w){
325320
}
326321

327322
htb_cleanup(w->cache, (void (*)(void*))chunk_cleanup);
328-
queue_cleanup(w->chunk_to_acquire);
323+
queue_og_cleanup(w->chunk_to_acquire);
329324
fixray_cleanup(w->loaded_chunks);
330325
free(w);
331326
}

src/world.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include <gpu.h>
88
#include <hashtable.h>
99
#include <fixed_array.h>
10-
#include <queue.h>
10+
#include <queue_og.h>
1111

1212
#define CHUNK_LOAD_PER_FRAME 8
1313

@@ -16,7 +16,7 @@ typedef struct world {
1616
htb* cache;
1717
fixray* loaded_chunks;
1818
chunk* center_chunk; // chunk in the center of the loaded world, where the player currently is
19-
queue* chunk_to_acquire;
19+
queue_og* chunk_to_acquire;
2020
} world;
2121

2222

0 commit comments

Comments
 (0)