Commit graph Crafter.Graphics/examples/SponzaBench
Author SHA1 Message Date
6e94cc6209
fix(rt): split Sponza's combined image sampler into a heap texture and sampler
examples/Sponza no longer built natively (#164). Its closest-hit declared a
descriptor_heap sampler2D, which glslang has rejected since c8253623
("Reject descriptor_heap combined image samplers"), and main.cpp wrote it
through VkResourceDescriptorDataEXT::pCombinedImageSampler, which that union
no longer has: the descriptor heap has no combined image samplers. Both went
unnoticed because nothing builds the examples.

Sponza
- closesthit.glsl declares texture2D and sampler heap arrays and joins them
  where it samples, as ui-shared.glsl and HeapDynamicIndexHit do. The
  sampler slot is a second spec constant beside the image slot, so the
  shader assumes nothing about where the host put it, and a constant index
  keeps the example running on NVIDIA 610.43.02 (see its README). The
  comment no longer says the image slot is offset by bufferStartElement;
  only buffer slots are.
- main.cpp gives the heap a sampler slot, writes the albedo as a
  SAMPLED_IMAGE from a view create-info, and writes the sampler into the
  sampler heap from a VkSamplerCreateInfo with vkWriteSamplerDescriptorsEXT,
  as UIRenderer::RegisterSampler does. SamplerVulkan's VkSampler had no use
  left. The sampler keeps its linear filtering and repeat addressing and
  drops anisotropy, which a hit shader cannot use: it samples at LOD 0,
  without derivatives.

Docs
- README.md and examples/Sponza/README.md quote the new declarations, and
  the Sponza README says why the texture and the sampler are two
  descriptors. Its texture2DArray materials pattern declared a
  descriptor_heap sampler2DArray, which glslang rejects as well; it now
  joins a texture2DArray and a sampler.
- examples/SponzaBench/README.md drops its caveat that Sponza does not
  compile.

Tests
- ExampleShaders compiles every GLSL shader under examples/ with glslang as
  crafter-build does for the example (Vulkan rules, SPIR-V 1.4, shaders/ on
  the include path, and the descriptor-set build where the example
  registers one), so a glslang that starts rejecting one fails a test
  rather than an example build nobody runs. It fails on Sponza's old
  closest-hit and needs glslang only.

Closes #164.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 08:25:52 +01:00
bcdc885de8
feat(device): applications ask for the device features their shaders use
Device
- Device::Initialize(required, optional) takes DeviceFeatures, the five
  core feature structs vulkan10 to vulkan14. The library enables only what
  its own shaders and code use. Device::enabledFeatures says what was
  enabled, supportedFeatures what the GPU has, apiVersion the version in
  use.
- shaderInt16, shaderFloat16, storageBuffer16BitAccess, scalarBlockLayout
  and the uniform-buffer, storage-buffer and storage-image non-uniform
  indexing bits are no longer enabled for everyone. An application whose
  shaders take uint16_t spec constants passes
  {.vulkan10 = {.shaderInt16 = VK_TRUE}}. scalarBlockLayout stays on with
  the NVIDIA workaround, whose TLAS address may sit in a struct's tail
  padding.
- Every GPU is weighed before one is chosen: Vulkan 1.3, the swapchain and,
  below 1.4, maintenance5 extensions, the library's needs, the required
  features. One that can't run the application is skipped, saying why when
  it ranks higher. A CPU device runs it only when nothing else is listed,
  and CRAFTER_GRAPHICS_DEVICE never falls back. A GPU two drivers both list
  is tried through each.
- When no GPU qualifies, Initialize throws naming each GPU's gaps. It
  destroys the instance it made, before any Wayland connection, so it can
  be called again asking for less.
- maintenance5 is vulkan14's on a 1.4 GPU and VK_KHR_maintenance5's below.
  CRAFTER_GRAPHICS_NO_VULKAN_1_4 runs as a 1.3 application, to exercise
  that path on a 1.4 GPU.
- VK_KHR_spirv_1_4 and VK_KHR_shader_float_controls, core since 1.2, are no
  longer enabled, nor VK_EXT_shader_atomic_float, which was enabled without
  its feature struct. memoryDecompression's feature bit is queried before
  it is enabled.

Shaders
- VulkanShader checks a module's capabilities, declared directly or
  implicitly, against the enabled core features, the GPU's subgroup
  operations and the optional groups, and throws naming the field to pass,
  or saying the GPU lacks it. The tables are generated from vk.xml and
  SPIR-V's grammar.
- WorkaroundNvidiaAS::Patch sized a row-major matrix push member by its
  columns, so the TLAS address could land inside it.

Window
- The swapchain format is one whose own feature flags allow storage reads
  and writes without a format, which since Vulkan 1.3 each format says for
  itself; shaderStorageImageRead/WriteWithoutFormat are no longer required.

Tests
- DeviceFeatures: ResolveFeatures, ChooseDevice and CheckShaderCapabilities,
  without a GPU.
- FeatureRequests: required and optional features end to end, the 1.3
  path, and a retry after a refusal.
- PushConstantRewrite: a row-major mat3x4 push member.
- HeapASRead, HeapDynamicIndexHit, RTPassPushData and the ray-tracing
  examples ask for the features their shaders use.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 06:40:02 +01:00
449d5da553
docs: where the NVIDIA descriptor-heap faults stand on 615.78.08
The heap acceleration-structure read still needs the rewrite on
615.78.08; the READMEs say so and point at HeapASRead --no-workaround
for checking a newer driver. Dynamic descriptor indexing in hit shaders
is fixed there, which the README and the Sponza and SponzaBench notes
now say, and the VulkanTriangle investigation no longer contradicts
itself about llvmpipe, which advertises VK_EXT_descriptor_heap now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 03:03:17 +02:00
42a479572d SPDX license update 2026-07-22 18:09:06 +02:00
catbot
619e39369d test(bench): SponzaBench harness + #40→HEAD perf measurement (#155)
Headless benchmark around the native Sponza RT scene: times setup and a
measured Render() loop over the full multi-mesh atrium, prints BENCH
metrics, and exits. Includes run-bench.sh and a README documenting the
methodology and the measured net gain from #40 to current master.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 19:35:54 +00:00