This commit is contained in:
Junkui Zhang 2025-07-14 16:47:45 +08:00
parent 9c3cfca835
commit fda3d56d87

View file

@ -48,8 +48,7 @@ struct DirectXContext {
struct DirectXRenderPipelines {
shadow_pipeline: PipelineState,
quad_pipeline: PipelineState,
paths_pipeline: PipelineState,
paths_indirect_draw_buffer: ID3D11Buffer,
paths_pipeline: PathsPipelineState,
underline_pipeline: PipelineState,
mono_sprites: PipelineState,
poly_sprites: PipelineState,
@ -309,21 +308,37 @@ impl DirectXRenderer {
});
}
update_buffer_capacity(
update_paths_buffer_capacity(
&self.pipelines.paths_pipeline,
std::mem::size_of::<PathSprite>(),
sprites.len(),
&self.devices.device,
)
.map(|input| update_pipeline(&mut self.pipelines.paths_pipeline, input));
.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_indirect_buffer(
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_indirect_draw_buffer,
&self.pipelines.paths_pipeline.vertex_buffer,
&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(
@ -337,7 +352,7 @@ impl DirectXRenderer {
for i in 0..paths.len() {
draw_indirect(
&self.devices.device_context,
&self.pipelines.paths_indirect_draw_buffer,
&self.pipelines.paths_pipeline.indirect_draw_buffer,
(i * std::mem::size_of::<DrawInstancedIndirectArgs>()) as u32,
);
}
@ -488,13 +503,14 @@ impl DirectXRenderPipelines {
std::mem::size_of::<Quad>(),
32,
)?;
let paths_pipeline = create_pipieline(
device,
"paths_vertex",
"paths_fragment",
std::mem::size_of::<PathSprite>(),
32,
)?;
// let paths_pipeline = create_pipieline(
// device,
// "paths_vertex",
// "paths_fragment",
// std::mem::size_of::<PathSprite>(),
// 32,
// )?;
let paths_pipeline = PathsPipelineState::new(device)?;
let underline_pipeline = create_pipieline(
device,
"underline_vertex",
@ -516,13 +532,11 @@ impl DirectXRenderPipelines {
std::mem::size_of::<PolychromeSprite>(),
32,
)?;
let paths_indirect_draw_buffer = create_indirect_draw_buffer(device, 32)?;
Ok(Self {
shadow_pipeline,
quad_pipeline,
paths_pipeline,
paths_indirect_draw_buffer,
underline_pipeline,
mono_sprites,
poly_sprites,
@ -614,6 +628,62 @@ struct PipelineState {
view: [Option<ID3D11ShaderResourceView>; 1],
}
struct PathsPipelineState {
vertex: ID3D11VertexShader,
fragment: ID3D11PixelShader,
buffer: ID3D11Buffer,
buffer_size: usize,
vertex_buffer: ID3D11Buffer,
vertex_buffer_size: usize,
indirect_draw_buffer: ID3D11Buffer,
indirect_buffer_size: usize,
view: [Option<ID3D11ShaderResourceView>; 1],
vertex_view: [Option<ID3D11ShaderResourceView>; 1],
}
impl PathsPipelineState {
fn new(device: &ID3D11Device) -> Result<Self> {
let vertex = {
let shader_blob = shader_resources::build_shader_blob("paths_vertex", "vs_5_0")?;
let bytes = unsafe {
std::slice::from_raw_parts(
shader_blob.GetBufferPointer() as *mut u8,
shader_blob.GetBufferSize(),
)
};
create_vertex_shader(device, bytes)?
};
let fragment = {
let shader_blob = shader_resources::build_shader_blob("paths_fragment", "ps_5_0")?;
let bytes = unsafe {
std::slice::from_raw_parts(
shader_blob.GetBufferPointer() as *mut u8,
shader_blob.GetBufferSize(),
)
};
create_fragment_shader(device, bytes)?
};
let buffer = create_buffer(device, std::mem::size_of::<PathSprite>(), 32)?;
let view = create_buffer_view(device, &buffer)?;
let vertex_buffer =
create_buffer(device, std::mem::size_of::<PathVertex<ScaledPixels>>(), 32)?;
let vertex_view = create_buffer_view(device, &vertex_buffer)?;
let indirect_draw_buffer = create_indirect_draw_buffer(device, 32)?;
Ok(Self {
vertex,
fragment,
buffer,
buffer_size: 32,
vertex_buffer,
vertex_buffer_size: 32,
indirect_draw_buffer,
indirect_buffer_size: 32,
view,
vertex_view,
})
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[repr(C)]
struct PathSprite {
@ -996,6 +1066,67 @@ fn update_buffer_capacity(
Some((buffer, buffer_size, view))
}
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;
}
println!(
"Paths buffer too small: {} < {}",
pipeline.buffer_size, data_size
);
let buffer_size = data_size.next_power_of_two();
println!("Paths New size: {}", buffer_size);
let buffer = create_buffer(device, std::mem::align_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, [Option<ID3D11ShaderResourceView>; 1])> {
if pipeline.vertex_buffer_size >= vertex_size {
return None;
}
println!(
"Paths vertex buffer too small: {} < {}",
pipeline.vertex_buffer_size, vertex_size
);
let vertex_size = vertex_size.next_power_of_two();
println!("Paths vertex New size: {}", vertex_size);
let buffer = create_buffer(
device,
std::mem::size_of::<PathVertex<ScaledPixels>>(),
vertex_size,
)
.unwrap();
let view = create_buffer_view(device, &buffer).unwrap();
Some((buffer, vertex_size, view))
}
fn update_indirect_buffer_capacity(
pipeline: &PathsPipelineState,
data_size: usize,
device: &ID3D11Device,
) -> Option<(ID3D11Buffer, usize)> {
if pipeline.indirect_buffer_size >= data_size {
return None;
}
println!(
"Indirect buffer too small: {} < {}",
pipeline.indirect_buffer_size, data_size
);
let buffer_size = data_size.next_power_of_two();
println!("Indirect New size: {}", buffer_size);
let buffer = create_indirect_draw_buffer(device, data_size as u32).unwrap();
Some((buffer, buffer_size))
}
fn update_pipeline(
pipeline: &mut PipelineState,
input: (ID3D11Buffer, usize, [Option<ID3D11ShaderResourceView>; 1]),
@ -1005,6 +1136,29 @@ fn update_pipeline(
pipeline.view = input.2;
}
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, [Option<ID3D11ShaderResourceView>; 1]),
) {
pipeline.vertex_buffer = input.0;
pipeline.vertex_buffer_size = input.1;
pipeline.vertex_view = input.2;
}
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,
@ -1035,14 +1189,15 @@ fn update_indirect_buffer(
fn prepare_indirect_draws(
device_context: &ID3D11DeviceContext,
pipeline: &PipelineState,
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.VSSetShaderResources(1, Some(&pipeline.vertex_view));
device_context.VSSetShaderResources(2, Some(&pipeline.view));
device_context.PSSetShaderResources(2, Some(&pipeline.view));
device_context.IASetPrimitiveTopology(topology);
device_context.RSSetViewports(Some(viewport));
device_context.VSSetShader(&pipeline.vertex, None);