Harbor

branch main
showing the latest snapshot on main
mask_clip_test.odin 3.9 KB · Plain text
tests/render_ir/mask_clip_test.odin 0644 Raw
package render_ir_tests

import ir "../../render_ir"
import "core:testing"

make_mask_frame :: proc() -> (
	frame: ir.Frame_IR,
	target: ir.Target_Handle,
	coverage: ir.Resource_Handle,
) {
	frame = ir.init_frame_ir()
	target = ir.add_target(
		&frame,
		{
			kind = .Present,
			name = "present",
			width = 256,
			height = 256,
			color_format = .B8G8R8A8_SRGB,
			clear_color = {0, 0, 0, 1},
			clear_depth = 1,
		},
	)
	coverage = ir.add_buffer(&frame, "mask-coverage", 256, {.Vertex}, {.Host_Visible}, .Transient)
	return
}

@(test)
test_mask_clip_model_validates_semantic_handles :: proc(t: ^testing.T) {
	frame, target, coverage := make_mask_frame()
	defer ir.destroy_frame_ir(&frame)

	mask := ir.add_mask(
		&frame,
		{
			target = target,
			name = "round-coverage",
			source_kind = .Geometry_Coverage,
			coverage_resource = coverage,
			vertex_count = 6,
		},
	)
	clip := ir.add_clip(&frame, {target = target, kind = .Mask, mask = mask})

	testing.expect(t, mask != ir.INVALID_MASK)
	testing.expect(t, clip != ir.INVALID_CLIP)
	testing.expect_value(t, ir.mask_count(&frame), 1)
	testing.expect_value(t, ir.clip_count(&frame), 1)

	diagnostics := ir.init_diagnostics()
	defer ir.destroy_diagnostics(&diagnostics)
	ir.validate_intent_handles(&frame, &diagnostics)
	testing.expect_value(t, len(diagnostics.items), 0)
}

@(test)
test_mask_clip_rejects_invalid_mask_handle :: proc(t: ^testing.T) {
	frame, target, _ := make_mask_frame()
	defer ir.destroy_frame_ir(&frame)

	_ = ir.add_clip(&frame, {target = target, kind = .Mask, mask = ir.Mask_Handle(99)})

	diagnostics := ir.init_diagnostics()
	defer ir.destroy_diagnostics(&diagnostics)
	ir.validate_intent_handles(&frame, &diagnostics)
	testing.expect(t, ir.has_errors(&diagnostics))
	testing.expect_value(t, diagnostics.items[0].code, ir.Diagnostic_Code.Invalid_Mask)
}

@(test)
test_mask_clip_rejects_target_mismatch :: proc(t: ^testing.T) {
	frame, target_a, coverage := make_mask_frame()
	defer ir.destroy_frame_ir(&frame)
	target_b := ir.add_target(
		&frame,
		{
			kind = .Present,
			name = "other",
			width = 256,
			height = 256,
			color_format = .B8G8R8A8_SRGB,
			clear_color = {0, 0, 0, 1},
			clear_depth = 1,
		},
	)
	mask := ir.add_mask(
		&frame,
		{target = target_a, name = "mask", source_kind = .Geometry_Coverage, coverage_resource = coverage, vertex_count = 3},
	)
	_ = ir.add_clip(&frame, {target = target_b, kind = .Mask, mask = mask})

	diagnostics := ir.init_diagnostics()
	defer ir.destroy_diagnostics(&diagnostics)
	ir.validate_intent_handles(&frame, &diagnostics)
	testing.expect(t, ir.has_errors(&diagnostics))
	testing.expect_value(t, diagnostics.items[0].code, ir.Diagnostic_Code.Invalid_Mask)
}

@(test)
test_mask_clip_rejects_missing_source :: proc(t: ^testing.T) {
	frame, target, _ := make_mask_frame()
	defer ir.destroy_frame_ir(&frame)

	_ = ir.add_mask(&frame, {target = target, name = "empty"})

	diagnostics := ir.init_diagnostics()
	defer ir.destroy_diagnostics(&diagnostics)
	ir.validate_intent_handles(&frame, &diagnostics)
	testing.expect(t, ir.has_errors(&diagnostics))
	testing.expect_value(t, diagnostics.items[0].code, ir.Diagnostic_Code.Invalid_Mask)
}

@(test)
test_mask_clip_lowering_refuses_until_stencil_capability_exists :: proc(t: ^testing.T) {
	frame, target, coverage := make_mask_frame()
	defer ir.destroy_frame_ir(&frame)

	mask := ir.add_mask(
		&frame,
		{target = target, name = "mask", source_kind = .Geometry_Coverage, coverage_resource = coverage, vertex_count = 3},
	)
	_ = ir.add_clip(&frame, {target = target, kind = .Mask, mask = mask})

	diagnostics := ir.init_diagnostics()
	defer ir.destroy_diagnostics(&diagnostics)
	ir.validate_mask_clips_supported(&frame, &diagnostics, false)
	testing.expect(t, ir.has_errors(&diagnostics))
	testing.expect_value(t, diagnostics.items[0].code, ir.Diagnostic_Code.Stencil_Unsupported)

	ir.reset_diagnostics(&diagnostics)
	ir.validate_mask_clips_supported(&frame, &diagnostics, true)
	testing.expect(t, !ir.has_errors(&diagnostics))
}