Harbor

Changelog 68bd764e40b6

enable mrt capabilities and tests

@sky · 1 month ago · parent b66531d97958
0 added 7 modified 0 deleted
backend/backend.odin +5 -1 modified
50 unchanged lines hidden
51 51 implemented_base_capabilities :: proc(
52 52 max_color_targets, max_push_constant_size: u32,
53 53 ) -> Capabilities {
54 + features := Capability_Flags{.Compute_Dispatch, .Storage_Buffers, .Offscreen_Targets, .Sampled_Targets}
55 + if max_color_targets > 1 {
56 + features += {.Multiple_Render_Targets}
57 + }
54 58 return {
55 - features = {.Compute_Dispatch, .Storage_Buffers, .Offscreen_Targets, .Sampled_Targets},
59 + features = features,
56 60 max_color_targets = max_color_targets,
57 61 max_push_constant_size = max_push_constant_size,
58 62 max_frames_in_flight = MAX_FRAMES_IN_FLIGHT,
604 unchanged lines hidden
backend/d3d11/d3d11_backend.odin +1 -1 modified
341 unchanged lines hidden
342 342 // Populate backend vtable
343 343 backend = bk.Backend {
344 344 capabilities = bk.implemented_base_capabilities(
345 - 1,
345 + bk.MAX_COLOR_TARGETS,
346 346 PUSH_CONSTANT_MAX_SIZE,
347 347 ),
348 348
246 unchanged lines hidden
backend/d3d12/d3d12_backend.odin modified

Diff hidden because this file has more than 800 lines.

backend/opengl/gl_backend.odin +1 -1 modified
169 unchanged lines hidden
170 170
171 171 backend = bk.Backend {
172 172 capabilities = bk.implemented_base_capabilities(
173 - 1,
173 + bk.MAX_COLOR_TARGETS,
174 174 PUSH_CONSTANT_MAX_SIZE,
175 175 ),
176 176 shutdown = shutdown_opengl,
131 unchanged lines hidden
backend/vulkan/vk_backend.odin +1 -1 modified
286 unchanged lines hidden
287 287 // Populate backend vtable
288 288 backend = bk.Backend {
289 289 capabilities = bk.implemented_base_capabilities(
290 - 1,
290 + bk.MAX_COLOR_TARGETS,
291 291 min(
292 292 state.device.properties.limits.maxPushConstantsSize,
293 293 u32(VULKAN_IMPLEMENTED_PUSH_CONSTANT_MAX_SIZE),
248 unchanged lines hidden
tests/capabilities_test.odin +7 -0 modified
34 unchanged lines hidden
35 35 }
36 36
37 37 @(test)
38 + test_backend_implemented_capabilities_enable_mrt_with_multi_target_limit :: proc(t: ^testing.T) {
39 + caps := bk.implemented_base_capabilities(bk.MAX_COLOR_TARGETS, 240)
40 + testing.expect(t, bk.supports(caps, .Multiple_Render_Targets))
41 + testing.expect_value(t, caps.max_color_targets, u32(bk.MAX_COLOR_TARGETS))
42 + }
43 +
44 + @(test)
38 45 test_backend_capability_limit_helpers :: proc(t: ^testing.T) {
39 46 caps := bk.implemented_base_capabilities(1, 240)
40 47 testing.expect(t, bk.supports_color_target_count(caps, 0))
50 unchanged lines hidden
tests/compiler_executor_test.odin +142 -0 modified
154 unchanged lines hidden
155 155 }
156 156
157 157 @(test)
158 + test_compiler_builds_mrt_backend_descriptors :: proc(t: ^testing.T) {
159 + frame := ir.init_frame_ir()
160 + defer ir.destroy_frame_ir(&frame)
161 +
162 + color_a := ir.add_texture(&frame, "a", 64, 32, .B8G8R8A8_SRGB, {.Color_Attachment, .Sampled}, .Transient)
163 + color_b := ir.add_texture(&frame, "b", 64, 32, .R8G8B8A8_UNORM, {.Color_Attachment}, .Transient)
164 + pass := ir.Pass_Desc {
165 + kind = .Render,
166 + name = "mrt",
167 + }
168 + testing.expect(
169 + t,
170 + ir.pass_add_color_target(
171 + &pass,
172 + ir.make_color_target(color_a, .B8G8R8A8_SRGB, .Clear, .Store, {1, 0, 0, 1}),
173 + ),
174 + )
175 + testing.expect(
176 + t,
177 + ir.pass_add_color_target(
178 + &pass,
179 + ir.make_color_target(color_b, .R8G8B8A8_UNORM, .Load, .Store, {0, 1, 0, 1}),
180 + ),
181 + )
182 +
183 + caps := bk.implemented_base_capabilities(2, 0)
184 + desc, ok := compiler.build_render_pass_desc_with_capabilities(&frame, &pass, caps)
185 + testing.expect(t, ok)
186 + testing.expect(t, desc.has_color)
187 + testing.expect_value(t, desc.color_count, u32(2))
188 + testing.expect_value(t, desc.color_format, bk.Format.B8G8R8A8_SRGB)
189 + testing.expect_value(t, desc.color_formats[0], bk.Format.B8G8R8A8_SRGB)
190 + testing.expect_value(t, desc.color_formats[1], bk.Format.R8G8B8A8_UNORM)
191 + testing.expect_value(t, desc.color_load_ops[0], bk.Attachment_Load_Op.Clear)
192 + testing.expect_value(t, desc.color_load_ops[1], bk.Attachment_Load_Op.Load)
193 + testing.expect_value(t, desc.color_final_layouts[0], bk.Image_Layout.Shader_Read_Only)
194 + testing.expect_value(t, desc.color_final_layouts[1], bk.Image_Layout.Color_Attachment)
195 +
196 + begin := compiler.build_begin_desc(&pass, bk.Render_Pass_Handle(7), bk.Framebuffer_Handle(11))
197 + testing.expect_value(t, begin.color_count, u32(2))
198 + testing.expect_value(t, begin.clear_color, [4]f32{1, 0, 0, 1})
199 + testing.expect_value(t, begin.clear_colors[0], [4]f32{1, 0, 0, 1})
200 + testing.expect_value(t, begin.clear_colors[1], [4]f32{0, 1, 0, 1})
201 +
202 + state := compiler.init_execution_state(nil)
203 + defer compiler.destroy_execution_state(&state)
204 + append(
205 + &state.resources,
206 + compiler.Prepared_Resource {resource = color_a, kind = .Texture, texture = bk.Texture_Handle(3)},
207 + )
208 + append(
209 + &state.resources,
210 + compiler.Prepared_Resource {resource = color_b, kind = .Texture, texture = bk.Texture_Handle(4)},
211 + )
212 + fb, fb_ok := compiler.build_framebuffer_desc(&state, &frame, &pass, bk.Render_Pass_Handle(5))
213 + testing.expect(t, fb_ok)
214 + testing.expect_value(t, fb.color_count, u32(2))
215 + testing.expect_value(t, fb.color_view, bk.Texture_Handle(3))
216 + testing.expect_value(t, fb.color_views[0], bk.Texture_Handle(3))
217 + testing.expect_value(t, fb.color_views[1], bk.Texture_Handle(4))
218 + }
219 +
220 + @(test)
158 221 test_compiler_offscreen_cache_key_includes_frame_index :: proc(t: ^testing.T) {
159 222 frame := ir.init_frame_ir()
160 223 defer ir.destroy_frame_ir(&frame)
26 unchanged lines hidden
187 250 }
188 251
189 252 @(test)
253 + test_compiler_offscreen_cache_key_includes_all_mrt_attachments :: proc(t: ^testing.T) {
254 + frame := ir.init_frame_ir()
255 + defer ir.destroy_frame_ir(&frame)
256 +
257 + color_a := ir.add_texture(&frame, "a", 16, 16, .B8G8R8A8_SRGB, {.Color_Attachment}, .Transient)
258 + color_b := ir.add_texture(&frame, "b", 16, 16, .R8G8B8A8_UNORM, {.Color_Attachment}, .Transient)
259 + pass_a := ir.Pass_Desc {kind = .Render, name = "mrt-a"}
260 + pass_b := ir.Pass_Desc {kind = .Render, name = "mrt-b"}
261 + testing.expect(t, ir.pass_add_color_target(&pass_a, ir.make_color_target(color_a, .B8G8R8A8_SRGB)))
262 + testing.expect(t, ir.pass_add_color_target(&pass_a, ir.make_color_target(color_b, .R8G8B8A8_UNORM)))
263 + testing.expect(t, ir.pass_add_color_target(&pass_b, ir.make_color_target(color_b, .R8G8B8A8_UNORM)))
264 + testing.expect(t, ir.pass_add_color_target(&pass_b, ir.make_color_target(color_a, .B8G8R8A8_SRGB)))
265 +
266 + caps := bk.implemented_base_capabilities(2, 0)
267 + key_a, ok_a := compiler.render_target_cache_key_with_capabilities(&frame, &pass_a, caps, 0)
268 + key_b, ok_b := compiler.render_target_cache_key_with_capabilities(&frame, &pass_b, caps, 0)
269 + testing.expect(t, ok_a)
270 + testing.expect(t, ok_b)
271 + testing.expect(t, key_a != key_b)
272 + testing.expect_value(t, key_a.color_count, u32(2))
273 + testing.expect_value(t, key_a.color_formats[0], ir.Format.B8G8R8A8_SRGB)
274 + testing.expect_value(t, key_a.color_formats[1], ir.Format.R8G8B8A8_UNORM)
275 + }
276 +
277 + @(test)
190 278 test_compiler_rejects_color_targets_over_capability_limit :: proc(t: ^testing.T) {
191 279 frame := ir.init_frame_ir()
192 280 defer ir.destroy_frame_ir(&frame)
121 unchanged lines hidden
314 402 }
315 403
316 404 @(test)
405 + test_compiler_prepares_mrt_pipeline_attachment_metadata :: proc(t: ^testing.T) {
406 + rec := recording_backend_init()
407 + defer recording_backend_destroy(&rec)
408 + frame := ir.init_frame_ir()
409 + defer ir.destroy_frame_ir(&frame)
410 +
411 + color_a := ir.add_texture(&frame, "a", 16, 16, .B8G8R8A8_SRGB, {.Color_Attachment}, .Transient)
412 + color_b := ir.add_texture(&frame, "b", 16, 16, .R8G8B8A8_UNORM, {.Color_Attachment}, .Transient)
413 + buffer := ir.add_buffer(&frame, "vertices", 256, {.Vertex}, {.Device_Local}, .Persistent)
414 + pass_desc := ir.Pass_Desc {kind = .Render, name = "mrt"}
415 + testing.expect(t, ir.pass_add_color_target(&pass_desc, ir.make_color_target(color_a, .B8G8R8A8_SRGB)))
416 + testing.expect(t, ir.pass_add_color_target(&pass_desc, ir.make_color_target(color_b, .R8G8B8A8_UNORM)))
417 + pass := ir.add_pass(&frame, pass_desc)
418 + vertex_shader := ir.add_shader(&frame, {stage = .Vertex, name = "vs"})
419 + fragment_shader := ir.add_shader(&frame, {stage = .Fragment, name = "fs"})
420 + pipeline_state := ir.default_graphics_pipeline_state()
421 + pipeline_state.vertex_shader = vertex_shader
422 + pipeline_state.fragment_shader = fragment_shader
423 + pipeline := ir.add_graphics_pipeline(&frame, "pipeline", pipeline_state)
424 + packet := ir.Draw_Packet {
425 + geometry = {kind = .Vertex_Stream, resource = buffer, vertex_count = 3},
426 + order = .Strict,
427 + }
428 + _ = ir.add_draw_packet(&frame, pass, pipeline, .Vertex_Stream, packet)
429 +
430 + backend := recording_backend_use(&rec)
431 + state := compiler.init_execution_state(&backend)
432 + defer compiler.destroy_execution_state_views(&state)
433 + append(
434 + &state.passes,
435 + compiler.Prepared_Pass {
436 + pass = pass,
437 + render_pass = bk.Render_Pass_Handle(21),
438 + framebuffer = bk.Framebuffer_Handle(22),
439 + begin_desc = compiler.build_begin_desc(&pass_desc, bk.Render_Pass_Handle(21), bk.Framebuffer_Handle(22)),
440 + },
441 + )
442 + append(&state.resources, compiler.Prepared_Resource {resource = buffer, kind = .Buffer, buffer = bk.Buffer_Handle(12)})
443 + append(&state.shaders, compiler.Prepared_Shader {shader = vertex_shader, stage = .Vertex, module = bk.Shader_Handle(41)})
444 + append(&state.shaders, compiler.Prepared_Shader {shader = fragment_shader, stage = .Fragment, module = bk.Shader_Handle(42)})
445 +
446 + _, ok := compiler.prepare_graphics_pipeline_for_pass(&state, &frame, pipeline, pass)
447 + testing.expect(t, ok)
448 + testing.expect_value(t, len(rec.calls), 1)
449 + testing.expect_value(t, rec.calls[0].kind, Recording_Call_Kind.Create_Graphics_Pipeline)
450 + testing.expect_value(t, rec.calls[0].color_count, u32(2))
451 + testing.expect_value(t, rec.calls[0].color_formats[0], bk.Format.B8G8R8A8_SRGB)
452 + testing.expect_value(t, rec.calls[0].color_formats[1], bk.Format.R8G8B8A8_UNORM)
453 + testing.expect(t, compiler.execute_prepared_planned_commands(&state, &frame, {}, {0, 0, 0, 1}))
454 + testing.expect_value(t, rec.calls[1].kind, Recording_Call_Kind.Begin_Render_Pass)
455 + testing.expect_value(t, rec.calls[1].color_count, u32(2))
456 + }
457 +
458 + @(test)
317 459 test_compiler_executes_planned_vertex_stream_draw :: proc(t: ^testing.T) {
318 460 rec := recording_backend_init()
319 461 defer recording_backend_destroy(&rec)
127 unchanged lines hidden