From dedde05c833c4dfd1e6f71560807e75225dcb17c Mon Sep 17 00:00:00 2001 From: chyyran Date: Sat, 28 Sep 2024 19:39:57 -0400 Subject: [PATCH] rt(d3d12): move update subresources to lut --- librashader-runtime-d3d12/src/luts.rs | 171 ++++++++++++++++++++++++-- librashader-runtime-d3d12/src/util.rs | 168 +------------------------ 2 files changed, 164 insertions(+), 175 deletions(-) diff --git a/librashader-runtime-d3d12/src/luts.rs b/librashader-runtime-d3d12/src/luts.rs index e9664ca..13e6c5e 100644 --- a/librashader-runtime-d3d12/src/luts.rs +++ b/librashader-runtime-d3d12/src/luts.rs @@ -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, @@ -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 { + // let allocation_size = std::mem::size_of::() + // + std::mem::size_of::() + // + std::mem::size_of::() * num_subresources; + + unsafe { + let destination_desc = destination_resource.GetDesc(); + let mut device: Option = 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 { + // 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, + ); + } + } + } +} \ No newline at end of file diff --git a/librashader-runtime-d3d12/src/util.rs b/librashader-runtime-d3d12/src/util.rs index 19ff040..0d04698 100644 --- a/librashader-runtime-d3d12/src/util.rs +++ b/librashader-runtime-d3d12/src/util.rs @@ -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 { - // let allocation_size = std::mem::size_of::() - // + std::mem::size_of::() - // + std::mem::size_of::() * num_subresources; - - unsafe { - let destination_desc = destination_resource.GetDesc(); - let mut device: Option = 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 { - // 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, - ); - } - } - } -}