package shader import "core:mem" import "core:testing" TRACKED_COMPUTE_SOURCE :: ` struct Params count: uint scale: float end struct DataBuffer values: [64]float end @group(0) @binding(0) buffer params: Params @group(0) @binding(1) buffer data: DataBuffer @entry(compute) @workgroup_size(64, 1, 1) function main(@builtin(global_invocation_id) global_id: uvec3) let idx = global_id.x data.values[idx] = data.values[idx] * params.scale end ` @(test) test_compile_result_destroy_releases_success_allocations :: proc(t: ^testing.T) { track: mem.Tracking_Allocator mem.tracking_allocator_init(&track, context.allocator) track.bad_free_callback = mem.tracking_allocator_bad_free_callback_add_to_array defer mem.tracking_allocator_destroy(&track) allocator := mem.tracking_allocator(&track) result := compile(TRACKED_COMPUTE_SOURCE, { target = .WGSL, stage = .Compute, opt_level = .Basic, }, "tracked_success.luma", allocator) testing.expect(t, result.success) testing.expect(t, len(result.output) > 0) testing.expect(t, len(result.reflection.entry_points) > 0) testing.expect(t, len(result.reflection.bindings) > 0) destroy_compile_result(&result) testing.expect_value(t, len(track.allocation_map), 0) testing.expect_value(t, len(track.bad_free_array), 0) } @(test) test_compile_result_destroy_releases_failure_allocations :: proc(t: ^testing.T) { track: mem.Tracking_Allocator mem.tracking_allocator_init(&track, context.allocator) track.bad_free_callback = mem.tracking_allocator_bad_free_callback_add_to_array defer mem.tracking_allocator_destroy(&track) allocator := mem.tracking_allocator(&track) result := compile("function main(\n", { target = .WGSL, stage = .Compute, }, "tracked_failure.luma", allocator) testing.expect(t, !result.success) testing.expect(t, len(result.diagnostics) > 0) testing.expect(t, len(result.diagnostics[0].message) > 0) destroy_compile_result(&result) testing.expect_value(t, len(track.allocation_map), 0) testing.expect_value(t, len(track.bad_free_array), 0) } @(test) test_compile_result_owned_across_repeated_compiles :: proc(t: ^testing.T) { track: mem.Tracking_Allocator mem.tracking_allocator_init(&track, context.allocator) track.bad_free_callback = mem.tracking_allocator_bad_free_callback_add_to_array defer mem.tracking_allocator_destroy(&track) allocator := mem.tracking_allocator(&track) first := compile(TRACKED_COMPUTE_SOURCE, { target = .WGSL, stage = .Compute, opt_level = .Basic, }, "first.luma", allocator) second := compile("function main(\n", { target = .WGSL, stage = .Compute, }, "second.luma", allocator) testing.expect(t, first.success) testing.expect(t, len(first.output) > 0) testing.expect(t, len(first.reflection.entry_points) > 0) testing.expect(t, !second.success) testing.expect(t, len(second.diagnostics) > 0) destroy_compile_result(&second) destroy_compile_result(&first) testing.expect_value(t, len(track.allocation_map), 0) testing.expect_value(t, len(track.bad_free_array), 0) }