rt(d3d12): move update subresources to lut
This commit is contained in:
parent
7d483f2e08
commit
dedde05c83
|
@ -3,7 +3,7 @@ use crate::error;
|
|||
use crate::filter_chain::FrameResiduals;
|
||||
use crate::mipmap::MipmapGenContext;
|
||||
use crate::texture::InputTexture;
|
||||
use crate::util::{d3d12_get_closest_format, d3d12_resource_transition, d3d12_update_subresources};
|
||||
use crate::util::{d3d12_get_closest_format, d3d12_resource_transition};
|
||||
use d3d12_descriptor_heap::D3D12DescriptorHeap;
|
||||
use gpu_allocator::d3d12::{
|
||||
Allocator, Resource, ResourceCategory, ResourceCreateDesc, ResourceStateOrBarrierLayout,
|
||||
|
@ -16,18 +16,10 @@ use librashader_runtime::scaling::MipmapSize;
|
|||
use parking_lot::Mutex;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::sync::Arc;
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
ID3D12Device, ID3D12GraphicsCommandList, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
|
||||
D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FORMAT_SUPPORT1_MIP,
|
||||
D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE, D3D12_FORMAT_SUPPORT1_TEXTURE2D,
|
||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_BUFFER,
|
||||
D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_SHADER_RESOURCE_VIEW_DESC,
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_SUBRESOURCE_DATA,
|
||||
D3D12_TEX2D_SRV, D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
|
||||
};
|
||||
use windows::Win32::Graphics::Direct3D12::{ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FORMAT_SUPPORT1_MIP, D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE, D3D12_FORMAT_SUPPORT1_TEXTURE2D, D3D12_MEMCPY_DEST, D3D12_PLACED_SUBRESOURCE_FOOTPRINT, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_SUBRESOURCE_DATA, D3D12_TEX2D_SRV, D3D12_TEXTURE_COPY_LOCATION, D3D12_TEXTURE_COPY_LOCATION_0, D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, D3D12_TEXTURE_LAYOUT_ROW_MAJOR};
|
||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
|
||||
use std::u64;
|
||||
use crate::error::assume_d3d12_init;
|
||||
|
||||
pub struct LutTexture {
|
||||
resource: ManuallyDrop<Resource>,
|
||||
|
@ -238,3 +230,158 @@ impl Drop for LutTexture {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn d3d12_update_subresources(
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
destination_resource: &ID3D12Resource,
|
||||
intermediate_resource: &ID3D12Resource,
|
||||
intermediate_offset: u64,
|
||||
first_subresouce: u32,
|
||||
num_subresources: u32,
|
||||
source: &[D3D12_SUBRESOURCE_DATA],
|
||||
gc: &mut FrameResiduals,
|
||||
) -> error::Result<u64> {
|
||||
// let allocation_size = std::mem::size_of::<D3D12_PLACED_SUBRESOURCE_FOOTPRINT>()
|
||||
// + std::mem::size_of::<u32>()
|
||||
// + std::mem::size_of::<u64>() * num_subresources;
|
||||
|
||||
unsafe {
|
||||
let destination_desc = destination_resource.GetDesc();
|
||||
let mut device: Option<ID3D12Device> = None;
|
||||
destination_resource.GetDevice(&mut device)?;
|
||||
assume_d3d12_init!(device, "GetDevice");
|
||||
|
||||
let mut layouts =
|
||||
vec![D3D12_PLACED_SUBRESOURCE_FOOTPRINT::default(); num_subresources as usize];
|
||||
let mut num_rows = vec![0; num_subresources as usize];
|
||||
let mut row_sizes_in_bytes = vec![0; num_subresources as usize];
|
||||
let mut required_size = 0;
|
||||
|
||||
// texture upload
|
||||
device.GetCopyableFootprints(
|
||||
&destination_desc,
|
||||
first_subresouce,
|
||||
num_subresources,
|
||||
intermediate_offset,
|
||||
Some(layouts.as_mut_ptr()),
|
||||
Some(num_rows.as_mut_ptr()),
|
||||
Some(row_sizes_in_bytes.as_mut_ptr()),
|
||||
Some(&mut required_size),
|
||||
);
|
||||
|
||||
update_subresources(
|
||||
cmd,
|
||||
destination_resource,
|
||||
intermediate_resource,
|
||||
first_subresouce,
|
||||
num_subresources,
|
||||
required_size,
|
||||
&layouts,
|
||||
&num_rows,
|
||||
&row_sizes_in_bytes,
|
||||
source,
|
||||
gc,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn update_subresources(
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
destination_resource: &ID3D12Resource,
|
||||
intermediate_resource: &ID3D12Resource,
|
||||
first_subresouce: u32,
|
||||
num_subresources: u32,
|
||||
required_size: u64,
|
||||
layouts: &[D3D12_PLACED_SUBRESOURCE_FOOTPRINT],
|
||||
num_rows: &[u32],
|
||||
row_sizes_in_bytes: &[u64],
|
||||
source_data: &[D3D12_SUBRESOURCE_DATA],
|
||||
gc: &mut FrameResiduals,
|
||||
) -> error::Result<u64> {
|
||||
// ToDo: implement validation as in the original function
|
||||
|
||||
unsafe {
|
||||
let mut data = std::ptr::null_mut();
|
||||
intermediate_resource.Map(0, None, Some(&mut data))?;
|
||||
|
||||
for i in 0..num_subresources as usize {
|
||||
let dest_data = D3D12_MEMCPY_DEST {
|
||||
pData: data.offset(layouts[i].Offset as isize) as *mut std::ffi::c_void,
|
||||
RowPitch: layouts[i].Footprint.RowPitch as usize,
|
||||
SlicePitch: ((layouts[i].Footprint.RowPitch) * num_rows[i]) as usize,
|
||||
};
|
||||
|
||||
memcpy_subresource(
|
||||
&dest_data,
|
||||
&source_data[i],
|
||||
row_sizes_in_bytes[i],
|
||||
num_rows[i],
|
||||
layouts[i].Footprint.Depth,
|
||||
);
|
||||
}
|
||||
intermediate_resource.Unmap(0, None);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let destination_desc = destination_resource.GetDesc();
|
||||
if destination_desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER {
|
||||
cmd.CopyBufferRegion(
|
||||
destination_resource,
|
||||
0,
|
||||
intermediate_resource,
|
||||
layouts[0].Offset,
|
||||
layouts[0].Footprint.Width as u64,
|
||||
);
|
||||
} else {
|
||||
for i in 0..num_subresources as usize {
|
||||
let dest_location = D3D12_TEXTURE_COPY_LOCATION {
|
||||
pResource: ManuallyDrop::new(Some(destination_resource.clone())),
|
||||
Type: D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||
Anonymous: D3D12_TEXTURE_COPY_LOCATION_0 {
|
||||
SubresourceIndex: i as u32 + first_subresouce,
|
||||
},
|
||||
};
|
||||
|
||||
let source_location = D3D12_TEXTURE_COPY_LOCATION {
|
||||
pResource: ManuallyDrop::new(Some(intermediate_resource.clone())),
|
||||
Type: D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
|
||||
Anonymous: D3D12_TEXTURE_COPY_LOCATION_0 {
|
||||
PlacedFootprint: layouts[i],
|
||||
},
|
||||
};
|
||||
|
||||
cmd.CopyTextureRegion(&dest_location, 0, 0, 0, &source_location, None);
|
||||
|
||||
gc.dispose_resource(dest_location.pResource);
|
||||
gc.dispose_resource(source_location.pResource);
|
||||
}
|
||||
}
|
||||
Ok(required_size)
|
||||
}
|
||||
}
|
||||
|
||||
// this function should not leak to the public API, so
|
||||
// there is no point in using struct wrappers
|
||||
unsafe fn memcpy_subresource(
|
||||
dest: &D3D12_MEMCPY_DEST,
|
||||
src: &D3D12_SUBRESOURCE_DATA,
|
||||
row_sizes_in_bytes: u64,
|
||||
num_rows: u32,
|
||||
num_slices: u32,
|
||||
) {
|
||||
unsafe {
|
||||
for z in 0..num_slices as usize {
|
||||
let dest_slice = dest.pData.add(dest.SlicePitch * z);
|
||||
let src_slice = src.pData.offset(src.SlicePitch * z as isize);
|
||||
|
||||
for y in 0..num_rows as usize {
|
||||
std::ptr::copy_nonoverlapping(
|
||||
src_slice.offset(src.RowPitch * y as isize),
|
||||
dest_slice.add(dest.RowPitch * y),
|
||||
row_sizes_in_bytes as usize,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
use crate::error;
|
||||
use crate::error::assume_d3d12_init;
|
||||
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::u64;
|
||||
use widestring::{u16cstr, U16CStr};
|
||||
use windows::core::{Interface, PCWSTR};
|
||||
use windows::Win32::Graphics::Direct3D::Dxc::{
|
||||
|
@ -10,15 +7,14 @@ use windows::Win32::Graphics::Direct3D::Dxc::{
|
|||
DXC_CP_UTF8,
|
||||
};
|
||||
|
||||
use crate::filter_chain::FrameResiduals;
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_FEATURE_DATA_FORMAT_SUPPORT,
|
||||
D3D12_FEATURE_FORMAT_SUPPORT, D3D12_MEMCPY_DEST, D3D12_PLACED_SUBRESOURCE_FOOTPRINT,
|
||||
D3D12_FEATURE_FORMAT_SUPPORT,
|
||||
D3D12_RESOURCE_BARRIER, D3D12_RESOURCE_BARRIER_0, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
|
||||
D3D12_RESOURCE_BARRIER_FLAG_NONE, D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
|
||||
D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_STATES, D3D12_RESOURCE_TRANSITION_BARRIER,
|
||||
D3D12_SUBRESOURCE_DATA, D3D12_TEXTURE_COPY_LOCATION, D3D12_TEXTURE_COPY_LOCATION_0,
|
||||
D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||
D3D12_RESOURCE_BARRIER_FLAG_NONE, D3D12_RESOURCE_BARRIER_TYPE_TRANSITION
|
||||
, D3D12_RESOURCE_STATES, D3D12_RESOURCE_TRANSITION_BARRIER
|
||||
|
||||
,
|
||||
};
|
||||
use windows::Win32::Graphics::Dxgi::Common::*;
|
||||
|
||||
|
@ -237,157 +233,3 @@ pub fn d3d12_resource_transition_subresource(
|
|||
barrier
|
||||
}
|
||||
|
||||
pub(crate) fn d3d12_update_subresources(
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
destination_resource: &ID3D12Resource,
|
||||
intermediate_resource: &ID3D12Resource,
|
||||
intermediate_offset: u64,
|
||||
first_subresouce: u32,
|
||||
num_subresources: u32,
|
||||
source: &[D3D12_SUBRESOURCE_DATA],
|
||||
gc: &mut FrameResiduals,
|
||||
) -> error::Result<u64> {
|
||||
// let allocation_size = std::mem::size_of::<D3D12_PLACED_SUBRESOURCE_FOOTPRINT>()
|
||||
// + std::mem::size_of::<u32>()
|
||||
// + std::mem::size_of::<u64>() * num_subresources;
|
||||
|
||||
unsafe {
|
||||
let destination_desc = destination_resource.GetDesc();
|
||||
let mut device: Option<ID3D12Device> = None;
|
||||
destination_resource.GetDevice(&mut device)?;
|
||||
assume_d3d12_init!(device, "GetDevice");
|
||||
|
||||
let mut layouts =
|
||||
vec![D3D12_PLACED_SUBRESOURCE_FOOTPRINT::default(); num_subresources as usize];
|
||||
let mut num_rows = vec![0; num_subresources as usize];
|
||||
let mut row_sizes_in_bytes = vec![0; num_subresources as usize];
|
||||
let mut required_size = 0;
|
||||
|
||||
// texture upload
|
||||
device.GetCopyableFootprints(
|
||||
&destination_desc,
|
||||
first_subresouce,
|
||||
num_subresources,
|
||||
intermediate_offset,
|
||||
Some(layouts.as_mut_ptr()),
|
||||
Some(num_rows.as_mut_ptr()),
|
||||
Some(row_sizes_in_bytes.as_mut_ptr()),
|
||||
Some(&mut required_size),
|
||||
);
|
||||
|
||||
update_subresources(
|
||||
cmd,
|
||||
destination_resource,
|
||||
intermediate_resource,
|
||||
first_subresouce,
|
||||
num_subresources,
|
||||
required_size,
|
||||
&layouts,
|
||||
&num_rows,
|
||||
&row_sizes_in_bytes,
|
||||
source,
|
||||
gc,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn update_subresources(
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
destination_resource: &ID3D12Resource,
|
||||
intermediate_resource: &ID3D12Resource,
|
||||
first_subresouce: u32,
|
||||
num_subresources: u32,
|
||||
required_size: u64,
|
||||
layouts: &[D3D12_PLACED_SUBRESOURCE_FOOTPRINT],
|
||||
num_rows: &[u32],
|
||||
row_sizes_in_bytes: &[u64],
|
||||
source_data: &[D3D12_SUBRESOURCE_DATA],
|
||||
gc: &mut FrameResiduals,
|
||||
) -> error::Result<u64> {
|
||||
// ToDo: implement validation as in the original function
|
||||
|
||||
unsafe {
|
||||
let mut data = std::ptr::null_mut();
|
||||
intermediate_resource.Map(0, None, Some(&mut data))?;
|
||||
|
||||
for i in 0..num_subresources as usize {
|
||||
let dest_data = D3D12_MEMCPY_DEST {
|
||||
pData: data.offset(layouts[i].Offset as isize) as *mut std::ffi::c_void,
|
||||
RowPitch: layouts[i].Footprint.RowPitch as usize,
|
||||
SlicePitch: ((layouts[i].Footprint.RowPitch) * num_rows[i]) as usize,
|
||||
};
|
||||
|
||||
memcpy_subresource(
|
||||
&dest_data,
|
||||
&source_data[i],
|
||||
row_sizes_in_bytes[i],
|
||||
num_rows[i],
|
||||
layouts[i].Footprint.Depth,
|
||||
);
|
||||
}
|
||||
intermediate_resource.Unmap(0, None);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let destination_desc = destination_resource.GetDesc();
|
||||
if destination_desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER {
|
||||
cmd.CopyBufferRegion(
|
||||
destination_resource,
|
||||
0,
|
||||
intermediate_resource,
|
||||
layouts[0].Offset,
|
||||
layouts[0].Footprint.Width as u64,
|
||||
);
|
||||
} else {
|
||||
for i in 0..num_subresources as usize {
|
||||
let dest_location = D3D12_TEXTURE_COPY_LOCATION {
|
||||
pResource: ManuallyDrop::new(Some(destination_resource.clone())),
|
||||
Type: D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||
Anonymous: D3D12_TEXTURE_COPY_LOCATION_0 {
|
||||
SubresourceIndex: i as u32 + first_subresouce,
|
||||
},
|
||||
};
|
||||
|
||||
let source_location = D3D12_TEXTURE_COPY_LOCATION {
|
||||
pResource: ManuallyDrop::new(Some(intermediate_resource.clone())),
|
||||
Type: D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
|
||||
Anonymous: D3D12_TEXTURE_COPY_LOCATION_0 {
|
||||
PlacedFootprint: layouts[i],
|
||||
},
|
||||
};
|
||||
|
||||
cmd.CopyTextureRegion(&dest_location, 0, 0, 0, &source_location, None);
|
||||
|
||||
gc.dispose_resource(dest_location.pResource);
|
||||
gc.dispose_resource(source_location.pResource);
|
||||
}
|
||||
}
|
||||
Ok(required_size)
|
||||
}
|
||||
}
|
||||
|
||||
// this function should not leak to the public API, so
|
||||
// there is no point in using struct wrappers
|
||||
unsafe fn memcpy_subresource(
|
||||
dest: &D3D12_MEMCPY_DEST,
|
||||
src: &D3D12_SUBRESOURCE_DATA,
|
||||
row_sizes_in_bytes: u64,
|
||||
num_rows: u32,
|
||||
num_slices: u32,
|
||||
) {
|
||||
unsafe {
|
||||
for z in 0..num_slices as usize {
|
||||
let dest_slice = dest.pData.add(dest.SlicePitch * z);
|
||||
let src_slice = src.pData.offset(src.SlicePitch * z as isize);
|
||||
|
||||
for y in 0..num_rows as usize {
|
||||
std::ptr::copy_nonoverlapping(
|
||||
src_slice.offset(src.RowPitch * y as isize),
|
||||
dest_slice.add(dest.RowPitch * y),
|
||||
row_sizes_in_bytes as usize,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue