dx12: use persistently bound buffers
This commit is contained in:
parent
f077f86bad
commit
fd48d88fdd
|
@ -1,19 +1,17 @@
|
||||||
use crate::error;
|
use crate::error;
|
||||||
use crate::error::assume_d3d12_init;
|
use crate::error::assume_d3d12_init;
|
||||||
use std::ops::Range;
|
use std::ffi::c_void;
|
||||||
|
use std::mem::ManuallyDrop;
|
||||||
|
use std::ops::{Deref, DerefMut, Range};
|
||||||
|
use std::ptr::NonNull;
|
||||||
use windows::Win32::Graphics::Direct3D12::{
|
use windows::Win32::Graphics::Direct3D12::{
|
||||||
ID3D12Device, ID3D12Resource, D3D12_CONSTANT_BUFFER_VIEW_DESC, D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
|
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
|
||||||
D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_UPLOAD, D3D12_MEMORY_POOL_UNKNOWN,
|
D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_UPLOAD, D3D12_MEMORY_POOL_UNKNOWN,
|
||||||
D3D12_RANGE, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_BUFFER,
|
D3D12_RANGE, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_BUFFER,
|
||||||
D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
|
D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
|
||||||
};
|
};
|
||||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
|
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
|
||||||
|
|
||||||
pub struct D3D12ConstantBuffer {
|
|
||||||
pub buffer: D3D12Buffer,
|
|
||||||
pub desc: D3D12_CONSTANT_BUFFER_VIEW_DESC,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct D3D12Buffer {
|
pub struct D3D12Buffer {
|
||||||
handle: ID3D12Resource,
|
handle: ID3D12Resource,
|
||||||
size: usize,
|
size: usize,
|
||||||
|
@ -100,15 +98,56 @@ impl D3D12Buffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl D3D12ConstantBuffer {
|
/// SAFETY: Creating the pointer should be safe in multithreaded contexts.
|
||||||
pub fn new(buffer: D3D12Buffer) -> D3D12ConstantBuffer {
|
///
|
||||||
unsafe {
|
/// Mutation is guarded by DerefMut<Target=[u8]>
|
||||||
let desc = D3D12_CONSTANT_BUFFER_VIEW_DESC {
|
unsafe impl Send for RawD3D12Buffer {}
|
||||||
BufferLocation: buffer.handle.GetGPUVirtualAddress(),
|
pub struct RawD3D12Buffer {
|
||||||
SizeInBytes: buffer.size as u32,
|
buffer: ManuallyDrop<D3D12Buffer>,
|
||||||
};
|
ptr: NonNull<c_void>,
|
||||||
|
}
|
||||||
|
|
||||||
D3D12ConstantBuffer { buffer, desc }
|
impl RawD3D12Buffer {
|
||||||
|
pub fn new(buffer: D3D12Buffer) -> error::Result<Self> {
|
||||||
|
let buffer = ManuallyDrop::new(buffer);
|
||||||
|
let range = D3D12_RANGE { Begin: 0, End: 0 };
|
||||||
|
let mut ptr = std::ptr::null_mut();
|
||||||
|
unsafe {
|
||||||
|
buffer.handle.Map(0, Some(&range), Some(&mut ptr))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// panic-safety: If Map returns Ok then ptr is not null
|
||||||
|
assert!(!ptr.is_null());
|
||||||
|
|
||||||
|
let ptr = unsafe { NonNull::new_unchecked(ptr) };
|
||||||
|
|
||||||
|
Ok(RawD3D12Buffer { buffer, ptr })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_cbv(&self, index: u32, cmd: &ID3D12GraphicsCommandList) {
|
||||||
|
unsafe { cmd.SetGraphicsRootConstantBufferView(index, self.buffer.gpu_address()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for RawD3D12Buffer {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
self.buffer.handle.Unmap(0, None);
|
||||||
|
ManuallyDrop::drop(&mut self.buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Deref for RawD3D12Buffer {
|
||||||
|
type Target = [u8];
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
unsafe { std::slice::from_raw_parts(self.ptr.as_ptr().cast(), self.buffer.size) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for RawD3D12Buffer {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
unsafe { std::slice::from_raw_parts_mut(self.ptr.as_ptr().cast(), self.buffer.size) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::error;
|
use crate::error;
|
||||||
|
use bitvec::bitvec;
|
||||||
|
use bitvec::boxed::BitBox;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use bitvec::{bits, bitvec};
|
|
||||||
use bitvec::boxed::BitBox;
|
|
||||||
|
|
||||||
use crate::error::FilterChainError;
|
use crate::error::FilterChainError;
|
||||||
use windows::Win32::Graphics::Direct3D12::{
|
use windows::Win32::Graphics::Direct3D12::{
|
||||||
|
@ -193,7 +193,7 @@ impl<T> D3D12DescriptorHeap<T> {
|
||||||
handle_size: device.GetDescriptorHandleIncrementSize(desc.Type) as usize,
|
handle_size: device.GetDescriptorHandleIncrementSize(desc.Type) as usize,
|
||||||
start: 0,
|
start: 0,
|
||||||
num_descriptors: desc.NumDescriptors as usize,
|
num_descriptors: desc.NumDescriptors as usize,
|
||||||
map: bitvec![0; desc.NumDescriptors as usize].into_boxed_bitslice()
|
map: bitvec![0; desc.NumDescriptors as usize].into_boxed_bitslice(),
|
||||||
})),
|
})),
|
||||||
PhantomData::default(),
|
PhantomData::default(),
|
||||||
))
|
))
|
||||||
|
@ -253,7 +253,7 @@ impl<T> D3D12DescriptorHeap<T> {
|
||||||
handle_size: inner.handle_size,
|
handle_size: inner.handle_size,
|
||||||
start: 0,
|
start: 0,
|
||||||
num_descriptors: size,
|
num_descriptors: size,
|
||||||
map: bitvec![0; size].into_boxed_bitslice()
|
map: bitvec![0; size].into_boxed_bitslice(),
|
||||||
});
|
});
|
||||||
|
|
||||||
start += size;
|
start += size;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use std::error::Error;
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
/// Cumulative error type for Direct3D12 filter chains.
|
/// Cumulative error type for Direct3D12 filter chains.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::buffer::{D3D12Buffer, D3D12ConstantBuffer};
|
use crate::buffer::{D3D12Buffer, RawD3D12Buffer};
|
||||||
use crate::descriptor_heap::{
|
use crate::descriptor_heap::{
|
||||||
CpuStagingHeap, D3D12DescriptorHeap, RenderTargetHeap, ResourceWorkHeap,
|
CpuStagingHeap, D3D12DescriptorHeap, RenderTargetHeap, ResourceWorkHeap,
|
||||||
};
|
};
|
||||||
|
@ -391,8 +391,8 @@ impl FilterChainD3D12 {
|
||||||
let Ok(graphics_pipeline) =
|
let Ok(graphics_pipeline) =
|
||||||
D3D12GraphicsPipeline::new_from_dxil(
|
D3D12GraphicsPipeline::new_from_dxil(
|
||||||
device,
|
device,
|
||||||
&library,
|
library,
|
||||||
&validator,
|
validator,
|
||||||
&dxil,
|
&dxil,
|
||||||
root_signature,
|
root_signature,
|
||||||
render_format,
|
render_format,
|
||||||
|
@ -401,8 +401,8 @@ impl FilterChainD3D12 {
|
||||||
} else {
|
} else {
|
||||||
let graphics_pipeline = D3D12GraphicsPipeline::new_from_hlsl(
|
let graphics_pipeline = D3D12GraphicsPipeline::new_from_hlsl(
|
||||||
device,
|
device,
|
||||||
&library,
|
library,
|
||||||
&compiler,
|
compiler,
|
||||||
&hlsl,
|
&hlsl,
|
||||||
root_signature,
|
root_signature,
|
||||||
render_format,
|
render_format,
|
||||||
|
@ -410,37 +410,26 @@ impl FilterChainD3D12 {
|
||||||
(hlsl_reflection, graphics_pipeline)
|
(hlsl_reflection, graphics_pipeline)
|
||||||
};
|
};
|
||||||
|
|
||||||
let uniform_storage = UniformStorage::new(
|
// minimum size here has to be 1 byte.
|
||||||
reflection.ubo.as_ref().map_or(0, |ubo| ubo.size as usize),
|
let ubo_size = reflection.ubo.as_ref().map_or(1, |ubo| ubo.size as usize);
|
||||||
reflection
|
let push_size = reflection
|
||||||
.push_constant
|
.push_constant
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(0, |push| push.size as usize),
|
.map_or(1, |push| push.size as usize);
|
||||||
|
|
||||||
|
let uniform_storage = UniformStorage::new_with_storage(
|
||||||
|
RawD3D12Buffer::new(D3D12Buffer::new(device, ubo_size)?)?,
|
||||||
|
RawD3D12Buffer::new(D3D12Buffer::new(device, push_size)?)?
|
||||||
);
|
);
|
||||||
|
|
||||||
let ubo_cbuffer = if let Some(ubo) = &reflection.ubo && ubo.size != 0 {
|
|
||||||
let buffer = D3D12ConstantBuffer::new(D3D12Buffer::new(device, ubo.size as usize)?);
|
|
||||||
Some(buffer)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let push_cbuffer = if let Some(push) = &reflection.push_constant && push.size != 0 {
|
|
||||||
let buffer = D3D12ConstantBuffer::new(D3D12Buffer::new(device, push.size as usize)?);
|
|
||||||
Some(buffer)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let uniform_bindings = reflection.meta.create_binding_map(|param| param.offset());
|
let uniform_bindings = reflection.meta.create_binding_map(|param| param.offset());
|
||||||
|
|
||||||
Ok((reflection,
|
Ok((reflection,
|
||||||
uniform_bindings,
|
uniform_bindings,
|
||||||
uniform_storage,
|
uniform_storage,
|
||||||
push_cbuffer,
|
|
||||||
ubo_cbuffer,
|
|
||||||
graphics_pipeline,
|
graphics_pipeline,
|
||||||
config.clone(),
|
config,
|
||||||
source))
|
source))
|
||||||
|
|
||||||
}).collect();
|
}).collect();
|
||||||
|
@ -456,16 +445,7 @@ impl FilterChainD3D12 {
|
||||||
.map(
|
.map(
|
||||||
|(
|
|(
|
||||||
(
|
(
|
||||||
(
|
(reflection, uniform_bindings, uniform_storage, pipeline, config, source),
|
||||||
reflection,
|
|
||||||
uniform_bindings,
|
|
||||||
uniform_storage,
|
|
||||||
push_cbuffer,
|
|
||||||
ubo_cbuffer,
|
|
||||||
pipeline,
|
|
||||||
config,
|
|
||||||
source,
|
|
||||||
),
|
|
||||||
mut texture_heap,
|
mut texture_heap,
|
||||||
),
|
),
|
||||||
mut sampler_heap,
|
mut sampler_heap,
|
||||||
|
@ -476,8 +456,6 @@ impl FilterChainD3D12 {
|
||||||
reflection,
|
reflection,
|
||||||
uniform_bindings,
|
uniform_bindings,
|
||||||
uniform_storage,
|
uniform_storage,
|
||||||
push_cbuffer,
|
|
||||||
ubo_cbuffer,
|
|
||||||
pipeline,
|
pipeline,
|
||||||
config,
|
config,
|
||||||
texture_heap,
|
texture_heap,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::buffer::D3D12ConstantBuffer;
|
use crate::buffer::RawD3D12Buffer;
|
||||||
use crate::descriptor_heap::{D3D12DescriptorHeapSlot, ResourceWorkHeap, SamplerWorkHeap};
|
use crate::descriptor_heap::{D3D12DescriptorHeapSlot, ResourceWorkHeap, SamplerWorkHeap};
|
||||||
use crate::error;
|
use crate::error;
|
||||||
use crate::filter_chain::FilterCommon;
|
use crate::filter_chain::FilterCommon;
|
||||||
|
@ -13,7 +13,7 @@ use librashader_reflect::reflect::semantics::{MemberOffset, TextureBinding, Unif
|
||||||
use librashader_reflect::reflect::ShaderReflection;
|
use librashader_reflect::reflect::ShaderReflection;
|
||||||
use librashader_runtime::binding::{BindSemantics, TextureInput};
|
use librashader_runtime::binding::{BindSemantics, TextureInput};
|
||||||
use librashader_runtime::quad::QuadType;
|
use librashader_runtime::quad::QuadType;
|
||||||
use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess};
|
use librashader_runtime::uniforms::{NoUniformBinder, UniformStorage};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use windows::core::Interface;
|
use windows::core::Interface;
|
||||||
|
@ -30,9 +30,8 @@ pub(crate) struct FilterPass {
|
||||||
pub(crate) reflection: ShaderReflection,
|
pub(crate) reflection: ShaderReflection,
|
||||||
pub(crate) config: ShaderPassConfig,
|
pub(crate) config: ShaderPassConfig,
|
||||||
pub(crate) uniform_bindings: FxHashMap<UniformBinding, MemberOffset>,
|
pub(crate) uniform_bindings: FxHashMap<UniformBinding, MemberOffset>,
|
||||||
pub uniform_storage: UniformStorage,
|
pub uniform_storage:
|
||||||
pub(crate) push_cbuffer: Option<D3D12ConstantBuffer>,
|
UniformStorage<NoUniformBinder, Option<()>, RawD3D12Buffer, RawD3D12Buffer>,
|
||||||
pub(crate) ubo_cbuffer: Option<D3D12ConstantBuffer>,
|
|
||||||
pub(crate) texture_heap: [D3D12DescriptorHeapSlot<ResourceWorkHeap>; 16],
|
pub(crate) texture_heap: [D3D12DescriptorHeapSlot<ResourceWorkHeap>; 16],
|
||||||
pub(crate) sampler_heap: [D3D12DescriptorHeapSlot<SamplerWorkHeap>; 16],
|
pub(crate) sampler_heap: [D3D12DescriptorHeapSlot<SamplerWorkHeap>; 16],
|
||||||
pub source: ShaderSource,
|
pub source: ShaderSource,
|
||||||
|
@ -44,7 +43,7 @@ impl TextureInput for InputTexture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindSemantics for FilterPass {
|
impl BindSemantics<NoUniformBinder, Option<()>, RawD3D12Buffer, RawD3D12Buffer> for FilterPass {
|
||||||
type InputTexture = InputTexture;
|
type InputTexture = InputTexture;
|
||||||
type SamplerSet = SamplerSet;
|
type SamplerSet = SamplerSet;
|
||||||
type DescriptorSet<'a> = (
|
type DescriptorSet<'a> = (
|
||||||
|
@ -160,33 +159,16 @@ impl FilterPass {
|
||||||
source,
|
source,
|
||||||
);
|
);
|
||||||
|
|
||||||
// todo: write directly to persistently bound cbuffer.
|
|
||||||
if let Some(ubo) = &self.reflection.ubo
|
if let Some(ubo) = &self.reflection.ubo
|
||||||
&& let Some(cbuffer) = &mut self.ubo_cbuffer
|
|
||||||
&& ubo.size != 0
|
&& ubo.size != 0
|
||||||
{
|
{
|
||||||
{
|
self.uniform_storage.inner_ubo().bind_cbv(2, cmd);
|
||||||
let guard = cbuffer.buffer.map(None)?;
|
|
||||||
guard.slice.copy_from_slice(self.uniform_storage.ubo_slice());
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
cmd.SetGraphicsRootConstantBufferView(2, cbuffer.desc.BufferLocation)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(push) = &self.reflection.push_constant
|
if let Some(push) = &self.reflection.push_constant
|
||||||
&& let Some(cbuffer) = &mut self.push_cbuffer
|
|
||||||
&& push.size != 0
|
&& push.size != 0
|
||||||
{
|
{
|
||||||
{
|
self.uniform_storage.inner_push().bind_cbv(3, cmd);
|
||||||
let guard = cbuffer.buffer.map(None)?;
|
|
||||||
guard.slice.copy_from_slice(self.uniform_storage.push_slice());
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
cmd.SetGraphicsRootConstantBufferView(3, cbuffer.desc.BufferLocation)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -7,10 +7,12 @@ use std::u64;
|
||||||
use widestring::u16cstr;
|
use widestring::u16cstr;
|
||||||
use windows::core::{Interface, PCSTR, PCWSTR};
|
use windows::core::{Interface, PCSTR, PCWSTR};
|
||||||
use windows::Win32::Graphics::Direct3D::Dxc::{
|
use windows::Win32::Graphics::Direct3D::Dxc::{
|
||||||
DxcValidatorFlags_InPlaceEdit, IDxcBlob, IDxcBlobUtf8, IDxcCompiler, IDxcUtils, IDxcValidator,
|
DxcValidatorFlags_InPlaceEdit, IDxcBlob, IDxcCompiler, IDxcUtils, IDxcValidator, DXC_CP,
|
||||||
DXC_CP, DXC_CP_UTF8,
|
DXC_CP_UTF8,
|
||||||
|
};
|
||||||
|
use windows::Win32::Graphics::Direct3D::Fxc::{
|
||||||
|
D3DCompile, D3DCOMPILE_DEBUG, D3DCOMPILE_OPTIMIZATION_LEVEL3, D3DCOMPILE_SKIP_OPTIMIZATION,
|
||||||
};
|
};
|
||||||
use windows::Win32::Graphics::Direct3D::Fxc::{D3DCompile, D3DCOMPILE_DEBUG, D3DCOMPILE_OPTIMIZATION_LEVEL3, D3DCOMPILE_SKIP_OPTIMIZATION};
|
|
||||||
use windows::Win32::Graphics::Direct3D::ID3DBlob;
|
use windows::Win32::Graphics::Direct3D::ID3DBlob;
|
||||||
use windows::Win32::Graphics::Direct3D12::{
|
use windows::Win32::Graphics::Direct3D12::{
|
||||||
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_FEATURE_DATA_FORMAT_SUPPORT,
|
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_FEATURE_DATA_FORMAT_SUPPORT,
|
||||||
|
|
|
@ -318,7 +318,7 @@ impl FilterChainVulkan {
|
||||||
let spirv_words = reflect.compile(None)?;
|
let spirv_words = reflect.compile(None)?;
|
||||||
|
|
||||||
let ubo_size = reflection.ubo.as_ref().map_or(0, |ubo| ubo.size as usize);
|
let ubo_size = reflection.ubo.as_ref().map_or(0, |ubo| ubo.size as usize);
|
||||||
let uniform_storage = UniformStorage::new_with_storage(
|
let uniform_storage = UniformStorage::new_with_ubo_storage(
|
||||||
RawVulkanBuffer::new(
|
RawVulkanBuffer::new(
|
||||||
&vulkan.device,
|
&vulkan.device,
|
||||||
&vulkan.memory_properties,
|
&vulkan.memory_properties,
|
||||||
|
|
|
@ -50,10 +50,11 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait that abstracts binding of semantics to shader uniforms.
|
/// Trait that abstracts binding of semantics to shader uniforms.
|
||||||
pub trait BindSemantics<H = NoUniformBinder, C = Option<()>, S = Box<[u8]>>
|
pub trait BindSemantics<H = NoUniformBinder, C = Option<()>, U = Box<[u8]>, P = Box<[u8]>>
|
||||||
where
|
where
|
||||||
C: Copy,
|
C: Copy,
|
||||||
S: Deref<Target = [u8]> + DerefMut,
|
U: Deref<Target = [u8]> + DerefMut,
|
||||||
|
P: Deref<Target = [u8]> + DerefMut,
|
||||||
H: BindUniform<C, f32>,
|
H: BindUniform<C, f32>,
|
||||||
H: BindUniform<C, u32>,
|
H: BindUniform<C, u32>,
|
||||||
H: BindUniform<C, i32>,
|
H: BindUniform<C, i32>,
|
||||||
|
@ -89,7 +90,7 @@ where
|
||||||
fn bind_semantics<'a>(
|
fn bind_semantics<'a>(
|
||||||
device: &Self::DeviceContext,
|
device: &Self::DeviceContext,
|
||||||
sampler_set: &Self::SamplerSet,
|
sampler_set: &Self::SamplerSet,
|
||||||
uniform_storage: &mut UniformStorage<H, C, S>,
|
uniform_storage: &mut UniformStorage<H, C, U, P>,
|
||||||
descriptor_set: &mut Self::DescriptorSet<'a>,
|
descriptor_set: &mut Self::DescriptorSet<'a>,
|
||||||
mvp: &[f32; 16],
|
mvp: &[f32; 16],
|
||||||
frame_count: u32,
|
frame_count: u32,
|
||||||
|
|
|
@ -37,9 +37,10 @@ pub trait UniformStorageAccess {
|
||||||
fn push_slice(&self) -> &[u8];
|
fn push_slice(&self) -> &[u8];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, H, S> UniformStorageAccess for UniformStorage<T, H, S>
|
impl<T, H, U, P> UniformStorageAccess for UniformStorage<T, H, U, P>
|
||||||
where
|
where
|
||||||
S: Deref<Target = [u8]> + DerefMut,
|
U: Deref<Target = [u8]> + DerefMut,
|
||||||
|
P: Deref<Target = [u8]> + DerefMut,
|
||||||
{
|
{
|
||||||
fn ubo_pointer(&self) -> *const u8 {
|
fn ubo_pointer(&self) -> *const u8 {
|
||||||
self.ubo.as_ptr()
|
self.ubo.as_ptr()
|
||||||
|
@ -68,25 +69,32 @@ impl<T> BindUniform<Option<()>, T> for NoUniformBinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A helper to bind uniform variables to UBO or Push Constant Buffers.
|
/// A helper to bind uniform variables to UBO or Push Constant Buffers.
|
||||||
pub struct UniformStorage<H = NoUniformBinder, C = Option<()>, S = Box<[u8]>>
|
pub struct UniformStorage<H = NoUniformBinder, C = Option<()>, U = Box<[u8]>, P = Box<[u8]>>
|
||||||
where
|
where
|
||||||
S: Deref<Target = [u8]> + DerefMut,
|
U: Deref<Target = [u8]> + DerefMut,
|
||||||
|
P: Deref<Target = [u8]> + DerefMut,
|
||||||
{
|
{
|
||||||
ubo: S,
|
ubo: U,
|
||||||
push: Box<[u8]>,
|
push: P,
|
||||||
_h: PhantomData<H>,
|
_h: PhantomData<H>,
|
||||||
_c: PhantomData<C>,
|
_c: PhantomData<C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H, C, S> UniformStorage<H, C, S>
|
impl<H, C, U, P> UniformStorage<H, C, U, P>
|
||||||
where
|
where
|
||||||
S: Deref<Target = [u8]> + DerefMut,
|
U: Deref<Target = [u8]> + DerefMut,
|
||||||
|
P: Deref<Target = [u8]> + DerefMut,
|
||||||
{
|
{
|
||||||
/// Access the backing storage for the UBO.
|
/// Access the backing storage for the UBO.
|
||||||
pub fn inner_ubo(&self) -> &S {
|
pub fn inner_ubo(&self) -> &U {
|
||||||
&self.ubo
|
&self.ubo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Access the backing storage for the Push storage.
|
||||||
|
pub fn inner_push(&self) -> &P {
|
||||||
|
&self.push
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn buffer(&mut self, ty: UniformMemberBlock) -> &mut [u8] {
|
pub(crate) fn buffer(&mut self, ty: UniformMemberBlock) -> &mut [u8] {
|
||||||
match ty {
|
match ty {
|
||||||
UniformMemberBlock::Ubo => self.ubo.deref_mut(),
|
UniformMemberBlock::Ubo => self.ubo.deref_mut(),
|
||||||
|
@ -95,10 +103,11 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H, C, S> UniformStorage<H, C, S>
|
impl<H, C, U, P> UniformStorage<H, C, U, P>
|
||||||
where
|
where
|
||||||
C: Copy,
|
C: Copy,
|
||||||
S: Deref<Target = [u8]> + DerefMut,
|
U: Deref<Target = [u8]> + DerefMut,
|
||||||
|
P: Deref<Target = [u8]> + DerefMut,
|
||||||
{
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn write_scalar_inner<T: UniformScalar>(buffer: &mut [u8], value: T) {
|
fn write_scalar_inner<T: UniformScalar>(buffer: &mut [u8], value: T) {
|
||||||
|
@ -125,7 +134,23 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new `UniformStorage` with the given backing storage
|
/// Create a new `UniformStorage` with the given backing storage
|
||||||
pub fn new_with_storage(storage: S, push_size: usize) -> UniformStorage<H, C, S> {
|
pub fn new_with_storage(ubo: U, push: P) -> UniformStorage<H, C, U, P> {
|
||||||
|
UniformStorage {
|
||||||
|
ubo,
|
||||||
|
push,
|
||||||
|
_h: Default::default(),
|
||||||
|
_c: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<H, C, U> UniformStorage<H, C, U, Box<[u8]>>
|
||||||
|
where
|
||||||
|
C: Copy,
|
||||||
|
U: Deref<Target = [u8]> + DerefMut,
|
||||||
|
{
|
||||||
|
/// Create a new `UniformStorage` with the given backing storage
|
||||||
|
pub fn new_with_ubo_storage(storage: U, push_size: usize) -> UniformStorage<H, C, U, Box<[u8]>> {
|
||||||
UniformStorage {
|
UniformStorage {
|
||||||
ubo: storage,
|
ubo: storage,
|
||||||
push: vec![0u8; push_size].into_boxed_slice(),
|
push: vec![0u8; push_size].into_boxed_slice(),
|
||||||
|
@ -135,7 +160,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H, C> UniformStorage<H, C, Box<[u8]>> {
|
impl<H, C> UniformStorage<H, C, Box<[u8]>, Box<[u8]>> {
|
||||||
/// Create a new `UniformStorage` with the given size for UBO and Push Constant Buffer sizes.
|
/// Create a new `UniformStorage` with the given size for UBO and Push Constant Buffer sizes.
|
||||||
pub fn new(ubo_size: usize, push_size: usize) -> UniformStorage<H, C, Box<[u8]>> {
|
pub fn new(ubo_size: usize, push_size: usize) -> UniformStorage<H, C, Box<[u8]>> {
|
||||||
UniformStorage {
|
UniformStorage {
|
||||||
|
@ -147,10 +172,11 @@ impl<H, C> UniformStorage<H, C, Box<[u8]>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H, C, S> UniformStorage<H, C, S>
|
impl<H, C, U, P> UniformStorage<H, C, U, P>
|
||||||
where
|
where
|
||||||
C: Copy,
|
C: Copy,
|
||||||
S: Deref<Target = [u8]> + DerefMut,
|
U: Deref<Target = [u8]> + DerefMut,
|
||||||
|
P: Deref<Target = [u8]> + DerefMut,
|
||||||
H: for<'a> BindUniform<C, &'a [f32; 4]>,
|
H: for<'a> BindUniform<C, &'a [f32; 4]>,
|
||||||
{
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -178,10 +204,11 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H, C, S> UniformStorage<H, C, S>
|
impl<H, C, U, P> UniformStorage<H, C, U, P>
|
||||||
where
|
where
|
||||||
C: Copy,
|
C: Copy,
|
||||||
S: Deref<Target = [u8]> + DerefMut,
|
U: Deref<Target = [u8]> + DerefMut,
|
||||||
|
P: Deref<Target = [u8]> + DerefMut,
|
||||||
H: for<'a> BindUniform<C, &'a [f32; 16]>,
|
H: for<'a> BindUniform<C, &'a [f32; 16]>,
|
||||||
{
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
Loading…
Reference in a new issue