Partial: remove pipelines - pipeline layout

Francesco Pasa 10 months ago

src/window.c   M +108 -100

 60 
 61 
 62 // TODO: reorganize code
 63-WGPUPipelineLayout configure_resources(const AlbaWindow* window, DrawCall* data)
 63+WGPUPipelineLayout configure_bind_group_layout(const AlbaWindow* window)
 64 {
 65-    WGPUBindGroupLayoutEntry bind_group_layout_entries[3] = {0};
 65+    WGPUBindGroupLayout bind_groups[2];
 66+
 67+    // @group(0) - Uniforms (scale)
 68+    // --------------------------------------------
 69+    WGPUBindGroupLayoutEntry uniforms_bind_group_entries[1] = {0};
 70 
 71-    // Uniform (scale)
 71     // @binding(0)
 72-    bind_group_layout_entries[0].binding = 0;
 73-    bind_group_layout_entries[0].visibility = WGPUShaderStage_Vertex;
 74-    bind_group_layout_entries[0].buffer.type = WGPUBufferBindingType_Uniform;
 72+    uniforms_bind_group_entries[0].binding = 0;
 73+    uniforms_bind_group_entries[0].visibility = WGPUShaderStage_Vertex;
 74+    uniforms_bind_group_entries[0].buffer.type = WGPUBufferBindingType_Uniform;
 75 
 76-    // Texture
 77-    // @binding(1)
 78-    bind_group_layout_entries[1].binding = 1;
 79-    bind_group_layout_entries[1].visibility = WGPUShaderStage_Fragment;
 80-    bind_group_layout_entries[1].texture.sampleType = WGPUTextureSampleType_Float;
 81-    bind_group_layout_entries[1].texture.viewDimension = WGPUTextureViewDimension_2D;
 82-
 83-    // Sampler
 84-    // @binding(2)
 85-    bind_group_layout_entries[2].binding = 2;
 86-    bind_group_layout_entries[2].visibility = WGPUShaderStage_Fragment;
 87-    bind_group_layout_entries[2].sampler.type = WGPUSamplerBindingType_Filtering;
 88-
 89-    WGPUBindGroupLayoutDescriptor bind_group_layout_options = {0};
 90-    bind_group_layout_options.entryCount = 3;
 91-    bind_group_layout_options.entries = bind_group_layout_entries;
 92-    const WGPUBindGroupLayout bind_group_layout = wgpuDeviceCreateBindGroupLayout(
 93-        window->device, &bind_group_layout_options);
 94-
 95-    // --------------------------
 96-    WGPUBindGroupEntry bind_group_entries[3] = {0};
 97-
 98-    // Uniform (scale)
 99-    WGPUBufferDescriptor uniform_options = {0};
100-    uniform_options.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform;
101-    uniform_options.size = 2 * sizeof(float);
102-    if (data->uniforms == NULL)
103-    {
104-        data->uniforms = wgpuDeviceCreateBuffer(window->device, &uniform_options);
105-    }
 76+    WGPUBindGroupLayoutDescriptor uniforms_bind_group_options = {0};
 77+    uniforms_bind_group_options.entryCount = 1;
 78+    uniforms_bind_group_options.entries = uniforms_bind_group_entries;
 79+    bind_groups[0] = wgpuDeviceCreateBindGroupLayout(window->device, &uniforms_bind_group_options);
 80 
 81-    // @binding(0)
 82-    bind_group_entries[0].binding = 0;
 83-    bind_group_entries[0].buffer = data->uniforms;
 84-    bind_group_entries[0].size = uniform_options.size;
 81+    // @group(1) - Texture & sampler
 82+    // --------------------------------------------
 83+    WGPUBindGroupLayoutEntry texture_bind_group_entries[2] = {0};
 84 
 85-    // Texture
 86-    if (data->texture == NULL)
 87-    {
 88-        // 1x1 transparent texture
 89-        data->texture = create_texture(
 90-            window,
 91-            WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst,
 92-            (AlbaVector){1, 1},
 93-            WGPUTextureFormat_RGBA8UnormSrgb, 1,
 94-            &(AlbaColor)WHITE
 95-        );
 96-    }
 85+    // @binding(0)
 86+    texture_bind_group_entries[0].binding = 0;
 87+    texture_bind_group_entries[0].visibility = WGPUShaderStage_Fragment;
 88+    texture_bind_group_entries[0].texture.sampleType = WGPUTextureSampleType_Float;
 89+    texture_bind_group_entries[0].texture.viewDimension = WGPUTextureViewDimension_2D;
 90     // @binding(1)
 91-    bind_group_entries[1].binding = 1;
 92-    bind_group_entries[1].textureView = wgpuTextureCreateView(data->texture, NULL);
 93-
 94-    // Sampler
 95-    WGPUSamplerDescriptor sampler_options = {0};
 96-    sampler_options.addressModeU = WGPUAddressMode_ClampToEdge;
 97-    sampler_options.addressModeV = WGPUAddressMode_ClampToEdge;
 98-    sampler_options.addressModeW = WGPUAddressMode_ClampToEdge;
 99-    sampler_options.magFilter = WGPUFilterMode_Linear;
100-    sampler_options.minFilter = WGPUFilterMode_Linear;
101-    sampler_options.mipmapFilter = WGPUMipmapFilterMode_Linear;
102-    sampler_options.lodMinClamp = 0;
103-    sampler_options.lodMaxClamp = 1;
104-    sampler_options.maxAnisotropy = 1;
105-
106-    // @binding(2)
107-    bind_group_entries[2].binding = 2;
108-    // TODO: free previous
109-    bind_group_entries[2].sampler = wgpuDeviceCreateSampler(window->device, &sampler_options);
110-
111-    WGPUBindGroupDescriptor binding_group_options = {0};
112-    binding_group_options.layout = bind_group_layout;
113-    binding_group_options.entryCount = 3;
114-    binding_group_options.entries = bind_group_entries;
115-
116-    // TODO: free previous
117-    data->bind_group = wgpuDeviceCreateBindGroup(window->device, &binding_group_options);
118-
119-    // A pipeline can have multiple bind groups
 91+    texture_bind_group_entries[1].binding = 1;
 92+    texture_bind_group_entries[1].visibility = WGPUShaderStage_Fragment;
 93+    texture_bind_group_entries[1].sampler.type = WGPUSamplerBindingType_Filtering;
 94+
 95+    WGPUBindGroupLayoutDescriptor texture_bind_group_options = {0};
 96+    texture_bind_group_options.entryCount = 2;
 97+    texture_bind_group_options.entries = texture_bind_group_entries;
 98+    bind_groups[1] = wgpuDeviceCreateBindGroupLayout(window->device, &texture_bind_group_options);
 99+
100+    // Pipeline layout
101+    // --------------------------------------------
102     WGPUPipelineLayoutDescriptor pipeline_layout_options = {0};
103-    pipeline_layout_options.bindGroupLayoutCount = 1;
104-    pipeline_layout_options.bindGroupLayouts = &bind_group_layout;
105-    // TODO: free previous
103+    pipeline_layout_options.bindGroupLayoutCount = 2;
104+    pipeline_layout_options.bindGroupLayouts = bind_groups;
105     const WGPUPipelineLayout pipeline_layout = wgpuDeviceCreatePipelineLayout(
106         window->device, &pipeline_layout_options);
106 
107-    wgpuBindGroupLayoutRelease(bind_group_layout);
107+    wgpuBindGroupLayoutRelease(bind_groups[0]);
108+    wgpuBindGroupLayoutRelease(bind_groups[1]);
109 
110     return pipeline_layout;
111+
112+    // // --------------------------
113+    // WGPUBindGroupEntry bind_group_entries[3] = {0};
114+    //
115+    // // Uniform (scale)
116+    // WGPUBufferDescriptor uniform_options = {0};
117+    // uniform_options.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform;
118+    // uniform_options.size = 2 * sizeof(float);
119+    // if (data->uniforms == NULL)
120+    // {
121+    //     data->uniforms = wgpuDeviceCreateBuffer(window->device, &uniform_options);
122+    // }
123+    //
124+    // // @binding(0)
125+    // bind_group_entries[0].binding = 0;
126+    // bind_group_entries[0].buffer = data->uniforms;
127+    // bind_group_entries[0].size = uniform_options.size;
128+    //
129+    // // Texture
130+    // if (data->texture == NULL)
131+    // {
132+    //     // 1x1 transparent texture
133+    //     data->texture = create_texture(
134+    //         window,
135+    //         WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst,
136+    //         (AlbaVector){1, 1},
137+    //         WGPUTextureFormat_RGBA8UnormSrgb, 1,
138+    //         &(AlbaColor)WHITE
139+    //     );
140+    // }
141+    // // @binding(1)
142+    // bind_group_entries[1].binding = 1;
143+    // bind_group_entries[1].textureView = wgpuTextureCreateView(data->texture, NULL);
144+    //
145+    // // Sampler
146+    // WGPUSamplerDescriptor sampler_options = {0};
147+    // sampler_options.addressModeU = WGPUAddressMode_ClampToEdge;
148+    // sampler_options.addressModeV = WGPUAddressMode_ClampToEdge;
149+    // sampler_options.addressModeW = WGPUAddressMode_ClampToEdge;
150+    // sampler_options.magFilter = WGPUFilterMode_Linear;
151+    // sampler_options.minFilter = WGPUFilterMode_Linear;
152+    // sampler_options.mipmapFilter = WGPUMipmapFilterMode_Linear;
153+    // sampler_options.lodMinClamp = 0;
154+    // sampler_options.lodMaxClamp = 1;
155+    // sampler_options.maxAnisotropy = 1;
156+    //
157+    // // @binding(2)
158+    // bind_group_entries[2].binding = 2;
159+    // // TODO: free previous
160+    // bind_group_entries[2].sampler = wgpuDeviceCreateSampler(window->device, &sampler_options);
161+    //
162+    // WGPUBindGroupDescriptor binding_group_options = {0};
163+    // binding_group_options.layout = bind_group_layout;
164+    // binding_group_options.entryCount = 3;
165+    // binding_group_options.entries = bind_group_entries;
166+    //
167+    // // TODO: free previous
168+    // data->bind_group = wgpuDeviceCreateBindGroup(window->device, &binding_group_options);
169 }
170 
171 void configure_surface(AlbaWindow* window)
181     window->size = (AlbaVector){width, height};
182     window->scale = (AlbaVector){width / (2 * x_scale), height / (2 * y_scale)};
181 
182-    // TODO: callback when scaling changes
182+    // TODO: callback when scaling changes (window changes monitor)
183     // Update uniforms
184-    wgpuQueueWriteBuffer(window->queue, window->layers[0].drawing.uniforms, 0, &window->scale, sizeof(AlbaVector));
185-    wgpuQueueWriteBuffer(window->queue, window->layers[0].text.uniforms, 0, &window->scale, sizeof(AlbaVector));
184+    wgpuQueueWriteBuffer(window->queue, window->uniforms, 0, &window->scale, sizeof(AlbaVector));
185 
186     const WGPUTextureFormat format = wgpuSurfaceGetPreferredFormat(window->surface, window->adapter);
187 
197     wgpuSurfaceConfigure(window->surface, &surface_options);
198 }
199 
200-
200 void configure_pipeline(AlbaWindow* window)
201 {
202+    // Load shaders
203+    // --------------------------------------------
204     WGPUShaderModuleWGSLDescriptor shader_options = {0};
205     shader_options.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
206     shader_options.code = _binary_shaders_wgsl_start;
211     window->shaders = wgpuDeviceCreateShaderModule(window->device, &shader_loader_options);
211 
212     // Configure render pipeline
213+    // --------------------------------------------
214     WGPURenderPipelineDescriptor pipleine_options = {0};
215     // Rendering settings
216     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);
284+    // Configure bind groups layout
285+    // --------------------------------------------
286+    pipleine_options.layout = configure_bind_group_layout(window);
287+    window->pipeline = wgpuDeviceCreateRenderPipeline(window->device, &pipleine_options);
288 
289     wgpuPipelineLayoutRelease(pipleine_options.layout);
290 }
314     memset(window, 0, sizeof(AlbaWindow));
315 
316     window->options = *options;
317-    window->layers = create_layer();
316 
317     // GLFW window
318     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]);
378+        draw_call_release(window->draw_calls.data + i);
379     }
380     alba_array_release(&window->draw_calls);
381 
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];
438+        DrawCall* draw_call = window->draw_calls.data + i;
439 
440         wgpuRenderPassEncoderSetBindGroup(render_pass, 0, draw_call->bind_group, 0, NULL);
441 
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;
526+    render_pass_attachment_options.resolveTarget = frame_view;
527     copy_color(window->options.clear_color, &render_pass_attachment_options.clearValue);
528 
529     WGPURenderPassDescriptor render_pass_options = {0};