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,
|
||||
sprites.len(),
|
||||
self.pipelines.paths_pipeline.update_buffer(
|
||||
&self.devices.device,
|
||||
)
|
||||
.map(|input| update_paths_pipeline_buffer(&mut self.pipelines.paths_pipeline, input));
|
||||
update_buffer(
|
||||
&self.devices.device_context,
|
||||
&self.pipelines.paths_pipeline.buffer,
|
||||
&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,
|
||||
)?;
|
||||
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,
|
||||
)?;
|
||||
prepare_indirect_draws(
|
||||
self.pipelines.paths_pipeline.draw(
|
||||
&self.devices.device_context,
|
||||
&self.pipelines.paths_pipeline,
|
||||
paths.len(),
|
||||
&self.context.viewport,
|
||||
&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<()> {
|
||||
|
@ -634,18 +594,19 @@ impl<T> PipelineState<T> {
|
|||
) -> Result<()> {
|
||||
if self.buffer_size < data.len() {
|
||||
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 view = create_buffer_view(device, &buffer)?;
|
||||
self.buffer = buffer;
|
||||
self.view = view;
|
||||
self.buffer_size = new_buffer_size;
|
||||
}
|
||||
unsafe {
|
||||
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(())
|
||||
update_buffer(device_context, &self.buffer, data)
|
||||
}
|
||||
|
||||
fn draw(
|
||||
|
@ -784,6 +745,101 @@ impl PathsPipelineState {
|
|||
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)]
|
||||
|
@ -1048,21 +1104,6 @@ fn create_indirect_draw_buffer(device: &ID3D11Device, buffer_size: usize) -> Res
|
|||
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(
|
||||
device_context: &ID3D11DeviceContext,
|
||||
global_params_buffer: &[Option<ID3D11Buffer>; 1],
|
||||
|
@ -1071,13 +1112,14 @@ fn pre_draw(
|
|||
clear_color: [f32; 4],
|
||||
blend_state: &ID3D11BlendState,
|
||||
) -> Result<()> {
|
||||
update_global_params(
|
||||
let global_params = global_params_buffer[0].as_ref().unwrap();
|
||||
update_buffer(
|
||||
device_context,
|
||||
global_params_buffer,
|
||||
GlobalParams {
|
||||
global_params,
|
||||
&[GlobalParams {
|
||||
viewport_size: [view_port[0].Width, view_port[0].Height],
|
||||
..Default::default()
|
||||
},
|
||||
}],
|
||||
)?;
|
||||
unsafe {
|
||||
device_context.RSSetViewports(Some(view_port));
|
||||
|
@ -1088,70 +1130,6 @@ fn pre_draw(
|
|||
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>(
|
||||
device_context: &ID3D11DeviceContext,
|
||||
buffer: &ID3D11Buffer,
|
||||
|
@ -1166,45 +1144,6 @@ fn update_buffer<T>(
|
|||
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;
|
||||
|
||||
mod shader_resources {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue