d3d12: fix texture resource loads

This commit is contained in:
chyyran 2023-02-01 01:25:39 -05:00 committed by Ronny Chan
parent 03b4a7574e
commit cbe087fa6c
5 changed files with 76 additions and 30 deletions

View file

@ -495,23 +495,23 @@ impl FilterChainD3D12 {
.map(|(_, p)| p.config.mipmap_input) .map(|(_, p)| p.config.mipmap_input)
.unwrap_or(false); .unwrap_or(false);
// let next_size = self.output_framebuffers[index].scale( let next_size = self.output_framebuffers[index].scale(
// pass.config.scaling.clone(), pass.config.scaling.clone(),
// pass.get_format(), pass.get_format(),
// &viewport.output.size, &viewport.output.size,
// &source_size, &source_size,
// should_mipmap, 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; self.feedback_framebuffers[index].scale(
pass.config.scaling.clone(),
pass.get_format(),
&viewport.output.size,
&source_size,
should_mipmap,
)?;
source_size = next_size;
} }
Ok(()) Ok(())

View file

@ -1,7 +1,8 @@
use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FORMAT_SUPPORT1_MIP, D3D12_FORMAT_SUPPORT1_RENDER_TARGET, D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE, D3D12_FORMAT_SUPPORT1_TEXTURE2D, D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_DEFAULT, D3D12_MEMORY_POOL_UNKNOWN, D3D12_RENDER_TARGET_VIEW_DESC, D3D12_RENDER_TARGET_VIEW_DESC_0, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RTV_DIMENSION_TEXTURE2D, D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_RTV, D3D12_TEX2D_SRV, ID3D12Device, ID3D12Resource}; use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FORMAT_SUPPORT1_MIP, D3D12_FORMAT_SUPPORT1_RENDER_TARGET, D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE, D3D12_FORMAT_SUPPORT1_TEXTURE2D, D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_DEFAULT, D3D12_MEMORY_POOL_UNKNOWN, D3D12_RENDER_TARGET_VIEW_DESC, D3D12_RENDER_TARGET_VIEW_DESC_0, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RTV_DIMENSION_TEXTURE2D, D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_RTV, D3D12_TEX2D_SRV, ID3D12Device, ID3D12Resource};
use windows::Win32::Graphics::Dxgi::Common::{DXGI_SAMPLE_DESC}; use windows::Win32::Graphics::Dxgi::Common::{DXGI_SAMPLE_DESC};
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_runtime::scaling::MipmapSize; use librashader_presets::Scale2D;
use librashader_runtime::scaling::{MipmapSize, ViewportSize};
use crate::error; use crate::error;
use crate::error::assume_d3d12_init; use crate::error::assume_d3d12_init;
use crate::heap::{CpuStagingHeap, D3D12DescriptorHeap, RenderTargetHeap}; use crate::heap::{CpuStagingHeap, D3D12DescriptorHeap, RenderTargetHeap};
@ -26,14 +27,14 @@ impl OwnedImage {
mipmap: bool, mipmap: bool,
) -> error::Result<OwnedImage> { ) -> error::Result<OwnedImage> {
unsafe { unsafe {
let miplevels = size.calculate_miplevels() as u16; let miplevels = if mipmap { size.calculate_miplevels() } else { 1 };
let mut desc = D3D12_RESOURCE_DESC { let mut desc = D3D12_RESOURCE_DESC {
Dimension: D3D12_RESOURCE_DIMENSION_TEXTURE2D, Dimension: D3D12_RESOURCE_DIMENSION_TEXTURE2D,
Alignment: 0, Alignment: 0,
Width: size.width as u64, Width: size.width as u64,
Height: size.height, Height: size.height,
DepthOrArraySize: 1, DepthOrArraySize: 1,
MipLevels: if mipmap { miplevels } else { 1 }, MipLevels: miplevels as u16,
Format: format.into(), Format: format.into(),
SampleDesc: DXGI_SAMPLE_DESC { SampleDesc: DXGI_SAMPLE_DESC {
Count: 1, Count: 1,
@ -54,11 +55,9 @@ impl OwnedImage {
if mipmap { if mipmap {
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
format_support.Support1 |= D3D12_FORMAT_SUPPORT1_MIP; format_support.Support1 |= D3D12_FORMAT_SUPPORT1_MIP;
format_support.Support2 |= D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE;
} }
desc.Format = d3d12_get_closest_format(device, desc.Format, format_support); desc.Format = d3d12_get_closest_format(device, desc.Format, format_support);
let mut resource: Option<ID3D12Resource> = None; let mut resource: Option<ID3D12Resource> = None;
unsafe { unsafe {
device.CreateCommittedResource( device.CreateCommittedResource(
@ -83,7 +82,7 @@ impl OwnedImage {
size, size,
format, format,
device: device.clone(), device: device.clone(),
max_mipmap: miplevels, max_mipmap: miplevels as u16,
}) })
} }
} }
@ -101,7 +100,7 @@ impl OwnedImage {
Shader4ComponentMapping: D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, Shader4ComponentMapping: D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
Anonymous: D3D12_SHADER_RESOURCE_VIEW_DESC_0 { Anonymous: D3D12_SHADER_RESOURCE_VIEW_DESC_0 {
Texture2D: D3D12_TEX2D_SRV { Texture2D: D3D12_TEX2D_SRV {
MipLevels: self.max_mipmap as u32, MipLevels: u32::MAX,
..Default::default() ..Default::default()
}, },
}, },
@ -135,4 +134,30 @@ impl OwnedImage {
Ok(OutputTexture::new(descriptor, self.size)) Ok(OutputTexture::new(descriptor, self.size))
} }
pub fn scale(&mut self,
scaling: Scale2D,
format: ImageFormat,
viewport_size: &Size<u32>,
source_size: &Size<u32>,
mipmap: bool,
) -> error::Result<Size<u32>>
{
let size = source_size.scale_viewport(scaling, *viewport_size);
if self.size != size
|| (mipmap && self.max_mipmap == 1)
|| (!mipmap && self.max_mipmap != 1)
|| format != self.format
{
let mut new = OwnedImage::new(
&self.device,
size,
format,
mipmap
)?;
std::mem::swap(self, &mut new);
}
Ok(size)
}
} }

View file

@ -240,6 +240,8 @@ pub mod d3d12_hello_triangle {
use super::*; use super::*;
use crate::filter_chain::FilterChainD3D12; use crate::filter_chain::FilterChainD3D12;
use std::path::Path; use std::path::Path;
use librashader_common::{FilterMode, Size, Viewport, WrapMode};
use crate::texture::{InputTexture, OutputTexture};
const FRAME_COUNT: u32 = 2; const FRAME_COUNT: u32 = 2;
@ -248,6 +250,7 @@ pub mod d3d12_hello_triangle {
device: ID3D12Device, device: ID3D12Device,
resources: Option<Resources>, resources: Option<Resources>,
pub filter: FilterChainD3D12, pub filter: FilterChainD3D12,
framecount: usize
} }
struct Resources { struct Resources {
@ -299,6 +302,7 @@ pub mod d3d12_hello_triangle {
device, device,
resources: None, resources: None,
filter, filter,
framecount: 0
}) })
} }
@ -479,7 +483,7 @@ pub mod d3d12_hello_triangle {
fn render(&mut self) { fn render(&mut self) {
if let Some(resources) = &mut self.resources { if let Some(resources) = &mut self.resources {
populate_command_list(resources).unwrap(); populate_command_list(resources, &mut self.filter, self.framecount).unwrap();
// Execute the command list. // Execute the command list.
let command_list = ID3D12CommandList::from(&resources.command_list); let command_list = ID3D12CommandList::from(&resources.command_list);
@ -489,11 +493,12 @@ pub mod d3d12_hello_triangle {
unsafe { resources.swap_chain.Present(1, 0) }.ok().unwrap(); unsafe { resources.swap_chain.Present(1, 0) }.ok().unwrap();
wait_for_previous_frame(resources); wait_for_previous_frame(resources);
self.framecount += 1;
} }
} }
} }
fn populate_command_list(resources: &Resources) -> Result<()> { fn populate_command_list(resources: &Resources, filter: &mut FilterChainD3D12, frame_count: usize) -> Result<()> {
// Command list allocators can only be reset when the associated // Command list allocators can only be reset when the associated
// command lists have finished execution on the GPU; apps should use // command lists have finished execution on the GPU; apps should use
// fences to determine GPU execution progress. // fences to determine GPU execution progress.
@ -562,6 +567,22 @@ pub mod d3d12_hello_triangle {
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
)]); )]);
filter.frame(
InputTexture::new_from_raw(D3D12_CPU_DESCRIPTOR_HANDLE {
ptr: 0
}, Size::new(resources.viewport.Width as u32, resources.viewport.Height as u32),
DXGI_FORMAT_R8G8B8A8_UNORM,
WrapMode::ClampToEdge,
FilterMode::Linear,
),
&Viewport {
x: 0.0,
y: 0.0,
mvp: None,
output: OutputTexture::new_from_raw(D3D12_CPU_DESCRIPTOR_HANDLE {
ptr: 0
}, Size::new(resources.viewport.Width as u32, resources.viewport.Height as u32)),
}, frame_count, None).unwrap();
command_list.ResourceBarrier(&[transition_barrier( command_list.ResourceBarrier(&[transition_barrier(
&resources.render_targets[resources.frame_index as usize], &resources.render_targets[resources.frame_index as usize],

View file

@ -54,7 +54,6 @@ impl LutTexture {
if mipmap { if mipmap {
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
format_support.Support1 |= D3D12_FORMAT_SUPPORT1_MIP; format_support.Support1 |= D3D12_FORMAT_SUPPORT1_MIP;
format_support.Support2 |= D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE;
} }
desc.Format = d3d12_get_closest_format(device, desc.Format, format_support); desc.Format = d3d12_get_closest_format(device, desc.Format, format_support);
@ -86,7 +85,7 @@ impl LutTexture {
Shader4ComponentMapping: D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, Shader4ComponentMapping: D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
Anonymous: D3D12_SHADER_RESOURCE_VIEW_DESC_0 { Anonymous: D3D12_SHADER_RESOURCE_VIEW_DESC_0 {
Texture2D: D3D12_TEX2D_SRV { Texture2D: D3D12_TEX2D_SRV {
MipLevels: desc.MipLevels as u32, MipLevels: u32::MAX,
..Default::default() ..Default::default()
}, },
}, },

View file

@ -1,4 +1,5 @@
use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_DESCRIPTOR_HANDLE}; use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_DESCRIPTOR_HANDLE};
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use crate::heap::{CpuStagingHeap, D3D12DescriptorHeapSlot, RenderTargetHeap}; use crate::heap::{CpuStagingHeap, D3D12DescriptorHeapSlot, RenderTargetHeap};
@ -61,7 +62,7 @@ impl OutputTexture {
pub struct InputTexture { pub struct InputTexture {
pub(crate) descriptor: InputDescriptor, pub(crate) descriptor: InputDescriptor,
pub(crate) size: Size<u32>, pub(crate) size: Size<u32>,
format: ImageFormat, format: DXGI_FORMAT,
pub(crate) wrap_mode: WrapMode, pub(crate) wrap_mode: WrapMode,
pub(crate) filter: FilterMode pub(crate) filter: FilterMode
} }
@ -76,7 +77,7 @@ impl InputTexture {
InputTexture { InputTexture {
descriptor: srv, descriptor: srv,
size, size,
format, format: format.into(),
wrap_mode, wrap_mode,
filter filter
} }
@ -85,7 +86,7 @@ impl InputTexture {
// unsafe since the lifetime of the handle has to survive // unsafe since the lifetime of the handle has to survive
pub unsafe fn new_from_raw(handle: D3D12_CPU_DESCRIPTOR_HANDLE, pub unsafe fn new_from_raw(handle: D3D12_CPU_DESCRIPTOR_HANDLE,
size: Size<u32>, size: Size<u32>,
format: ImageFormat, format: DXGI_FORMAT,
wrap_mode: WrapMode, wrap_mode: WrapMode,
filter: FilterMode filter: FilterMode
) -> InputTexture { ) -> InputTexture {