d3d12: filter chain pass
This commit is contained in:
parent
e1154ac52a
commit
03b4a7574e
|
@ -5,8 +5,8 @@ use crate::error;
|
|||
use crate::error::assume_d3d12_init;
|
||||
|
||||
pub struct D3D12ConstantBuffer {
|
||||
buffer: D3D12Buffer,
|
||||
desc: D3D12_CONSTANT_BUFFER_VIEW_DESC,
|
||||
pub buffer: D3D12Buffer,
|
||||
pub desc: D3D12_CONSTANT_BUFFER_VIEW_DESC,
|
||||
}
|
||||
|
||||
pub struct D3D12Buffer {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::VecDeque;
|
||||
use crate::{error};
|
||||
use crate::heap::{D3D12DescriptorHeap, CpuStagingHeap, ResourceWorkHeap, SamplerWorkHeap};
|
||||
use crate::heap::{D3D12DescriptorHeap, CpuStagingHeap, ResourceWorkHeap, SamplerWorkHeap, RenderTargetHeap};
|
||||
use crate::samplers::SamplerSet;
|
||||
use crate::luts::LutTexture;
|
||||
use librashader_presets::{ShaderPreset, TextureConfig};
|
||||
|
@ -14,17 +14,14 @@ use std::path::Path;
|
|||
use windows::core::Interface;
|
||||
use windows::w;
|
||||
use windows::Win32::Foundation::CloseHandle;
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
ID3D12CommandAllocator, ID3D12CommandQueue, ID3D12Device, ID3D12Fence,
|
||||
ID3D12GraphicsCommandList, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_DESC,
|
||||
D3D12_COMMAND_QUEUE_FLAG_NONE, D3D12_FENCE_FLAG_NONE,
|
||||
};
|
||||
use windows::Win32::Graphics::Direct3D12::{ID3D12CommandAllocator, ID3D12CommandQueue, ID3D12Device, ID3D12Fence, ID3D12GraphicsCommandList, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_DESC, D3D12_COMMAND_QUEUE_FLAG_NONE, D3D12_FENCE_FLAG_NONE, ID3D12DescriptorHeap};
|
||||
use windows::Win32::System::Threading::{CreateEventA, ResetEvent, WaitForSingleObject};
|
||||
use windows::Win32::System::WindowsProgramming::INFINITE;
|
||||
use librashader_common::{ImageFormat, Size};
|
||||
use librashader_common::{ImageFormat, Size, Viewport};
|
||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||
use librashader_reflect::reflect::ReflectShader;
|
||||
use librashader_reflect::reflect::semantics::{MAX_BINDINGS_COUNT, ShaderSemantics, TextureSemantics, UniformBinding};
|
||||
use librashader_runtime::binding::TextureInput;
|
||||
use librashader_runtime::uniforms::UniformStorage;
|
||||
use crate::buffer::{D3D12Buffer, D3D12ConstantBuffer};
|
||||
use crate::filter_pass::FilterPass;
|
||||
|
@ -32,7 +29,7 @@ use crate::framebuffer::OwnedImage;
|
|||
use crate::graphics_pipeline::{D3D12GraphicsPipeline, D3D12RootSignature};
|
||||
use crate::mipmap::D3D12MipmapGen;
|
||||
use crate::quad_render::DrawQuad;
|
||||
use crate::texture::InputTexture;
|
||||
use crate::texture::{InputTexture, OutputTexture};
|
||||
|
||||
type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<HLSL, GlslangCompilation>>;
|
||||
|
||||
|
@ -48,6 +45,10 @@ pub struct FilterChainD3D12 {
|
|||
pub(crate) feedback_framebuffers: Box<[OwnedImage]>,
|
||||
pub(crate) history_framebuffers: VecDeque<OwnedImage>,
|
||||
staging_heap: D3D12DescriptorHeap<CpuStagingHeap>,
|
||||
rtv_heap: D3D12DescriptorHeap<RenderTargetHeap>,
|
||||
|
||||
pub texture_heap: ID3D12DescriptorHeap,
|
||||
pub sampler_heap: ID3D12DescriptorHeap,
|
||||
}
|
||||
|
||||
pub(crate) struct FilterCommon {
|
||||
|
@ -97,6 +98,10 @@ impl FilterChainD3D12 {
|
|||
D3D12DescriptorHeap::new(device,
|
||||
(MAX_BINDINGS_COUNT as usize) *
|
||||
shader_count + 2048 + lut_count)?;
|
||||
let mut rtv_heap =
|
||||
D3D12DescriptorHeap::new(device,
|
||||
(MAX_BINDINGS_COUNT as usize) *
|
||||
shader_count + 2048 + lut_count)?;
|
||||
|
||||
|
||||
|
||||
|
@ -104,7 +109,8 @@ impl FilterChainD3D12 {
|
|||
|
||||
let root_signature = D3D12RootSignature::new(device)?;
|
||||
|
||||
let filters = FilterChainD3D12::init_passes(device, &root_signature, passes, &semantics)?;
|
||||
let (texture_heap, sampler_heap, filters)
|
||||
= FilterChainD3D12::init_passes(device, &root_signature, passes, &semantics)?;
|
||||
|
||||
|
||||
|
||||
|
@ -172,10 +178,13 @@ impl FilterChainD3D12 {
|
|||
history_textures,
|
||||
},
|
||||
staging_heap,
|
||||
rtv_heap,
|
||||
passes: filters,
|
||||
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
||||
history_framebuffers,
|
||||
texture_heap,
|
||||
sampler_heap
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -329,7 +338,7 @@ impl FilterChainD3D12 {
|
|||
root_signature: &D3D12RootSignature,
|
||||
passes: Vec<ShaderPassMeta>,
|
||||
semantics: &ShaderSemantics,)
|
||||
-> error::Result<Vec<FilterPass>> {
|
||||
-> error::Result<(ID3D12DescriptorHeap, ID3D12DescriptorHeap, Vec<FilterPass>)> {
|
||||
|
||||
let mut filters = Vec::new();
|
||||
let shader_count = passes.len();
|
||||
|
@ -337,8 +346,8 @@ impl FilterChainD3D12 {
|
|||
D3D12DescriptorHeap::<ResourceWorkHeap>::new(device,
|
||||
(MAX_BINDINGS_COUNT as usize) *
|
||||
shader_count)?;
|
||||
let work_heaps = unsafe {
|
||||
work_heap.suballocate(shader_count)
|
||||
let (work_heaps, texture_heap_handle) = unsafe {
|
||||
work_heap.suballocate(MAX_BINDINGS_COUNT as usize)
|
||||
};
|
||||
|
||||
|
||||
|
@ -346,12 +355,12 @@ impl FilterChainD3D12 {
|
|||
D3D12DescriptorHeap::new(device,
|
||||
(MAX_BINDINGS_COUNT as usize) * shader_count)?;
|
||||
|
||||
let sampler_work_heaps = unsafe {
|
||||
sampler_work_heap.suballocate(shader_count)
|
||||
let (sampler_work_heaps, sampler_heap_handle) = unsafe {
|
||||
sampler_work_heap.suballocate(MAX_BINDINGS_COUNT as usize)
|
||||
};
|
||||
|
||||
for (index, (((config, source, mut reflect),
|
||||
texture_heap), sampler_heap))
|
||||
mut texture_heap), mut sampler_heap))
|
||||
in passes.into_iter()
|
||||
.zip(work_heaps)
|
||||
.zip(sampler_work_heaps)
|
||||
|
@ -411,6 +420,8 @@ impl FilterChainD3D12 {
|
|||
uniform_bindings.insert(UniformBinding::TextureSize(*semantics), param.offset);
|
||||
}
|
||||
|
||||
let texture_heap = texture_heap.alloc_range()?;
|
||||
let sampler_heap = sampler_heap.alloc_range()?;
|
||||
filters.push(FilterPass {
|
||||
reflection,
|
||||
uniform_bindings,
|
||||
|
@ -426,7 +437,84 @@ impl FilterChainD3D12 {
|
|||
|
||||
}
|
||||
|
||||
Ok(filters)
|
||||
Ok((texture_heap_handle, sampler_heap_handle, filters))
|
||||
}
|
||||
|
||||
/// Process a frame with the input image.
|
||||
pub fn frame(
|
||||
&mut self,
|
||||
input: InputTexture,
|
||||
viewport: &Viewport<OutputTexture>,
|
||||
frame_count: usize,
|
||||
options: Option<&()>,
|
||||
) -> error::Result<()>
|
||||
{
|
||||
let max = std::cmp::min(self.passes.len(), self.common.config.passes_enabled);
|
||||
let passes = &mut self.passes[0..max];
|
||||
if passes.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let filter = passes[0].config.filter;
|
||||
let wrap_mode = passes[0].config.wrap_mode;
|
||||
|
||||
for ((texture, fbo), pass) in self
|
||||
.common
|
||||
.feedback_textures
|
||||
.iter_mut()
|
||||
.zip(self.feedback_framebuffers.iter())
|
||||
.zip(passes.iter())
|
||||
{
|
||||
*texture = Some(fbo.create_shader_resource_view(&mut self.staging_heap,
|
||||
pass.config.filter,
|
||||
pass.config.wrap_mode)?);
|
||||
}
|
||||
|
||||
for (texture, fbo) in self
|
||||
.common
|
||||
.history_textures
|
||||
.iter_mut()
|
||||
.zip(self.history_framebuffers.iter())
|
||||
{
|
||||
*texture = Some(fbo.create_shader_resource_view(&mut self.staging_heap,
|
||||
filter,
|
||||
wrap_mode)?);
|
||||
}
|
||||
|
||||
|
||||
let original = &input;
|
||||
let mut source = &input;
|
||||
|
||||
|
||||
// rescale render buffers to ensure all bindings are valid.
|
||||
let mut source_size = source.size();
|
||||
let mut iterator = passes.iter_mut().enumerate().peekable();
|
||||
while let Some((index, pass)) = iterator.next() {
|
||||
let should_mipmap = iterator
|
||||
.peek()
|
||||
.map(|(_, p)| p.config.mipmap_input)
|
||||
.unwrap_or(false);
|
||||
|
||||
// let next_size = self.output_framebuffers[index].scale(
|
||||
// pass.config.scaling.clone(),
|
||||
// pass.get_format(),
|
||||
// &viewport.output.size,
|
||||
// &source_size,
|
||||
// should_mipmap,
|
||||
// )?;
|
||||
//
|
||||
// self.feedback_framebuffers[index].scale(
|
||||
// pass.config.scaling.clone(),
|
||||
// pass.get_format(),
|
||||
// &viewport.output.size,
|
||||
// &source_size,
|
||||
// should_mipmap,
|
||||
// )?;
|
||||
|
||||
// source_size = next_size;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
use rustc_hash::FxHashMap;
|
||||
use windows::core::Interface;
|
||||
use windows::Win32::Foundation::RECT;
|
||||
use windows::Win32::Graphics::Direct3D11::ID3D11Device;
|
||||
use windows::Win32::Graphics::Direct3D12::ID3D12Device;
|
||||
use librashader_common::{ImageFormat, Size};
|
||||
use windows::Win32::Graphics::Direct3D12::{D3D12_RENDER_PASS_BEGINNING_ACCESS, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD, D3D12_RENDER_PASS_ENDING_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_FLAG_NONE, D3D12_RENDER_PASS_RENDER_TARGET_DESC, D3D12_VIEWPORT, ID3D12CommandList, ID3D12Device, ID3D12GraphicsCommandList, ID3D12GraphicsCommandList4};
|
||||
use librashader_common::{ImageFormat, Size, Viewport};
|
||||
use librashader_preprocess::ShaderSource;
|
||||
use librashader_presets::ShaderPassConfig;
|
||||
use librashader_reflect::reflect::semantics::{MemberOffset, TextureBinding, UniformBinding};
|
||||
use librashader_reflect::reflect::ShaderReflection;
|
||||
use librashader_runtime::binding::{BindSemantics, TextureInput};
|
||||
use librashader_runtime::uniforms::UniformStorage;
|
||||
use librashader_runtime::quad::QuadType;
|
||||
use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess};
|
||||
use crate::buffer::D3D12ConstantBuffer;
|
||||
use crate::{error, util};
|
||||
use crate::filter_chain::FilterCommon;
|
||||
use crate::graphics_pipeline::D3D12GraphicsPipeline;
|
||||
use crate::heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap, SamplerWorkHeap};
|
||||
use crate::render_target::RenderTarget;
|
||||
use crate::samplers::SamplerSet;
|
||||
use crate::texture::InputTexture;
|
||||
use crate::texture::{InputTexture, OutputTexture};
|
||||
|
||||
pub(crate) struct FilterPass {
|
||||
pub(crate) pipeline: D3D12GraphicsPipeline,
|
||||
|
@ -23,8 +28,8 @@ pub(crate) struct FilterPass {
|
|||
pub uniform_storage: UniformStorage,
|
||||
pub(crate) push_cbuffer: Option<D3D12ConstantBuffer>,
|
||||
pub(crate) ubo_cbuffer: Option<D3D12ConstantBuffer>,
|
||||
pub(crate) texture_heap: D3D12DescriptorHeap<ResourceWorkHeap>,
|
||||
pub(crate) sampler_heap: D3D12DescriptorHeap<SamplerWorkHeap>,
|
||||
pub(crate) texture_heap: [D3D12DescriptorHeapSlot<ResourceWorkHeap>; 16],
|
||||
pub(crate) sampler_heap: [D3D12DescriptorHeapSlot<SamplerWorkHeap>; 16],
|
||||
pub source: ShaderSource,
|
||||
|
||||
}
|
||||
|
@ -34,7 +39,7 @@ impl TextureInput for InputTexture {
|
|||
self.size
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
impl BindSemantics for FilterPass {
|
||||
type InputTexture = InputTexture;
|
||||
type SamplerSet = SamplerSet;
|
||||
|
@ -87,18 +92,15 @@ impl FilterPass {
|
|||
frame_direction: i32,
|
||||
fb_size: Size<u32>,
|
||||
viewport_size: Size<u32>,
|
||||
mut descriptors: (
|
||||
&'a mut [D3D12DescriptorHeapSlot<ResourceWorkHeap>; 16],
|
||||
&'a mut [D3D12DescriptorHeapSlot<SamplerWorkHeap>; 16],
|
||||
),
|
||||
original: &InputTexture,
|
||||
source: &InputTexture,
|
||||
) {
|
||||
|
||||
Self::bind_semantics(
|
||||
&(),
|
||||
&parent.samplers,
|
||||
&mut self.uniform_storage,
|
||||
&mut descriptors,
|
||||
&mut (&mut self.texture_heap, &mut self.sampler_heap),
|
||||
mvp,
|
||||
frame_count,
|
||||
frame_direction,
|
||||
|
@ -118,4 +120,121 @@ impl FilterPass {
|
|||
&parent.config.parameters,
|
||||
);
|
||||
}
|
||||
|
||||
/// preconditions
|
||||
/// rootsig is bound
|
||||
/// descriptor heaps are bound
|
||||
/// input must be ready to read from
|
||||
/// output must be ready to write to
|
||||
pub(crate) fn draw(
|
||||
&mut self,
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
pass_index: usize,
|
||||
parent: &FilterCommon,
|
||||
frame_count: u32,
|
||||
frame_direction: i32,
|
||||
viewport: &Viewport<OutputTexture>,
|
||||
original: &InputTexture,
|
||||
source: &InputTexture,
|
||||
output: RenderTarget,
|
||||
vbo_type: QuadType,
|
||||
) -> error::Result<()> {
|
||||
|
||||
parent.draw_quad.bind_vertices(cmd, vbo_type);
|
||||
unsafe {
|
||||
cmd.SetPipelineState(&self.pipeline.handle);
|
||||
}
|
||||
|
||||
self.build_semantics(
|
||||
pass_index,
|
||||
parent,
|
||||
output.mvp,
|
||||
frame_count,
|
||||
frame_direction,
|
||||
output.output.size,
|
||||
viewport.output.size,
|
||||
original,
|
||||
source,
|
||||
);
|
||||
|
||||
// todo: write directly to persistently bound cbuffer.
|
||||
if let Some(ubo) = &self.reflection.ubo
|
||||
&& let Some(cbuffer) = &mut self.ubo_cbuffer
|
||||
&& ubo.size != 0
|
||||
{
|
||||
{
|
||||
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
|
||||
&& let Some(cbuffer) = &mut self.push_cbuffer
|
||||
&& push.size != 0
|
||||
{
|
||||
{
|
||||
let guard = cbuffer.buffer.map(None)?;
|
||||
guard.slice.copy_from_slice(self.uniform_storage.push_slice());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
cmd.SetGraphicsRootConstantBufferView(3, cbuffer.desc.BufferLocation)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
cmd.SetGraphicsRootDescriptorTable(0, *self.texture_heap[0].as_ref());
|
||||
cmd.SetGraphicsRootDescriptorTable(0, *self.sampler_heap[0].as_ref());
|
||||
}
|
||||
|
||||
// todo: check for non-renderpass.
|
||||
|
||||
let cmd = cmd.cast::<ID3D12GraphicsCommandList4>()?;
|
||||
unsafe {
|
||||
let pass = [D3D12_RENDER_PASS_RENDER_TARGET_DESC {
|
||||
cpuDescriptor: *output.output.descriptor.as_ref(),
|
||||
BeginningAccess: D3D12_RENDER_PASS_BEGINNING_ACCESS {
|
||||
Type: D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD,
|
||||
..Default::default()
|
||||
},
|
||||
EndingAccess: D3D12_RENDER_PASS_ENDING_ACCESS {
|
||||
Type: D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
|
||||
Anonymous: Default::default(),
|
||||
},
|
||||
}];
|
||||
|
||||
cmd.BeginRenderPass(Some(&pass), None, D3D12_RENDER_PASS_FLAG_NONE)
|
||||
}
|
||||
|
||||
unsafe {
|
||||
cmd.RSSetViewports(&[D3D12_VIEWPORT {
|
||||
TopLeftX: output.x,
|
||||
TopLeftY: output.y,
|
||||
Width: output.output.size.width as f32,
|
||||
Height: output.output.size.height as f32,
|
||||
MinDepth: 0.0,
|
||||
MaxDepth: 1.0,
|
||||
}]);
|
||||
|
||||
cmd.RSSetScissorRects(&[RECT {
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: output.output.size.width as i32,
|
||||
bottom: output.output.size.height as i32,
|
||||
}]);
|
||||
|
||||
// todo put this in drawquad
|
||||
cmd.DrawInstanced(4, 1, 0, 0)
|
||||
}
|
||||
|
||||
unsafe {
|
||||
cmd.EndRenderPass()
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -4,8 +4,8 @@ use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
|||
use librashader_runtime::scaling::MipmapSize;
|
||||
use crate::error;
|
||||
use crate::error::assume_d3d12_init;
|
||||
use crate::heap::{CpuStagingHeap, D3D12DescriptorHeap};
|
||||
use crate::texture::InputTexture;
|
||||
use crate::heap::{CpuStagingHeap, D3D12DescriptorHeap, RenderTargetHeap};
|
||||
use crate::texture::{InputTexture, OutputTexture};
|
||||
use crate::util::d3d12_get_closest_format;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -113,8 +113,8 @@ impl OwnedImage {
|
|||
Ok(InputTexture::new(descriptor, self.size, self.format, wrap_mode, filter))
|
||||
}
|
||||
|
||||
pub(crate) fn create_render_target_view(&self, heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
|
||||
filter: FilterMode, wrap_mode: WrapMode) -> error::Result<InputTexture> {
|
||||
pub(crate) fn create_render_target_view(&self, heap: &mut D3D12DescriptorHeap<RenderTargetHeap>
|
||||
) -> error::Result<OutputTexture> {
|
||||
|
||||
let descriptor = heap.alloc_slot()?;
|
||||
|
||||
|
@ -133,6 +133,6 @@ impl OwnedImage {
|
|||
self.device.CreateRenderTargetView(&self.handle, Some(&rtv_desc), *descriptor.as_ref());
|
||||
}
|
||||
|
||||
Ok(InputTexture::new(descriptor, self.size, self.format, wrap_mode, filter))
|
||||
Ok(OutputTexture::new(descriptor, self.size))
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ use crate::{error, util};
|
|||
use crate::quad_render::DrawQuad;
|
||||
|
||||
pub struct D3D12GraphicsPipeline {
|
||||
pipeline_state: ID3D12PipelineState,
|
||||
pub(crate) handle: ID3D12PipelineState,
|
||||
}
|
||||
|
||||
const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER; 4] = &[
|
||||
|
@ -198,7 +198,7 @@ impl D3D12GraphicsPipeline {
|
|||
};
|
||||
|
||||
Ok(D3D12GraphicsPipeline {
|
||||
pipeline_state,
|
||||
handle: pipeline_state,
|
||||
})
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ use std::cell::RefCell;
|
|||
use std::marker::PhantomData;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
use windows::Win32::Graphics::Direct3D12::{ID3D12DescriptorHeap, ID3D12Device, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_DESC, D3D12_DESCRIPTOR_HEAP_FLAG_NONE, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, D3D12_GPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_TYPE};
|
||||
use windows::Win32::Graphics::Direct3D12::{ID3D12DescriptorHeap, ID3D12Device, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_DESC, D3D12_DESCRIPTOR_HEAP_FLAG_NONE, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, D3D12_GPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_TYPE, D3D12_DESCRIPTOR_HEAP_TYPE_RTV};
|
||||
|
||||
#[const_trait]
|
||||
pub trait D3D12HeapType {
|
||||
|
@ -17,6 +17,9 @@ pub struct SamplerPaletteHeap;
|
|||
#[derive(Clone)]
|
||||
pub struct CpuStagingHeap;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RenderTargetHeap;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ResourceWorkHeap;
|
||||
|
||||
|
@ -47,6 +50,18 @@ impl const D3D12HeapType for CpuStagingHeap {
|
|||
}
|
||||
}
|
||||
|
||||
impl const D3D12HeapType for RenderTargetHeap {
|
||||
// Lut texture heaps are CPU only and get bound to the descriptor heap of the shader.
|
||||
fn get_desc(size: usize) -> D3D12_DESCRIPTOR_HEAP_DESC {
|
||||
D3D12_DESCRIPTOR_HEAP_DESC {
|
||||
Type: D3D12_DESCRIPTOR_HEAP_TYPE_RTV,
|
||||
NumDescriptors: size as u32,
|
||||
Flags: D3D12_DESCRIPTOR_HEAP_FLAG_NONE,
|
||||
NodeMask: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl D3D12ShaderVisibleHeapType for ResourceWorkHeap {}
|
||||
impl const D3D12HeapType for ResourceWorkHeap {
|
||||
// Lut texture heaps are CPU only and get bound to the descriptor heap of the shader.
|
||||
|
@ -73,7 +88,6 @@ impl const D3D12HeapType for SamplerWorkHeap {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct D3D12DescriptorHeapSlot<T> {
|
||||
cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||
gpu_handle: Option<D3D12_GPU_DESCRIPTOR_HANDLE>,
|
||||
|
@ -191,7 +205,7 @@ impl<T> D3D12DescriptorHeap<T> {
|
|||
/// descriptors allocated for it.
|
||||
///
|
||||
/// size must also divide equally into the size of the heap.
|
||||
pub unsafe fn suballocate(self, size: usize) -> Vec<D3D12DescriptorHeap<T>> {
|
||||
pub unsafe fn suballocate(self, size: usize) -> (Vec<D3D12DescriptorHeap<T>>, ID3D12DescriptorHeap) {
|
||||
// has to be called right after creation.
|
||||
assert_eq!(Arc::strong_count(&self.0), 1,
|
||||
"D3D12DescriptorHeap::suballocate can only be callled immediately after creation.");
|
||||
|
@ -237,11 +251,11 @@ impl<T> D3D12DescriptorHeap<T> {
|
|||
start += size;
|
||||
}
|
||||
|
||||
heaps.into_iter()
|
||||
(heaps.into_iter()
|
||||
.map(|inner| D3D12DescriptorHeap(
|
||||
Arc::new(RefCell::new(inner)),
|
||||
PhantomData::default()))
|
||||
.collect()
|
||||
.collect(), inner.heap)
|
||||
}
|
||||
|
||||
pub fn alloc_slot(&mut self) -> error::Result<D3D12DescriptorHeapSlot<T>> {
|
||||
|
|
|
@ -15,6 +15,7 @@ mod graphics_pipeline;
|
|||
mod buffer;
|
||||
mod framebuffer;
|
||||
mod texture;
|
||||
mod render_target;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
|
|
@ -5,6 +5,7 @@ use windows::w;
|
|||
use windows::Win32::Graphics::Direct3D::{D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP};
|
||||
use windows::Win32::Graphics::Direct3D12::{D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, D3D12_INPUT_ELEMENT_DESC, D3D12_VERTEX_BUFFER_VIEW, ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource};
|
||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT;
|
||||
use librashader_runtime::quad::QuadType;
|
||||
use crate::buffer::{D3D12Buffer};
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -70,7 +71,7 @@ impl DrawQuad {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn bind_vertices(&self, cmd: &ID3D12GraphicsCommandList) {
|
||||
pub fn bind_vertices(&self, cmd: &ID3D12GraphicsCommandList, _vbo_type: QuadType) {
|
||||
unsafe {
|
||||
cmd.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
cmd.IASetVertexBuffers(0, Some(&[self.view]));
|
||||
|
|
9
librashader-runtime-d3d12/src/render_target.rs
Normal file
9
librashader-runtime-d3d12/src/render_target.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
use crate::texture::OutputTexture;
|
||||
|
||||
pub(crate) struct RenderTarget<'a> {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
pub mvp: &'a [f32; 16],
|
||||
pub output: OutputTexture,
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_DESCRIPTOR_HANDLE};
|
||||
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
||||
use crate::heap::{CpuStagingHeap, D3D12DescriptorHeapSlot};
|
||||
use crate::heap::{CpuStagingHeap, D3D12DescriptorHeapSlot, RenderTargetHeap};
|
||||
|
||||
pub(crate) enum InputDescriptor {
|
||||
Owned(D3D12DescriptorHeapSlot<CpuStagingHeap>),
|
||||
|
@ -8,7 +8,7 @@ pub(crate) enum InputDescriptor {
|
|||
}
|
||||
|
||||
pub(crate) enum OutputDescriptor {
|
||||
Owned(D3D12DescriptorHeapSlot<CpuStagingHeap>),
|
||||
Owned(D3D12DescriptorHeapSlot<RenderTargetHeap>),
|
||||
Raw(D3D12_CPU_DESCRIPTOR_HANDLE)
|
||||
}
|
||||
|
||||
|
@ -31,12 +31,12 @@ impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for OutputDescriptor {
|
|||
}
|
||||
|
||||
pub struct OutputTexture {
|
||||
descriptor: OutputDescriptor,
|
||||
size: Size<u32>,
|
||||
pub(crate) descriptor: OutputDescriptor,
|
||||
pub(crate) size: Size<u32>,
|
||||
}
|
||||
|
||||
impl OutputTexture {
|
||||
pub fn new(handle: D3D12DescriptorHeapSlot<CpuStagingHeap>,
|
||||
pub fn new(handle: D3D12DescriptorHeapSlot<RenderTargetHeap>,
|
||||
size: Size<u32>,
|
||||
) -> OutputTexture {
|
||||
let descriptor = OutputDescriptor::Owned(handle);
|
||||
|
|
Loading…
Reference in a new issue