librashader/librashader-runtime-d3d12/src/draw_quad.rs

122 lines
3.8 KiB
Rust
Raw Normal View History

2023-02-06 08:17:23 +11:00
use crate::buffer::D3D12Buffer;
2023-01-30 18:02:10 +11:00
use crate::error;
2023-02-06 17:05:19 +11:00
use array_concat::concat_arrays;
2024-02-22 16:41:29 +11:00
use bytemuck::offset_of;
use librashader_runtime::quad::{QuadType, VertexInput};
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;
2023-02-06 17:05:19 +11:00
use windows::Win32::Graphics::Direct3D12::{
ID3D12Device, ID3D12GraphicsCommandList, ID3D12GraphicsCommandList4, 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;
2024-02-22 16:41:29 +11:00
const OFFSCREEN_VBO_DATA: [VertexInput; 4] = [
VertexInput {
position: [-1.0, -1.0, 0.0, 1.0],
texcoord: [0.0, 1.0],
},
2024-02-22 16:41:29 +11:00
VertexInput {
position: [-1.0, 1.0, 0.0, 1.0],
texcoord: [0.0, 0.0],
},
2024-02-22 16:41:29 +11:00
VertexInput {
position: [1.0, -1.0, 0.0, 1.0],
texcoord: [1.0, 1.0],
},
2024-02-22 16:41:29 +11:00
VertexInput {
position: [1.0, 1.0, 0.0, 1.0],
texcoord: [1.0, 0.0],
},
];
2024-02-22 16:41:29 +11:00
const FINAL_VBO_DATA: [VertexInput; 4] = [
VertexInput {
position: [0.0, 0.0, 0.0, 1.0],
2023-01-30 18:02:10 +11:00
texcoord: [0.0, 1.0],
},
2024-02-22 16:41:29 +11:00
VertexInput {
position: [0.0, 1.0, 0.0, 1.0],
2023-01-30 18:02:10 +11:00
texcoord: [0.0, 0.0],
},
2024-02-22 16:41:29 +11:00
VertexInput {
position: [1.0, 0.0, 0.0, 1.0],
2023-01-30 18:02:10 +11:00
texcoord: [1.0, 1.0],
},
2024-02-22 16:41:29 +11:00
VertexInput {
position: [1.0, 1.0, 0.0, 1.0],
2023-01-30 18:02:10 +11:00
texcoord: [1.0, 0.0],
},
];
2024-02-22 16:41:29 +11:00
static VBO_DATA: &[VertexInput; 8] = &concat_arrays!(OFFSCREEN_VBO_DATA, FINAL_VBO_DATA);
2023-01-30 18:02:10 +11:00
pub(crate) struct DrawQuad {
2023-02-10 13:03:55 +11:00
_buffer: ID3D12Resource,
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> {
2024-02-22 16:41:29 +11:00
let stride = std::mem::size_of::<VertexInput>() as u32;
let size = 2 * std::mem::size_of::<[VertexInput; 4]>() as u32;
let mut buffer = D3D12Buffer::new(device, size as usize)?;
buffer
.map(None)?
.slice
.copy_from_slice(bytemuck::cast_slice(VBO_DATA));
let view = D3D12_VERTEX_BUFFER_VIEW {
BufferLocation: buffer.gpu_address(),
SizeInBytes: size,
StrideInBytes: stride,
};
let buffer = buffer.into_raw();
2023-02-10 13:03:55 +11:00
Ok(DrawQuad {
_buffer: buffer,
view,
})
2023-01-31 15:30:11 +11:00
}
pub fn bind_vertices_for_frame(&self, cmd: &ID3D12GraphicsCommandList) {
2023-01-31 15:30:11 +11:00
unsafe {
cmd.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
cmd.IASetVertexBuffers(0, Some(&[self.view]));
}
}
// frame uses ID3D12GraphicsCommandList4 for renderpasses, don't need to bother with the cast.
pub fn draw_quad(&self, cmd: &ID3D12GraphicsCommandList4, vbo_type: QuadType) {
let offset = match vbo_type {
QuadType::Offscreen => 0,
QuadType::Final => 4,
};
2023-02-06 17:05:19 +11:00
unsafe { cmd.DrawInstanced(4, 1, offset, 0) }
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,
2024-02-22 16:41:29 +11:00
AlignedByteOffset: offset_of!(VertexInput, position) as u32,
2023-01-30 18:02:10 +11:00
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,
2024-02-22 16:41:29 +11:00
AlignedByteOffset: offset_of!(VertexInput, texcoord) as u32,
2023-01-30 18:02:10 +11:00
InputSlotClass: D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
]
}
}