9.9 KiB
9.9 KiB
renderer_resources
Purpose
renderer_resources owns Vulkan buffer, image, view, descriptor, sampler, shader-module, and pipeline construction on the renderer_device layer. It handles resource memory and handle lifetimes, but contains no window, swapchain, or presentation orchestration; those remain in renderer. It must not depend on renderer.
Module map
lib.rs: re-exportsDevice,Error,Result,device, andmake_extensionfromrenderer_device; declares four public resource modules.buffers.rs:BufferDescandBuffer; Vulkan buffer creation, GPU allocation/binding, raw access, and host mapping.images.rs:ImageDesc,Image,ImageViewDesc,ImageView, subresource ranges, extents, offsets, and queue ownership.ImageInnerdistinguishes allocated images from borrowed swapchain images.pipeline.rs: shader-stage and graphics/compute pipeline descriptions;DescriptorPool,DescriptorSetLayout,PipelineLayout,Sampler,ShaderModule, andPipeline.util.rs:eq_f32,ord_f32,hash_f32,F32, and the crate-privateweak_vecmodule /WeakVecused by image view tracking.
Key types and API
- These modules are public from
renderer_resources; the crate root re-exports the core device types anddevicemodule fromrenderer_devicefor resource construction. BufferDescconfigures Vulkan buffer flags, size, usage, queue families, memory location, allocation strategy, and optional debug name.Buffer::newallocates/binds memory;mapandmap_mutreturn mapped slices when available.Buffer::rawreturns the Vulkan handle andlenreturns the configured size. Mapping is bounded to the descriptor size, not the allocator block size.ImageDescconfigures image type, format, extent, layers/mips, samples, tiling, usage, initial layout, queue sharing, and allocation.Image::newcreates an allocated image.Image::new_with_allocationaccepts an explicitrenderer_device::device::Allocationand validates size and memory-type compatibility.Image::from_swapchain_raw(image, device, format, extent, usage)builds an image wrapper for an image owned by a swapchain; renderer calls it fromSwapchain::acquire_image.ImageViewDescdescribes a view's type, format, component mapping, aspect, mip range, and layer range.Image::create_viewvalidates compatibility and returnsManuallyDrop<ImageView>.Image::create_viewresolves remaining mip/layer sentinels against the parent image, defaults an undefined view format to the image format, and checks image/view kind and format compatibility.Extent,Offset, andMipRangerepresent image dimensions, offsets, and mip/layer ranges.QueueOwnershipcarries source and destination family indices.Imageexposes its raw handle, format, dimensions, and optional allocation; swapchain-backed images have no allocation.- Pipeline configuration records include
ShaderStageDesc,GraphicsPipelineDesc,ComputePipelineDesc,PipelineLayoutDesc,DescriptorSetLayoutDesc,DescriptorSetLayoutBindingDesc,DescriptorPoolDesc,DescriptorSetAllocDesc,SamplerDesc, and fixed-function state descriptions. - Fixed-function state records are
VertexInputState,TessellationState,InputAssemblyState,ViewportState,DepthBiasState,RasterizationState,MultisampleState,DepthBounds,DepthState,StencilState,DepthStencilState,ColorBlendState,RenderingState, andDynamicState. Pipelinewraps graphics or compute Vulkan pipelines and retains itsPipelineLayoutin anArc. Creation usesdevice.pools.pipeline_cache.raw.DescriptorPoolserializes allocation/reset with a mutex; descriptor set layouts and pipeline layouts own their Vulkan handles.DescriptorPool::allocatereturns raw descriptor-set handles from the providedDescriptorSetLayoutvalues and optionally assigns names fromDescriptorSetAllocDesc.DescriptorSetLayout::newapplies per-binding descriptor flags when the device supports Vulkan 1.2 orVK_EXT_descriptor_indexing.PipelineLayoutDescreferences descriptor-set layouts and push-constant ranges;PipelineLayoutowns the created Vulkan layout.SamplerDescdescribes filtering, addressing, anisotropy, compare, LOD, and border settings;Sampler::newcreates the Vulkan sampler.ShaderModule::new_from_pathreads a shader file relative to the process working directory; file-open failures map toError::AssetMissing, while read/Vulkan failures use their correspondingErrorconversions.new_from_memoryaccepts SPIR-V words.GraphicsPipelineDescsupports render-pass/subpass inputs or dynamicRenderingState; optional fixed-function states are converted during pipeline creation.SamplerDescuseseq_f32/hash_f32for float-valued fields.F32providesEq/Ord/Hashsemantics using the same helpers.WeakVec<T>storesWeak<T>references and prunes entries whose strong count is zero when growing; it is crate-private, not public API.
Invariants and gotchas
- This crate consumes the
renderer_deviceownership types and re-exports; do not add a parallel device model or a dependency onrenderer. Image::from_swapchain_rawstores the raw image in theImageInner::Swapchainvariant with its device. The swapchain owns that Vulkan image; never destroy it as an independently allocated image.from_swapchain_rawrecords a 2D, one-mip, one-layer, single-sample, optimal-tiled image with PRESENT queue sharing and UNDEFINED initial layout; the caller supplies format, extent, and usage.from_swapchain_rawretains aDevicefor views and device queries, but not ownership of the image handle or swapchain lifetime; the renderer's frame/swapchain token must keep the swapchain alive.- Allocated images and buffers use
DeviceObjectfor Vulkan handles and allocation ownership. Keep resource destruction ordered before freeing bound memory. Bufferequality compares the raw buffer handle;Imageequality compares the raw image handle. Descriptor equality is separate from resource object identity.Allocation::Ownedowns a device-managed allocation;Sharedshares it throughArcand permits mutable access only when uniquely held;Unmanagedcarries no allocation.ImageViewretainsArc<Image>so the source image outlives the view.Image::create_viewreturnsManuallyDrop<ImageView>; callers must transfer/drop it deliberately.Imagetracks views throughWeakVec<ImageView>to avoid a strong-reference cycle. The weak list does not keep views alive.ImageView'sDeviceObjectowns and destroys the Vulkan view; its parentArc<Image>must remain alive through view destruction.ImageDescandBufferDescomitalloc_schemefrom bothHashandEq; theirHashimplementations omitname, andEqalso omitsname. Do not treat these descriptors as complete resource identities without accounting for these fields.- Descriptor hashing/equality covers resource shape, usage, sharing, and memory location but not every construction input. Update both implementations together if adding descriptor-keyed resource deduplication.
Pipelineretains its layout withArc; descriptor-pool operations are mutex-serialized. Keep these lifetime and synchronization guarantees when changing constructors or wrappers.DescriptorPool::allocatereturns rawvk::DescriptorSethandles; keep the owning pool alive while those sets are in use. Descriptor sets are not wrapped in owning resource objects here.- Descriptor-set layout binding flags are chained into layout creation when the device API version or descriptor-indexing extension supports them.
- Pipeline cache lifetime and teardown belong to
renderer_device; use the device's existing cache rather than adding a resource-crate cache. - Renderer shader assets remain under
crates/renderer/shaders; this crate does not own those assets. rendereraccesses these modules through crate-private aliases. Making a resource type available inrenderer's public API requires an explicit API/re-export decision there.
Conventions
renderer_resourceshas no crate-level nightly feature attributes; use APIs available under the workspace's pinned nightly toolchain and edition 2024.- Depend on
renderer_devicepaths re-exported at this crate root (crate::Device,crate::device::..., andcrate::make_extension) rather than introducing a dependency onrenderer. - Do not commit changes. Verify with
cargo check -p renderer_resourcesandcargo check --workspacefrom the workspace root.
Change guidance
- Add buffer, image, view, descriptor, sampler, shader, and pipeline constructors in this crate, not in
renderer's orchestration layer. - For each Vulkan handle, preserve the distinction between resource-owned handles and externally owned handles such as raw swapchain images.
- Keep image-view range/format/kind validation close to image/view construction. Cover
REMAINING_MIP_LEVELSandREMAINING_ARRAY_LAYERSnormalization when changing range handling. - When modifying descriptor equality/hash behavior, update both together and account for
nameandalloc_schemedeliberately. - Preserve
renderer_device::device::Allocationownership semantics when accepting shared or unmanaged memory; ensure bound resources outlive their allocation use. - Keep
SamplerDescfloat equality and hashing consistent across every float field. renderer_resources::util::weak_vecis internal support for images; do not expose or move it back intorendererwithout reviewing view ownership cycles.- Keep shader loading errors compatible with
renderer_device::Error, and test path-based loading relative to the workspace runtime working directory. - Keep this crate independent of swapchain/window wrappers. Integrate swapchain images through the raw image plus explicit device, format, extent, and usage, not renderer types.
- Keep pipeline descriptors, Vulkan state conversion, and handle ownership in this crate rather than moving resource ownership back into renderer orchestration.