Harbor

Changelog 7f752ff3403c

pin implemented capabilities

@sky · 1 month ago · parent c56a8f0cd760
0 added 8 modified 0 deleted
gpu/backend/backend.odin +12 -2 modified
37 unchanged lines hidden
38 38 Capabilities :: struct {
39 39 features: Capability_Flags,
40 40 max_color_targets: u32,
41 + max_push_constant_size: u32,
41 42 max_frames_in_flight: u32,
42 43 }
43 44
1 unchanged lines hidden
45 46 return {}
46 47 }
47 48
48 - advertised_render_capabilities :: proc() -> Capabilities {
49 + implemented_base_capabilities :: proc(max_color_targets, max_push_constant_size: u32) -> Capabilities {
49 50 return {
50 51 features = {
51 52 .Compute_Dispatch,
1 unchanged lines hidden
53 54 .Offscreen_Targets,
54 55 .Sampled_Targets,
55 56 },
56 - max_color_targets = 1,
57 + max_color_targets = max_color_targets,
58 + max_push_constant_size = max_push_constant_size,
57 59 max_frames_in_flight = MAX_FRAMES_IN_FLIGHT,
58 60 }
59 61 }
2 unchanged lines hidden
62 64 return capability in caps.features
63 65 }
64 66
67 + supports_color_target_count :: proc(caps: Capabilities, count: u32) -> bool {
68 + return count == 0 || count <= caps.max_color_targets
69 + }
70 +
71 + supports_push_constant_size :: proc(caps: Capabilities, size: u32) -> bool {
72 + return size == 0 || size <= caps.max_push_constant_size
73 + }
74 +
65 75 // --- Surface descriptors ---
66 76
67 77 Surface_Kind :: enum {
462 unchanged lines hidden
gpu/backend/d3d11/d3d11_backend.odin +1 -1 modified
330 unchanged lines hidden
331 331
332 332 // Populate backend vtable
333 333 backend = bk.Backend{
334 - capabilities = bk.advertised_render_capabilities(),
334 + capabilities = bk.implemented_base_capabilities(1, PUSH_CONSTANT_MAX_SIZE),
335 335
336 336 // Lifecycle
337 337 shutdown = shutdown_d3d11,
243 unchanged lines hidden
gpu/backend/d3d12/d3d12_backend.odin modified

Diff hidden because this file has more than 800 lines.

gpu/backend/opengl/gl_backend.odin +1 -1 modified
156 unchanged lines hidden
157 157 gl.NamedBufferData(state.push_constant_buffer, PUSH_CONSTANT_MAX_SIZE, nil, gl.DYNAMIC_DRAW)
158 158
159 159 backend = bk.Backend{
160 - capabilities = bk.advertised_render_capabilities(),
160 + capabilities = bk.implemented_base_capabilities(1, PUSH_CONSTANT_MAX_SIZE),
161 161
162 162 shutdown = shutdown_opengl,
163 163 wait_idle = wait_idle_opengl,
142 unchanged lines hidden
gpu/backend/vulkan/vk_backend.odin +6 -1 modified
49 unchanged lines hidden
50 50 MAX_FRAMEBUFFERS :: 64
51 51 MAX_SAMPLERS :: 64
52 52
53 + VULKAN_IMPLEMENTED_PUSH_CONSTANT_MAX_SIZE :: 256
54 +
53 55 // Pool entry types
54 56 Vk_Buffer_Entry :: struct {
55 57 buffer: gpu.Gpu_Buffer,
215 unchanged lines hidden
271 273
272 274 // Populate backend vtable
273 275 backend = bk.Backend{
274 - capabilities = bk.advertised_render_capabilities(),
276 + capabilities = bk.implemented_base_capabilities(
277 + 1,
278 + min(state.device.properties.limits.maxPushConstantsSize, u32(VULKAN_IMPLEMENTED_PUSH_CONSTANT_MAX_SIZE)),
279 + ),
275 280
276 281 // Lifecycle
277 282 shutdown = shutdown_vk,
242 unchanged lines hidden
gpu/gpu.odin modified

Diff hidden because this file has more than 800 lines.

gpu/resource/resource.odin +9 -0 modified
259 unchanged lines hidden
260 260 log.errorf("gpu/resource: compute shader '%s' format does not match backend requirement", name)
261 261 return 0, false
262 262 }
263 + if !bk.supports_push_constant_size(b.capabilities, push_constant_size) {
264 + log.errorf(
265 + "gpu/resource: compute shader '%s' push constant size %d exceeds backend implemented limit %d",
266 + name,
267 + push_constant_size,
268 + b.capabilities.max_push_constant_size,
269 + )
270 + return 0, false
271 + }
263 272
264 273 slot: u32
265 274 slot_found := false
224 unchanged lines hidden
gpu/tests/capabilities_test.odin +15 -2 modified
14 unchanged lines hidden
15 15 testing.expect(t, !gpu.supports(.Stencil_Clips))
16 16 testing.expect(t, !gpu.supports(.Indirect_Draws))
17 17 testing.expect_value(t, caps.max_color_targets, u32(0))
18 + testing.expect_value(t, caps.max_push_constant_size, u32(0))
18 19 testing.expect_value(t, caps.max_frames_in_flight, u32(0))
19 20 }
20 21
21 22 @(test)
22 - test_backend_advertised_capabilities_are_neutral_and_explicit :: proc(t: ^testing.T) {
23 - caps := bk.advertised_render_capabilities()
23 + test_backend_implemented_capabilities_are_conservative_and_explicit :: proc(t: ^testing.T) {
24 + caps := bk.implemented_base_capabilities(1, 240)
24 25 testing.expect(t, bk.supports(caps, .Compute_Dispatch))
25 26 testing.expect(t, bk.supports(caps, .Storage_Buffers))
26 27 testing.expect(t, bk.supports(caps, .Offscreen_Targets))
2 unchanged lines hidden
29 30 testing.expect(t, !bk.supports(caps, .Stencil_Clips))
30 31 testing.expect(t, !bk.supports(caps, .Indirect_Draws))
31 32 testing.expect_value(t, caps.max_color_targets, u32(1))
33 + testing.expect_value(t, caps.max_push_constant_size, u32(240))
32 34 testing.expect_value(t, caps.max_frames_in_flight, u32(bk.MAX_FRAMES_IN_FLIGHT))
33 35 }
34 36
35 37 @(test)
38 + test_backend_capability_limit_helpers :: proc(t: ^testing.T) {
39 + caps := bk.implemented_base_capabilities(1, 240)
40 + testing.expect(t, bk.supports_color_target_count(caps, 0))
41 + testing.expect(t, bk.supports_color_target_count(caps, 1))
42 + testing.expect(t, !bk.supports_color_target_count(caps, 2))
43 + testing.expect(t, bk.supports_push_constant_size(caps, 0))
44 + testing.expect(t, bk.supports_push_constant_size(caps, 240))
45 + testing.expect(t, !bk.supports_push_constant_size(caps, 241))
46 + }
47 +
48 + @(test)
36 49 test_backend_vtable_rejects_missing_required_slots :: proc(t: ^testing.T) {
37 50 testing.expect(t, !bk.backend_vtable_is_complete(nil))
38 51 backend: bk.Backend
2 unchanged lines hidden