Partial: remove pipelines - pipeline layout
Francesco Pasa 1 year ago
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};