Partial: remove pipelines - pipeline layout

Francesco Pasa 1 year ago

src/window.c   M +108 -100

 60 
 61 
 62 // TODO: reorganize code
 63-WGPUPipelineLayout configure_resources(const AlbaWindow* window, DrawCall* data)
 64+WGPUPipelineLayout configure_bind_group_layout(const AlbaWindow* window)
 65 {
 66-    WGPUBindGroupLayoutEntry bind_group_layout_entries[3] = {0};
 67+    WGPUBindGroupLayout bind_groups[2];
 68+
 69+    // @group(0) - Uniforms (scale)
 70+    // --------------------------------------------
 71+    WGPUBindGroupLayoutEntry uniforms_bind_group_entries[1] = {0};
 72 
 73-    // Uniform (scale)
 74     // @binding(0)
 75-    bind_group_layout_entries[0].binding = 0;
 76-    bind_group_layout_entries[0].visibility = WGPUShaderStage_Vertex;
 77-    bind_group_layout_entries[0].buffer.type = WGPUBufferBindingType_Uniform;
 78+    uniforms_bind_group_entries[0].binding = 0;
 79+    uniforms_bind_group_entries[0].visibility = WGPUShaderStage_Vertex;
 80+    uniforms_bind_group_entries[0].buffer.type = WGPUBufferBindingType_Uniform;
 81 
 82-    // Texture
 83-    // @binding(1)
 84-    bind_group_layout_entries[1].binding = 1;
 85-    bind_group_layout_entries[1].visibility = WGPUShaderStage_Fragment;
 86-    bind_group_layout_entries[1].texture.sampleType = WGPUTextureSampleType_Float;
 87-    bind_group_layout_entries[1].texture.viewDimension = WGPUTextureViewDimension_2D;
 88-
 89-    // Sampler
 90-    // @binding(2)
 91-    bind_group_layout_entries[2].binding = 2;
 92-    bind_group_layout_entries[2].visibility = WGPUShaderStage_Fragment;
 93-    bind_group_layout_entries[2].sampler.type = WGPUSamplerBindingType_Filtering;
 94-
 95-    WGPUBindGroupLayoutDescriptor bind_group_layout_options = {0};
 96-    bind_group_layout_options.entryCount = 3;
 97-    bind_group_layout_options.entries = bind_group_layout_entries;
 98-    const WGPUBindGroupLayout bind_group_layout = wgpuDeviceCreateBindGroupLayout(
 99-        window->device, &bind_group_layout_options);
100-
101-    // --------------------------
102-    WGPUBindGroupEntry bind_group_entries[3] = {0};
103-
104-    // Uniform (scale)
105-    WGPUBufferDescriptor uniform_options = {0};
106-    uniform_options.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform;
107-    uniform_options.size = 2 * sizeof(float);
108-    if (data->uniforms == NULL)
109-    {
110-        data->uniforms = wgpuDeviceCreateBuffer(window->device, &uniform_options);
111-    }
112+    WGPUBindGroupLayoutDescriptor uniforms_bind_group_options = {0};
113+    uniforms_bind_group_options.entryCount = 1;
114+    uniforms_bind_group_options.entries = uniforms_bind_group_entries;
115+    bind_groups[0] = wgpuDeviceCreateBindGroupLayout(window->device, &uniforms_bind_group_options);
116 
117-    // @binding(0)
118-    bind_group_entries[0].binding = 0;
119-    bind_group_entries[0].buffer = data->uniforms;
120-    bind_group_entries[0].size = uniform_options.size;
121+    // @group(1) - Texture & sampler
122+    // --------------------------------------------
123+    WGPUBindGroupLayoutEntry texture_bind_group_entries[2] = {0};
124 
125-    // Texture
126-    if (data->texture == NULL)
127-    {
128-        // 1x1 transparent texture
129-        data->texture = create_texture(
130-            window,
131-            WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst,
132-            (AlbaVector){1, 1},
133-            WGPUTextureFormat_RGBA8UnormSrgb, 1,
134-            &(AlbaColor)WHITE
135-        );
136-    }
137+    // @binding(0)
138+    texture_bind_group_entries[0].binding = 0;
139+    texture_bind_group_entries[0].visibility = WGPUShaderStage_Fragment;
140+    texture_bind_group_entries[0].texture.sampleType = WGPUTextureSampleType_Float;
141+    texture_bind_group_entries[0].texture.viewDimension = WGPUTextureViewDimension_2D;
142     // @binding(1)
143-    bind_group_entries[1].binding = 1;
144-    bind_group_entries[1].textureView = wgpuTextureCreateView(data->texture, NULL);
145-
146-    // Sampler
147-    WGPUSamplerDescriptor sampler_options = {0};
148-    sampler_options.addressModeU = WGPUAddressMode_ClampToEdge;
149-    sampler_options.addressModeV = WGPUAddressMode_ClampToEdge;
150-    sampler_options.addressModeW = WGPUAddressMode_ClampToEdge;
151-    sampler_options.magFilter = WGPUFilterMode_Linear;
152-    sampler_options.minFilter = WGPUFilterMode_Linear;
153-    sampler_options.mipmapFilter = WGPUMipmapFilterMode_Linear;
154-    sampler_options.lodMinClamp = 0;
155-    sampler_options.lodMaxClamp = 1;
156-    sampler_options.maxAnisotropy = 1;
157-
158-    // @binding(2)
159-    bind_group_entries[2].binding = 2;
160-    // TODO: free previous
161-    bind_group_entries[2].sampler = wgpuDeviceCreateSampler(window->device, &sampler_options);
162-
163-    WGPUBindGroupDescriptor binding_group_options = {0};
164-    binding_group_options.layout = bind_group_layout;
165-    binding_group_options.entryCount = 3;
166-    binding_group_options.entries = bind_group_entries;
167-
168-    // TODO: free previous
169-    data->bind_group = wgpuDeviceCreateBindGroup(window->device, &binding_group_options);
170-
171-    // A pipeline can have multiple bind groups
172+    texture_bind_group_entries[1].binding = 1;
173+    texture_bind_group_entries[1].visibility = WGPUShaderStage_Fragment;
174+    texture_bind_group_entries[1].sampler.type = WGPUSamplerBindingType_Filtering;
175+
176+    WGPUBindGroupLayoutDescriptor texture_bind_group_options = {0};
177+    texture_bind_group_options.entryCount = 2;
178+    texture_bind_group_options.entries = texture_bind_group_entries;
179+    bind_groups[1] = wgpuDeviceCreateBindGroupLayout(window->device, &texture_bind_group_options);
180+
181+    // Pipeline layout
182+    // --------------------------------------------
183     WGPUPipelineLayoutDescriptor pipeline_layout_options = {0};
184-    pipeline_layout_options.bindGroupLayoutCount = 1;
185-    pipeline_layout_options.bindGroupLayouts = &bind_group_layout;
186-    // TODO: free previous
187+    pipeline_layout_options.bindGroupLayoutCount = 2;
188+    pipeline_layout_options.bindGroupLayouts = bind_groups;
189     const WGPUPipelineLayout pipeline_layout = wgpuDeviceCreatePipelineLayout(
190         window->device, &pipeline_layout_options);
191 
192-    wgpuBindGroupLayoutRelease(bind_group_layout);
193+    wgpuBindGroupLayoutRelease(bind_groups[0]);
194+    wgpuBindGroupLayoutRelease(bind_groups[1]);
195 
196     return pipeline_layout;
197+
198+    // // --------------------------
199+    // WGPUBindGroupEntry bind_group_entries[3] = {0};
200+    //
201+    // // Uniform (scale)
202+    // WGPUBufferDescriptor uniform_options = {0};
203+    // uniform_options.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform;
204+    // uniform_options.size = 2 * sizeof(float);
205+    // if (data->uniforms == NULL)
206+    // {
207+    //     data->uniforms = wgpuDeviceCreateBuffer(window->device, &uniform_options);
208+    // }
209+    //
210+    // // @binding(0)
211+    // bind_group_entries[0].binding = 0;
212+    // bind_group_entries[0].buffer = data->uniforms;
213+    // bind_group_entries[0].size = uniform_options.size;
214+    //
215+    // // Texture
216+    // if (data->texture == NULL)
217+    // {
218+    //     // 1x1 transparent texture
219+    //     data->texture = create_texture(
220+    //         window,
221+    //         WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst,
222+    //         (AlbaVector){1, 1},
223+    //         WGPUTextureFormat_RGBA8UnormSrgb, 1,
224+    //         &(AlbaColor)WHITE
225+    //     );
226+    // }
227+    // // @binding(1)
228+    // bind_group_entries[1].binding = 1;
229+    // bind_group_entries[1].textureView = wgpuTextureCreateView(data->texture, NULL);
230+    //
231+    // // Sampler
232+    // WGPUSamplerDescriptor sampler_options = {0};
233+    // sampler_options.addressModeU = WGPUAddressMode_ClampToEdge;
234+    // sampler_options.addressModeV = WGPUAddressMode_ClampToEdge;
235+    // sampler_options.addressModeW = WGPUAddressMode_ClampToEdge;
236+    // sampler_options.magFilter = WGPUFilterMode_Linear;
237+    // sampler_options.minFilter = WGPUFilterMode_Linear;
238+    // sampler_options.mipmapFilter = WGPUMipmapFilterMode_Linear;
239+    // sampler_options.lodMinClamp = 0;
240+    // sampler_options.lodMaxClamp = 1;
241+    // sampler_options.maxAnisotropy = 1;
242+    //
243+    // // @binding(2)
244+    // bind_group_entries[2].binding = 2;
245+    // // TODO: free previous
246+    // bind_group_entries[2].sampler = wgpuDeviceCreateSampler(window->device, &sampler_options);
247+    //
248+    // WGPUBindGroupDescriptor binding_group_options = {0};
249+    // binding_group_options.layout = bind_group_layout;
250+    // binding_group_options.entryCount = 3;
251+    // binding_group_options.entries = bind_group_entries;
252+    //
253+    // // TODO: free previous
254+    // data->bind_group = wgpuDeviceCreateBindGroup(window->device, &binding_group_options);
255 }
256 
257 void configure_surface(AlbaWindow* window)
181     window->size = (AlbaVector){width, height};
182     window->scale = (AlbaVector){width / (2 * x_scale), height / (2 * y_scale)};
183 
184-    // TODO: callback when scaling changes
185+    // TODO: callback when scaling changes (window changes monitor)
186     // Update uniforms
187-    wgpuQueueWriteBuffer(window->queue, window->layers[0].drawing.uniforms, 0, &window->scale, sizeof(AlbaVector));
188-    wgpuQueueWriteBuffer(window->queue, window->layers[0].text.uniforms, 0, &window->scale, sizeof(AlbaVector));
189+    wgpuQueueWriteBuffer(window->queue, window->uniforms, 0, &window->scale, sizeof(AlbaVector));
190 
191     const WGPUTextureFormat format = wgpuSurfaceGetPreferredFormat(window->surface, window->adapter);
192 
197     wgpuSurfaceConfigure(window->surface, &surface_options);
198 }
199 
200-
201 void configure_pipeline(AlbaWindow* window)
202 {
203+    // Load shaders
204+    // --------------------------------------------
205     WGPUShaderModuleWGSLDescriptor shader_options = {0};
206     shader_options.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
207     shader_options.code = _binary_shaders_wgsl_start;
211     window->shaders = wgpuDeviceCreateShaderModule(window->device, &shader_loader_options);
212 
213     // Configure render pipeline
214+    // --------------------------------------------
215     WGPURenderPipelineDescriptor pipleine_options = {0};
216     // Rendering settings
217     pipleine_options.primitive.topology = WGPUPrimitiveTopology_TriangleList;
281     fragment_state.targets = &color_state;
282     pipleine_options.fragment = &fragment_state;
283 
284-    // Configure resources for drawing pass
285-    pipleine_options.layout = configure_resources(window, &window->layers[0].drawing);
286-    window->layers[0].drawing.pipeline = wgpuDeviceCreateRenderPipeline(window->device, &pipleine_options);
287-
288-    // Configure resources for text pass
289-    pipleine_options.layout = configure_resources(window, &window->layers[0].text);
290-    window->layers[0].text.pipeline = wgpuDeviceCreateRenderPipeline(window->device, &pipleine_options);
291+    // Configure bind groups layout
292+    // --------------------------------------------
293+    pipleine_options.layout = configure_bind_group_layout(window);
294+    window->pipeline = wgpuDeviceCreateRenderPipeline(window->device, &pipleine_options);
295 
296     wgpuPipelineLayoutRelease(pipleine_options.layout);
297 }
314     memset(window, 0, sizeof(AlbaWindow));
315 
316     window->options = *options;
317-    window->layers = create_layer();
318 
319     // GLFW window
320     glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
356     configure_pipeline(window);
357     configure_surface(window);
358 
359+    window->draw_calls = alba_create_array(sizeof(DrawCall), 0);
360+
361     return window;
362 }
363 
375 {
376     for (uint64_t i = 0; i < window->draw_calls.length; i++)
377     {
378-        draw_call_release(&window->draw_calls.data[i]);
379+        draw_call_release(window->draw_calls.data + i);
380     }
381     alba_array_release(&window->draw_calls);
382 
435     wgpuRenderPassEncoderSetPipeline(render_pass, window->pipeline);
436     for (uint64_t i = 0; i < window->draw_calls.length; i++)
437     {
438-        DrawCall* draw_call = &window->draw_calls.data[i];
439+        DrawCall* draw_call = window->draw_calls.data + i;
440 
441         wgpuRenderPassEncoderSetBindGroup(render_pass, 0, draw_call->bind_group, 0, NULL);
442 
523     render_pass_attachment_options.view = render_target_view;
524     render_pass_attachment_options.loadOp = WGPULoadOp_Clear;
525     render_pass_attachment_options.storeOp = WGPUStoreOp_Store;
526-    render_pass_attachment_options.resolveTarget = frame;
527+    render_pass_attachment_options.resolveTarget = frame_view;
528     copy_color(window->options.clear_color, &render_pass_attachment_options.clearValue);
529 
530     WGPURenderPassDescriptor render_pass_options = {0};