refactor
This commit is contained in:
parent
667c19907a
commit
b012246d2b
1 changed files with 112 additions and 173 deletions
|
@ -285,59 +285,19 @@ impl DirectXRenderer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
update_paths_buffer_capacity(
|
self.pipelines.paths_pipeline.update_buffer(
|
||||||
&self.pipelines.paths_pipeline,
|
|
||||||
sprites.len(),
|
|
||||||
&self.devices.device,
|
&self.devices.device,
|
||||||
)
|
|
||||||
.map(|input| update_paths_pipeline_buffer(&mut self.pipelines.paths_pipeline, input));
|
|
||||||
update_buffer(
|
|
||||||
&self.devices.device_context,
|
&self.devices.device_context,
|
||||||
&self.pipelines.paths_pipeline.buffer,
|
|
||||||
&sprites,
|
&sprites,
|
||||||
)?;
|
|
||||||
update_paths_vertex_capacity(
|
|
||||||
&mut self.pipelines.paths_pipeline,
|
|
||||||
vertices.len(),
|
|
||||||
&self.devices.device,
|
|
||||||
)
|
|
||||||
.map(|input| update_paths_pipeline_vertex(&mut self.pipelines.paths_pipeline, input));
|
|
||||||
update_buffer(
|
|
||||||
&self.devices.device_context,
|
|
||||||
self.pipelines
|
|
||||||
.paths_pipeline
|
|
||||||
.vertex_buffer
|
|
||||||
.as_ref()
|
|
||||||
.unwrap(),
|
|
||||||
&vertices,
|
&vertices,
|
||||||
)?;
|
|
||||||
update_indirect_buffer_capacity(
|
|
||||||
&self.pipelines.paths_pipeline,
|
|
||||||
draw_indirect_commands.len(),
|
|
||||||
&self.devices.device,
|
|
||||||
)
|
|
||||||
.map(|input| update_paths_indirect_buffer(&mut self.pipelines.paths_pipeline, input));
|
|
||||||
update_buffer(
|
|
||||||
&self.devices.device_context,
|
|
||||||
&self.pipelines.paths_pipeline.indirect_draw_buffer,
|
|
||||||
&draw_indirect_commands,
|
&draw_indirect_commands,
|
||||||
)?;
|
)?;
|
||||||
prepare_indirect_draws(
|
self.pipelines.paths_pipeline.draw(
|
||||||
&self.devices.device_context,
|
&self.devices.device_context,
|
||||||
&self.pipelines.paths_pipeline,
|
paths.len(),
|
||||||
&self.context.viewport,
|
&self.context.viewport,
|
||||||
&self.globals.global_params_buffer,
|
&self.globals.global_params_buffer,
|
||||||
D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
|
)
|
||||||
)?;
|
|
||||||
|
|
||||||
for i in 0..paths.len() {
|
|
||||||
draw_indirect(
|
|
||||||
&self.devices.device_context,
|
|
||||||
&self.pipelines.paths_pipeline.indirect_draw_buffer,
|
|
||||||
(i * std::mem::size_of::<DrawInstancedIndirectArgs>()) as u32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_underlines(&mut self, underlines: &[Underline]) -> Result<()> {
|
fn draw_underlines(&mut self, underlines: &[Underline]) -> Result<()> {
|
||||||
|
@ -634,18 +594,19 @@ impl<T> PipelineState<T> {
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if self.buffer_size < data.len() {
|
if self.buffer_size < data.len() {
|
||||||
let new_buffer_size = data.len().next_power_of_two();
|
let new_buffer_size = data.len().next_power_of_two();
|
||||||
|
log::info!(
|
||||||
|
"Updating {} buffer size from {} to {}",
|
||||||
|
self.label,
|
||||||
|
self.buffer_size,
|
||||||
|
new_buffer_size
|
||||||
|
);
|
||||||
let buffer = create_buffer(device, std::mem::size_of::<T>(), new_buffer_size)?;
|
let buffer = create_buffer(device, std::mem::size_of::<T>(), new_buffer_size)?;
|
||||||
let view = create_buffer_view(device, &buffer)?;
|
let view = create_buffer_view(device, &buffer)?;
|
||||||
self.buffer = buffer;
|
self.buffer = buffer;
|
||||||
self.view = view;
|
self.view = view;
|
||||||
|
self.buffer_size = new_buffer_size;
|
||||||
}
|
}
|
||||||
unsafe {
|
update_buffer(device_context, &self.buffer, data)
|
||||||
let mut dest = std::mem::zeroed();
|
|
||||||
device_context.Map(&self.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, Some(&mut dest))?;
|
|
||||||
std::ptr::copy_nonoverlapping(data.as_ptr(), dest.pData as _, data.len());
|
|
||||||
device_context.Unmap(&self.buffer, 0);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(
|
fn draw(
|
||||||
|
@ -784,6 +745,101 @@ impl PathsPipelineState {
|
||||||
view,
|
view,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_buffer(
|
||||||
|
&mut self,
|
||||||
|
device: &ID3D11Device,
|
||||||
|
device_context: &ID3D11DeviceContext,
|
||||||
|
buffer_data: &[PathSprite],
|
||||||
|
vertices_data: &[PathVertex<ScaledPixels>],
|
||||||
|
draw_commands: &[DrawInstancedIndirectArgs],
|
||||||
|
) -> Result<()> {
|
||||||
|
if self.buffer_size < buffer_data.len() {
|
||||||
|
let new_buffer_size = buffer_data.len().next_power_of_two();
|
||||||
|
log::info!(
|
||||||
|
"Updating Paths Pipeline buffer size from {} to {}",
|
||||||
|
self.buffer_size,
|
||||||
|
new_buffer_size
|
||||||
|
);
|
||||||
|
let buffer = create_buffer(device, std::mem::size_of::<PathSprite>(), new_buffer_size)?;
|
||||||
|
let view = create_buffer_view(device, &buffer)?;
|
||||||
|
self.buffer = buffer;
|
||||||
|
self.view = view;
|
||||||
|
self.buffer_size = new_buffer_size;
|
||||||
|
}
|
||||||
|
update_buffer(device_context, &self.buffer, buffer_data)?;
|
||||||
|
if self.vertex_buffer_size < vertices_data.len() {
|
||||||
|
let new_vertex_buffer_size = vertices_data.len().next_power_of_two();
|
||||||
|
log::info!(
|
||||||
|
"Updating Paths Pipeline vertex buffer size from {} to {}",
|
||||||
|
self.vertex_buffer_size,
|
||||||
|
new_vertex_buffer_size
|
||||||
|
);
|
||||||
|
let vertex_buffer = create_buffer(
|
||||||
|
device,
|
||||||
|
std::mem::size_of::<PathVertex<ScaledPixels>>(),
|
||||||
|
new_vertex_buffer_size,
|
||||||
|
)?;
|
||||||
|
self.vertex_buffer = Some(vertex_buffer);
|
||||||
|
self.vertex_buffer_size = new_vertex_buffer_size;
|
||||||
|
}
|
||||||
|
update_buffer(
|
||||||
|
device_context,
|
||||||
|
self.vertex_buffer.as_ref().unwrap(),
|
||||||
|
vertices_data,
|
||||||
|
)?;
|
||||||
|
if self.indirect_buffer_size < draw_commands.len() {
|
||||||
|
let new_indirect_buffer_size = draw_commands.len().next_power_of_two();
|
||||||
|
log::info!(
|
||||||
|
"Updating Paths Pipeline indirect buffer size from {} to {}",
|
||||||
|
self.indirect_buffer_size,
|
||||||
|
new_indirect_buffer_size
|
||||||
|
);
|
||||||
|
let indirect_draw_buffer =
|
||||||
|
create_indirect_draw_buffer(device, new_indirect_buffer_size)?;
|
||||||
|
self.indirect_draw_buffer = indirect_draw_buffer;
|
||||||
|
self.indirect_buffer_size = new_indirect_buffer_size;
|
||||||
|
}
|
||||||
|
update_buffer(device_context, &self.indirect_draw_buffer, draw_commands)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
device_context: &ID3D11DeviceContext,
|
||||||
|
count: usize,
|
||||||
|
viewport: &[D3D11_VIEWPORT],
|
||||||
|
global_params: &[Option<ID3D11Buffer>],
|
||||||
|
) -> Result<()> {
|
||||||
|
unsafe {
|
||||||
|
device_context.VSSetShaderResources(1, Some(&self.view));
|
||||||
|
device_context.PSSetShaderResources(1, Some(&self.view));
|
||||||
|
device_context.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
|
device_context.RSSetViewports(Some(viewport));
|
||||||
|
device_context.VSSetShader(&self.vertex, None);
|
||||||
|
device_context.PSSetShader(&self.fragment, None);
|
||||||
|
device_context.VSSetConstantBuffers(0, Some(global_params));
|
||||||
|
device_context.PSSetConstantBuffers(0, Some(global_params));
|
||||||
|
const STRIDE: u32 = std::mem::size_of::<PathVertex<ScaledPixels>>() as u32;
|
||||||
|
device_context.IASetVertexBuffers(
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
Some(&self.vertex_buffer),
|
||||||
|
Some(&STRIDE),
|
||||||
|
Some(&0),
|
||||||
|
);
|
||||||
|
device_context.IASetInputLayout(&self.input_layout);
|
||||||
|
}
|
||||||
|
for i in 0..count {
|
||||||
|
unsafe {
|
||||||
|
device_context.DrawInstancedIndirect(
|
||||||
|
&self.indirect_draw_buffer,
|
||||||
|
(i * std::mem::size_of::<DrawInstancedIndirectArgs>()) as u32,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
@ -1048,21 +1104,6 @@ fn create_indirect_draw_buffer(device: &ID3D11Device, buffer_size: usize) -> Res
|
||||||
Ok(buffer.unwrap())
|
Ok(buffer.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_global_params(
|
|
||||||
device_context: &ID3D11DeviceContext,
|
|
||||||
buffer: &[Option<ID3D11Buffer>; 1],
|
|
||||||
globals: GlobalParams,
|
|
||||||
) -> Result<()> {
|
|
||||||
let buffer = buffer[0].as_ref().unwrap();
|
|
||||||
unsafe {
|
|
||||||
let mut data = std::mem::zeroed();
|
|
||||||
device_context.Map(buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, Some(&mut data))?;
|
|
||||||
std::ptr::copy_nonoverlapping(&globals, data.pData as *mut _, 1);
|
|
||||||
device_context.Unmap(buffer, 0);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pre_draw(
|
fn pre_draw(
|
||||||
device_context: &ID3D11DeviceContext,
|
device_context: &ID3D11DeviceContext,
|
||||||
global_params_buffer: &[Option<ID3D11Buffer>; 1],
|
global_params_buffer: &[Option<ID3D11Buffer>; 1],
|
||||||
|
@ -1071,13 +1112,14 @@ fn pre_draw(
|
||||||
clear_color: [f32; 4],
|
clear_color: [f32; 4],
|
||||||
blend_state: &ID3D11BlendState,
|
blend_state: &ID3D11BlendState,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
update_global_params(
|
let global_params = global_params_buffer[0].as_ref().unwrap();
|
||||||
|
update_buffer(
|
||||||
device_context,
|
device_context,
|
||||||
global_params_buffer,
|
global_params,
|
||||||
GlobalParams {
|
&[GlobalParams {
|
||||||
viewport_size: [view_port[0].Width, view_port[0].Height],
|
viewport_size: [view_port[0].Width, view_port[0].Height],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
}],
|
||||||
)?;
|
)?;
|
||||||
unsafe {
|
unsafe {
|
||||||
device_context.RSSetViewports(Some(view_port));
|
device_context.RSSetViewports(Some(view_port));
|
||||||
|
@ -1088,70 +1130,6 @@ fn pre_draw(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_paths_buffer_capacity(
|
|
||||||
pipeline: &PathsPipelineState,
|
|
||||||
data_size: usize,
|
|
||||||
device: &ID3D11Device,
|
|
||||||
) -> Option<(ID3D11Buffer, usize, [Option<ID3D11ShaderResourceView>; 1])> {
|
|
||||||
if pipeline.buffer_size >= data_size {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let buffer_size = data_size.next_power_of_two();
|
|
||||||
let buffer = create_buffer(device, std::mem::size_of::<PathSprite>(), buffer_size).unwrap();
|
|
||||||
let view = create_buffer_view(device, &buffer).unwrap();
|
|
||||||
Some((buffer, buffer_size, view))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_paths_vertex_capacity(
|
|
||||||
pipeline: &PathsPipelineState,
|
|
||||||
vertex_size: usize,
|
|
||||||
device: &ID3D11Device,
|
|
||||||
) -> Option<(ID3D11Buffer, usize)> {
|
|
||||||
if pipeline.vertex_buffer_size >= vertex_size {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let vertex_size = vertex_size.next_power_of_two();
|
|
||||||
let buffer = create_buffer(
|
|
||||||
device,
|
|
||||||
std::mem::size_of::<PathVertex<ScaledPixels>>(),
|
|
||||||
vertex_size,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
Some((buffer, vertex_size))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_indirect_buffer_capacity(
|
|
||||||
pipeline: &PathsPipelineState,
|
|
||||||
data_size: usize,
|
|
||||||
device: &ID3D11Device,
|
|
||||||
) -> Option<(ID3D11Buffer, usize)> {
|
|
||||||
if pipeline.indirect_buffer_size >= data_size {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let buffer_size = data_size.next_power_of_two();
|
|
||||||
let buffer = create_indirect_draw_buffer(device, data_size).unwrap();
|
|
||||||
Some((buffer, buffer_size))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_paths_pipeline_buffer(
|
|
||||||
pipeline: &mut PathsPipelineState,
|
|
||||||
input: (ID3D11Buffer, usize, [Option<ID3D11ShaderResourceView>; 1]),
|
|
||||||
) {
|
|
||||||
pipeline.buffer = input.0;
|
|
||||||
pipeline.buffer_size = input.1;
|
|
||||||
pipeline.view = input.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_paths_pipeline_vertex(pipeline: &mut PathsPipelineState, input: (ID3D11Buffer, usize)) {
|
|
||||||
pipeline.vertex_buffer = Some(input.0);
|
|
||||||
pipeline.vertex_buffer_size = input.1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_paths_indirect_buffer(pipeline: &mut PathsPipelineState, input: (ID3D11Buffer, usize)) {
|
|
||||||
pipeline.indirect_draw_buffer = input.0;
|
|
||||||
pipeline.indirect_buffer_size = input.1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_buffer<T>(
|
fn update_buffer<T>(
|
||||||
device_context: &ID3D11DeviceContext,
|
device_context: &ID3D11DeviceContext,
|
||||||
buffer: &ID3D11Buffer,
|
buffer: &ID3D11Buffer,
|
||||||
|
@ -1166,45 +1144,6 @@ fn update_buffer<T>(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_indirect_draws(
|
|
||||||
device_context: &ID3D11DeviceContext,
|
|
||||||
pipeline: &PathsPipelineState,
|
|
||||||
viewport: &[D3D11_VIEWPORT],
|
|
||||||
global_params: &[Option<ID3D11Buffer>],
|
|
||||||
topology: D3D_PRIMITIVE_TOPOLOGY,
|
|
||||||
) -> Result<()> {
|
|
||||||
unsafe {
|
|
||||||
device_context.VSSetShaderResources(1, Some(&pipeline.view));
|
|
||||||
device_context.PSSetShaderResources(1, Some(&pipeline.view));
|
|
||||||
device_context.IASetPrimitiveTopology(topology);
|
|
||||||
device_context.RSSetViewports(Some(viewport));
|
|
||||||
device_context.VSSetShader(&pipeline.vertex, None);
|
|
||||||
device_context.PSSetShader(&pipeline.fragment, None);
|
|
||||||
device_context.VSSetConstantBuffers(0, Some(global_params));
|
|
||||||
device_context.PSSetConstantBuffers(0, Some(global_params));
|
|
||||||
const STRIDE: u32 = std::mem::size_of::<PathVertex<ScaledPixels>>() as u32;
|
|
||||||
device_context.IASetVertexBuffers(
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
Some(&pipeline.vertex_buffer),
|
|
||||||
Some(&STRIDE),
|
|
||||||
Some(&0),
|
|
||||||
);
|
|
||||||
device_context.IASetInputLayout(&pipeline.input_layout);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw_indirect(
|
|
||||||
device_context: &ID3D11DeviceContext,
|
|
||||||
indirect_draw_buffer: &ID3D11Buffer,
|
|
||||||
offset: u32,
|
|
||||||
) {
|
|
||||||
unsafe {
|
|
||||||
device_context.DrawInstancedIndirect(indirect_draw_buffer, offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const BUFFER_COUNT: usize = 3;
|
const BUFFER_COUNT: usize = 3;
|
||||||
|
|
||||||
mod shader_resources {
|
mod shader_resources {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue