| … | 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 | ||
| … | 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 | ||
Diff hidden because this file has more than 800 lines.
| … | 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 | ||
| … | 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 | ||
Diff hidden because this file has more than 800 lines.
| … | 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 | ||
| … | 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 | ||