src/draw_call.c
  1#include "alba.h"
  2#include "internal.h"
  3
  4DrawCall *window_create_draw_call(AlbaWindow *window) {
  5    DrawCall draw_call = {0};
  6    draw_call.buffers_dirty = 1;
  7    draw_call.bind_group_dirty = 1;
  8    draw_call.new_vertices = alba_create_array(sizeof(AlbaVector), 0);
  9    draw_call.new_attributes = alba_create_array(sizeof(AlbaAttribute), 0);
 10    draw_call.new_indices = alba_create_array(sizeof(uint32_t), 0);
 11    draw_call.new_texts = alba_create_array(sizeof(Text), 0);
 12    alba_array_append(&window->draw_calls, &draw_call);
 13    return alba_array_last(&window->draw_calls);
 14}
 15
 16void window_set_texture(AlbaWindow *window, const WGPUTexture texture) {
 17    DrawCall *draw_call = alba_array_last(&window->draw_calls);
 18    if (draw_call->texture_set) {
 19        draw_call = window_create_draw_call(window);
 20    }
 21    draw_call_set_texture(draw_call, texture);
 22    draw_call->texture_set = 1;
 23}
 24
 25void window_clear(AlbaWindow *window) {
 26    alba_array_clear(&window->draw_calls);
 27}
 28
 29void clear_texture_bind_group(const DrawCall *draw_call) {
 30    wgpuBindGroupRelease(draw_call->bind_group);
 31}
 32
 33void draw_call_set_texture(DrawCall *draw_call, const WGPUTexture texture) {
 34    if (draw_call->view != NULL) {
 35        wgpuTextureViewRelease(draw_call->view);
 36    }
 37    if (draw_call->texture != NULL) {
 38        wgpuTextureDestroy(draw_call->texture);
 39        wgpuTextureRelease(draw_call->texture);
 40    }
 41
 42    draw_call->texture = texture;
 43    draw_call->view = wgpuTextureCreateView(draw_call->texture, NULL);
 44    draw_call->bind_group_dirty = 1;
 45}
 46
 47void draw_call_update_bind_group(const AlbaWindow *window, DrawCall *draw_call) {
 48    WGPUBindGroupEntry bind_group_entries[2] = {0};
 49
 50    // Texture
 51    if (draw_call->texture == NULL) {
 52        draw_call_set_texture(
 53            draw_call,
 54            // 1x1 white texture
 55            create_texture(
 56                window,
 57                WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst,
 58                (AlbaVector){1, 1},
 59                window->surface_format,
 60                1,
 61                &(AlbaColor)WHITE
 62            )
 63        );
 64    }
 65
 66    // @binding(1)
 67    bind_group_entries[0].binding = 0; // @group(1) @binding(0)
 68    bind_group_entries[0].textureView = draw_call->view;
 69
 70    // Sampler
 71    if (draw_call->sampler == NULL) {
 72        WGPUSamplerDescriptor sampler_options = {0};
 73        sampler_options.addressModeU = WGPUAddressMode_ClampToEdge;
 74        sampler_options.addressModeV = WGPUAddressMode_ClampToEdge;
 75        sampler_options.addressModeW = WGPUAddressMode_ClampToEdge;
 76        sampler_options.magFilter = WGPUFilterMode_Linear;
 77        sampler_options.minFilter = WGPUFilterMode_Linear;
 78        sampler_options.mipmapFilter = WGPUMipmapFilterMode_Linear;
 79        sampler_options.lodMinClamp = 0;
 80        sampler_options.lodMaxClamp = 1;
 81        sampler_options.maxAnisotropy = 1;
 82        draw_call->sampler = wgpuDeviceCreateSampler(window->device, &sampler_options);
 83    }
 84
 85    // @binding(2)
 86    bind_group_entries[1].binding = 1; // @group(1) @binding(1)
 87    bind_group_entries[1].sampler = draw_call->sampler;
 88
 89    WGPUBindGroupDescriptor binding_group_options = {0};
 90    binding_group_options.layout = window->texture_bind_group_layout;
 91    binding_group_options.entryCount = 2;
 92    binding_group_options.entries = bind_group_entries;
 93
 94    if (draw_call->bind_group != NULL) {
 95        wgpuBindGroupRelease(draw_call->bind_group);
 96    }
 97    draw_call->bind_group = wgpuDeviceCreateBindGroup(window->device, &binding_group_options);
 98}
 99
100void draw_call_release(const DrawCall *draw_call) {
101    wgpuBufferDestroy(draw_call->vertices);
102    wgpuBufferRelease(draw_call->vertices);
103    alba_array_release(&draw_call->new_vertices);
104
105    wgpuBufferDestroy(draw_call->attributes);
106    wgpuBufferRelease(draw_call->attributes);
107    alba_array_release(&draw_call->new_attributes);
108
109    wgpuBufferDestroy(draw_call->indices);
110    wgpuBufferRelease(draw_call->indices);
111    alba_array_release(&draw_call->new_indices);
112
113    wgpuTextureViewRelease(draw_call->view);
114    wgpuTextureDestroy(draw_call->texture);
115    wgpuTextureRelease(draw_call->texture);
116    wgpuSamplerRelease(draw_call->sampler);
117    wgpuBindGroupRelease(draw_call->bind_group);
118}