Harbor

branch main
showing the latest snapshot on main
capabilities_test.odin 4.8 KB · Plain text
gpu/tests/capabilities_test.odin 0644 Raw
package gpu_tests

import gpu ".."
import bk "../backend"
import "core:testing"

@(test)
test_gpu_capabilities_are_empty_without_backend :: proc(t: ^testing.T) {
	caps := gpu.get_capabilities()
	testing.expect(t, !gpu.supports(.Compute_Dispatch))
	testing.expect(t, !gpu.supports(.Storage_Buffers))
	testing.expect(t, !gpu.supports(.Offscreen_Targets))
	testing.expect(t, !gpu.supports(.Sampled_Targets))
	testing.expect(t, !gpu.supports(.Multiple_Render_Targets))
	testing.expect(t, !gpu.supports(.Stencil_Clips))
	testing.expect(t, !gpu.supports(.Indirect_Draws))
	testing.expect_value(t, caps.max_color_targets, u32(0))
	testing.expect_value(t, caps.max_push_constant_size, u32(0))
	testing.expect_value(t, caps.max_frames_in_flight, u32(0))
}

@(test)
test_backend_implemented_capabilities_are_conservative_and_explicit :: proc(t: ^testing.T) {
	caps := bk.implemented_base_capabilities(1, 240)
	testing.expect(t, bk.supports(caps, .Compute_Dispatch))
	testing.expect(t, bk.supports(caps, .Storage_Buffers))
	testing.expect(t, bk.supports(caps, .Offscreen_Targets))
	testing.expect(t, bk.supports(caps, .Sampled_Targets))
	testing.expect(t, bk.supports(caps, .Indirect_Draws))
	testing.expect(t, !bk.supports(caps, .Multiple_Render_Targets))
	testing.expect(t, bk.supports(caps, .Stencil_Clips))
	testing.expect_value(t, caps.max_color_targets, u32(1))
	testing.expect_value(t, caps.max_push_constant_size, u32(240))
	testing.expect_value(t, caps.max_frames_in_flight, u32(bk.MAX_FRAMES_IN_FLIGHT))
}

@(test)
test_backend_implemented_capabilities_enable_mrt_with_multi_target_limit :: proc(t: ^testing.T) {
	caps := bk.implemented_base_capabilities(bk.MAX_COLOR_TARGETS, 240)
	testing.expect(t, bk.supports(caps, .Multiple_Render_Targets))
	testing.expect_value(t, caps.max_color_targets, u32(bk.MAX_COLOR_TARGETS))
}

@(test)
test_backend_capability_limit_helpers :: proc(t: ^testing.T) {
	caps := bk.implemented_base_capabilities(1, 240)
	testing.expect(t, bk.supports_color_target_count(caps, 0))
	testing.expect(t, bk.supports_color_target_count(caps, 1))
	testing.expect(t, !bk.supports_color_target_count(caps, 2))
	testing.expect(t, bk.supports_push_constant_size(caps, 0))
	testing.expect(t, bk.supports_push_constant_size(caps, 240))
	testing.expect(t, !bk.supports_push_constant_size(caps, 241))
}

@(test)
test_vertex_layout_can_emit_instance_binding_metadata :: proc(t: ^testing.T) {
	layout := bk.vertex_layout_build(.Position, .Color)
	binding, attrs, attr_count := bk.vertex_layout_to_pipeline_attrs_for_binding(
		&layout,
		1,
		.Instance,
		3,
	)
	testing.expect_value(t, binding.binding, u32(1))
	testing.expect_value(t, binding.input_rate, bk.Vertex_Input_Rate.Instance)
	testing.expect_value(t, binding.stride, u32(28))
	testing.expect_value(t, attr_count, 2)
	testing.expect_value(t, attrs[0].location, u32(3))
	testing.expect_value(t, attrs[0].binding, u32(1))
	testing.expect_value(t, attrs[0].offset, u32(0))
	testing.expect_value(t, attrs[1].location, u32(4))
	testing.expect_value(t, attrs[1].binding, u32(1))
	testing.expect_value(t, attrs[1].offset, u32(12))
}

@(test)
test_backend_handle_index_rejects_null_and_out_of_range :: proc(t: ^testing.T) {
	_, null_ok := bk.handle_index(bk.NULL_BUFFER, 8)
	testing.expect(t, !null_ok)

	idx, valid_ok := bk.handle_index(bk.Buffer_Handle(1), 8)
	testing.expect(t, valid_ok)
	testing.expect_value(t, idx, 1)

	_, max_ok := bk.handle_index(bk.Buffer_Handle(8), 8)
	testing.expect(t, !max_ok)

	_, overflow_ok := bk.handle_index(bk.Texture_Handle(99), 8)
	testing.expect(t, !overflow_ok)
}

@(test)
test_backend_blend_factors_are_canonical :: proc(t: ^testing.T) {
	alpha := bk.blend_factors(.Alpha)
	testing.expect_value(t, alpha.src_color, bk.Blend_Factor.Src_Alpha)
	testing.expect_value(t, alpha.dst_color, bk.Blend_Factor.One_Minus_Src_Alpha)
	testing.expect_value(t, alpha.src_alpha, bk.Blend_Factor.One)
	testing.expect_value(t, alpha.dst_alpha, bk.Blend_Factor.One_Minus_Src_Alpha)

	additive := bk.blend_factors(.Additive)
	testing.expect_value(t, additive.src_color, bk.Blend_Factor.Src_Alpha)
	testing.expect_value(t, additive.dst_color, bk.Blend_Factor.One)
	testing.expect_value(t, additive.src_alpha, bk.Blend_Factor.One)
	testing.expect_value(t, additive.dst_alpha, bk.Blend_Factor.One)

	premultiplied := bk.blend_factors(.Premultiplied_Alpha)
	testing.expect_value(t, premultiplied.src_color, bk.Blend_Factor.One)
	testing.expect_value(t, premultiplied.dst_color, bk.Blend_Factor.One_Minus_Src_Alpha)
	testing.expect_value(t, premultiplied.src_alpha, bk.Blend_Factor.One)
	testing.expect_value(t, premultiplied.dst_alpha, bk.Blend_Factor.One_Minus_Src_Alpha)
}

@(test)
test_backend_vtable_rejects_missing_required_slots :: proc(t: ^testing.T) {
	testing.expect(t, !bk.backend_vtable_is_complete(nil))
	backend: bk.Backend
	testing.expect(t, !bk.backend_vtable_is_complete(&backend))
}