2023-02-06 08:17:23 +11:00
|
|
|
use crate::buffer::D3D12Buffer;
|
2023-01-30 18:02:10 +11:00
|
|
|
use crate::error;
|
2023-01-31 15:30:11 +11:00
|
|
|
use bytemuck::{offset_of, Pod, Zeroable};
|
2023-02-06 08:17:23 +11:00
|
|
|
use librashader_runtime::quad::QuadType;
|
2023-01-30 18:02:10 +11:00
|
|
|
use windows::core::PCSTR;
|
2023-02-06 08:17:23 +11:00
|
|
|
use windows::Win32::Graphics::Direct3D::D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
|
|
|
|
use windows::Win32::Graphics::Direct3D12::{
|
|
|
|
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource,
|
|
|
|
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, D3D12_INPUT_ELEMENT_DESC, D3D12_VERTEX_BUFFER_VIEW,
|
|
|
|
};
|
2023-01-30 18:02:10 +11:00
|
|
|
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT;
|
|
|
|
|
|
|
|
#[repr(C)]
|
2023-01-31 15:30:11 +11:00
|
|
|
#[derive(Debug, Copy, Clone, Default, Zeroable, Pod)]
|
2023-01-30 18:02:10 +11:00
|
|
|
struct D3D12Vertex {
|
|
|
|
position: [f32; 2],
|
|
|
|
texcoord: [f32; 2],
|
|
|
|
color: [f32; 4],
|
|
|
|
}
|
|
|
|
|
|
|
|
const CLEAR: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
|
|
|
|
|
2023-02-06 15:26:14 +11:00
|
|
|
static OFFSCREEN_VBO_DATA: &[D3D12Vertex; 4] = &[
|
|
|
|
D3D12Vertex {
|
|
|
|
position: [-1.0, -1.0],
|
|
|
|
texcoord: [0.0, 1.0],
|
|
|
|
color: CLEAR,
|
|
|
|
},
|
|
|
|
D3D12Vertex {
|
|
|
|
position: [-1.0, 1.0],
|
|
|
|
texcoord: [0.0, 0.0],
|
|
|
|
color: CLEAR,
|
|
|
|
},
|
|
|
|
D3D12Vertex {
|
|
|
|
position: [1.0, -1.0],
|
|
|
|
texcoord: [1.0, 1.0],
|
|
|
|
color: CLEAR,
|
|
|
|
},
|
|
|
|
D3D12Vertex {
|
|
|
|
position: [1.0, 1.0],
|
|
|
|
texcoord: [1.0, 0.0],
|
|
|
|
color: CLEAR,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
static FINAL_VBO_DATA: &[D3D12Vertex; 4] = &[
|
2023-01-30 18:02:10 +11:00
|
|
|
D3D12Vertex {
|
|
|
|
position: [0.0, 0.0],
|
|
|
|
texcoord: [0.0, 1.0],
|
|
|
|
color: CLEAR,
|
|
|
|
},
|
|
|
|
D3D12Vertex {
|
|
|
|
position: [0.0, 1.0],
|
|
|
|
texcoord: [0.0, 0.0],
|
|
|
|
color: CLEAR,
|
|
|
|
},
|
|
|
|
D3D12Vertex {
|
|
|
|
position: [1.0, 0.0],
|
|
|
|
texcoord: [1.0, 1.0],
|
|
|
|
color: CLEAR,
|
|
|
|
},
|
|
|
|
D3D12Vertex {
|
|
|
|
position: [1.0, 1.0],
|
|
|
|
texcoord: [1.0, 0.0],
|
|
|
|
color: CLEAR,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
pub(crate) struct DrawQuad {
|
2023-02-06 15:26:14 +11:00
|
|
|
offscreen_buffer: ID3D12Resource,
|
|
|
|
offscreen_view: D3D12_VERTEX_BUFFER_VIEW,
|
|
|
|
final_buffer: ID3D12Resource,
|
|
|
|
final_view: D3D12_VERTEX_BUFFER_VIEW,
|
2023-01-30 18:02:10 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
impl DrawQuad {
|
2023-02-06 08:17:23 +11:00
|
|
|
pub fn new(device: &ID3D12Device) -> error::Result<DrawQuad> {
|
2023-01-31 15:30:11 +11:00
|
|
|
let stride = std::mem::size_of::<D3D12Vertex>() as u32;
|
2023-02-06 08:17:23 +11:00
|
|
|
let size = std::mem::size_of::<[D3D12Vertex; 4]>() as u32;
|
2023-02-06 15:26:14 +11:00
|
|
|
let mut offscreen_buffer = D3D12Buffer::new(device, size as usize)?;
|
|
|
|
offscreen_buffer
|
2023-02-06 08:17:23 +11:00
|
|
|
.map(None)?
|
|
|
|
.slice
|
2023-02-06 15:26:14 +11:00
|
|
|
.copy_from_slice(bytemuck::cast_slice(OFFSCREEN_VBO_DATA));
|
2023-01-31 15:30:11 +11:00
|
|
|
|
2023-02-06 15:26:14 +11:00
|
|
|
let offscreen_view = D3D12_VERTEX_BUFFER_VIEW {
|
|
|
|
BufferLocation: offscreen_buffer.gpu_address(),
|
2023-01-31 15:30:11 +11:00
|
|
|
SizeInBytes: size,
|
|
|
|
StrideInBytes: stride,
|
|
|
|
};
|
|
|
|
|
2023-02-06 15:26:14 +11:00
|
|
|
let offscreen_buffer = offscreen_buffer.into_raw();
|
|
|
|
|
|
|
|
let mut final_buffer = D3D12Buffer::new(device, size as usize)?;
|
|
|
|
final_buffer
|
|
|
|
.map(None)?
|
|
|
|
.slice
|
|
|
|
.copy_from_slice(bytemuck::cast_slice(FINAL_VBO_DATA));
|
|
|
|
|
|
|
|
let final_view = D3D12_VERTEX_BUFFER_VIEW {
|
|
|
|
BufferLocation: final_buffer.gpu_address(),
|
|
|
|
SizeInBytes: size,
|
|
|
|
StrideInBytes: stride,
|
|
|
|
};
|
|
|
|
|
|
|
|
let final_buffer = final_buffer.into_raw();
|
|
|
|
|
|
|
|
Ok(DrawQuad { offscreen_buffer, offscreen_view, final_buffer, final_view })
|
2023-01-31 15:30:11 +11:00
|
|
|
}
|
|
|
|
|
2023-02-06 15:26:14 +11:00
|
|
|
pub fn bind_vertices(&self, cmd: &ID3D12GraphicsCommandList, vbo_type: QuadType) {
|
2023-01-31 15:30:11 +11:00
|
|
|
unsafe {
|
|
|
|
cmd.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
2023-02-06 15:26:14 +11:00
|
|
|
|
|
|
|
let view = match vbo_type {
|
|
|
|
QuadType::Offscreen => [self.offscreen_view],
|
|
|
|
QuadType::Final => [self.final_view],
|
|
|
|
};
|
|
|
|
|
|
|
|
cmd.IASetVertexBuffers(0, Some(&view));
|
2023-01-31 15:30:11 +11:00
|
|
|
}
|
|
|
|
}
|
2023-01-30 18:02:10 +11:00
|
|
|
|
|
|
|
pub fn get_spirv_cross_vbo_desc() -> [D3D12_INPUT_ELEMENT_DESC; 2] {
|
|
|
|
[
|
|
|
|
D3D12_INPUT_ELEMENT_DESC {
|
|
|
|
SemanticName: PCSTR(b"TEXCOORD\0".as_ptr()),
|
|
|
|
SemanticIndex: 0,
|
|
|
|
Format: DXGI_FORMAT_R32G32_FLOAT,
|
|
|
|
InputSlot: 0,
|
|
|
|
AlignedByteOffset: offset_of!(D3D12Vertex, position) as u32,
|
|
|
|
InputSlotClass: D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
|
|
|
|
InstanceDataStepRate: 0,
|
|
|
|
},
|
|
|
|
D3D12_INPUT_ELEMENT_DESC {
|
|
|
|
SemanticName: PCSTR(b"TEXCOORD\0".as_ptr()),
|
|
|
|
SemanticIndex: 1,
|
|
|
|
Format: DXGI_FORMAT_R32G32_FLOAT,
|
|
|
|
InputSlot: 0,
|
|
|
|
AlignedByteOffset: offset_of!(D3D12Vertex, texcoord) as u32,
|
|
|
|
InputSlotClass: D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
|
|
|
|
InstanceDataStepRate: 0,
|
|
|
|
},
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|