Skip to content

Commit

Permalink
changed draw_instances to accept element_range + run_pass
Browse files Browse the repository at this point in the history
- `run_pass` accepts number of instances to be drawn
  • Loading branch information
mrDIMAS committed Feb 20, 2025
1 parent f408734 commit 3c8c9b0
Show file tree
Hide file tree
Showing 14 changed files with 97 additions and 35 deletions.
5 changes: 3 additions & 2 deletions fyrox-graphics/src/framebuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,14 @@ pub trait GpuFrameBufferTrait: Downcast {
/// could be supplied in vertex attributes, uniform buffers, textures, etc.
fn draw_instances(
&self,
count: usize,
instance_count: usize,
geometry: &GpuGeometryBuffer,
viewport: Rect<i32>,
program: &GpuProgram,
params: &DrawParameters,
resources: &[ResourceBindGroup],
) -> DrawCallStatistics;
element_range: ElementRange,
) -> Result<DrawCallStatistics, FrameworkError>;
}

define_shared_wrapper!(GpuFrameBuffer<dyn GpuFrameBufferTrait>);
67 changes: 44 additions & 23 deletions fyrox-graphics/src/gl/framebuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,23 +379,23 @@ impl GpuFrameBufferTrait for GlFrameBuffer {

pre_draw(self.id(), &server, viewport, program, params, resources);

let (offset, count) = match element_range {
let (offset, element_count) = match element_range {
ElementRange::Full => (0, geometry.element_count.get()),
ElementRange::Specific { offset, count } => (offset, count),
};

let last_triangle_index = offset + count;
let last_element_index = offset + element_count;

if last_triangle_index > geometry.element_count.get() {
if last_element_index > geometry.element_count.get() {
Err(FrameworkError::InvalidElementRange {
start: offset,
end: last_triangle_index,
end: last_element_index,
total: geometry.element_count.get(),
})
} else {
let index_per_element = geometry.element_kind.index_per_element();
let start_index = offset * index_per_element;
let index_count = count * index_per_element;
let index_count = element_count * index_per_element;

unsafe {
if index_count > 0 {
Expand All @@ -411,19 +411,22 @@ impl GpuFrameBufferTrait for GlFrameBuffer {
}
}

Ok(DrawCallStatistics { triangles: count })
Ok(DrawCallStatistics {
triangles: element_count,
})
}
}

fn draw_instances(
&self,
count: usize,
instance_count: usize,
geometry: &GpuGeometryBuffer,
viewport: Rect<i32>,
program: &GpuProgram,
params: &DrawParameters,
resources: &[ResourceBindGroup],
) -> DrawCallStatistics {
element_range: ElementRange,
) -> Result<DrawCallStatistics, FrameworkError> {
let server = self.state.upgrade().unwrap();
let geometry = geometry
.as_any()
Expand All @@ -432,23 +435,41 @@ impl GpuFrameBufferTrait for GlFrameBuffer {

pre_draw(self.id(), &server, viewport, program, params, resources);

let index_per_element = geometry.element_kind.index_per_element();
let index_count = geometry.element_count.get() * index_per_element;
if index_count > 0 {
let (offset, element_count) = match element_range {
ElementRange::Full => (0, geometry.element_count.get()),
ElementRange::Specific { offset, count } => (offset, count),
};

let last_element_index = offset + element_count;

if last_element_index > geometry.element_count.get() {
Err(FrameworkError::InvalidElementRange {
start: offset,
end: last_element_index,
total: geometry.element_count.get(),
})
} else {
let index_per_element = geometry.element_kind.index_per_element();
let start_index = offset * index_per_element;
let index_count = geometry.element_count.get() * index_per_element;

unsafe {
server.set_vertex_array_object(Some(geometry.vertex_array_object));

server.gl.draw_elements_instanced(
geometry.mode(),
index_count as i32,
glow::UNSIGNED_INT,
0,
count as i32,
)
if index_count > 0 {
server.set_vertex_array_object(Some(geometry.vertex_array_object));
let indices = (start_index * size_of::<u32>()) as i32;
server.gl.draw_elements_instanced(
geometry.mode(),
index_count as i32,
glow::UNSIGNED_INT,
indices,
instance_count as i32,
)
}
}
}
DrawCallStatistics {
triangles: geometry.element_count.get() * count,

Ok(DrawCallStatistics {
triangles: geometry.element_count.get() * instance_count,
})
}
}
}
Expand Down
1 change: 1 addition & 0 deletions fyrox-impl/src/renderer/bloom/blur.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ impl GaussianBlur {
RenderMaterial::from([binding("image", image), binding("properties", &properties)]);

stats += self.shader.run_pass(
1,
&ImmutableString::new("Primary"),
framebuffer,
quad,
Expand Down
1 change: 1 addition & 0 deletions fyrox-impl/src/renderer/bloom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ impl BloomRenderer {
]);

stats += self.shader.run_pass(
1,
&ImmutableString::new("Primary"),
&self.framebuffer,
quad,
Expand Down
39 changes: 29 additions & 10 deletions fyrox-impl/src/renderer/cache/shader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ impl RenderPassContainer {

pub fn run_pass<const N: usize>(
&self,
instance_count: usize,
render_pass_name: &ImmutableString,
framebuffer: &GpuFrameBuffer,
geometry: &GpuGeometryBuffer,
Expand All @@ -257,6 +258,10 @@ impl RenderPassContainer {
element_range: ElementRange,
override_params: Option<&DrawParameters>,
) -> Result<DrawCallStatistics, FrameworkError> {
if instance_count == 0 {
return Ok(Default::default());
}

let render_pass = self.get(render_pass_name)?;

let mut resource_bindings = ArrayVec::<ResourceBinding, 32>::new();
Expand Down Expand Up @@ -328,16 +333,30 @@ impl RenderPassContainer {
}
}

framebuffer.draw(
geometry,
viewport,
&render_pass.program,
override_params.unwrap_or(&render_pass.draw_params),
&[ResourceBindGroup {
bindings: &resource_bindings,
}],
element_range,
)
let resources = [ResourceBindGroup {
bindings: &resource_bindings,
}];

if instance_count == 1 {
framebuffer.draw(
geometry,
viewport,
&render_pass.program,
override_params.unwrap_or(&render_pass.draw_params),
&resources,
element_range,
)
} else {
framebuffer.draw_instances(
instance_count,
geometry,
viewport,
&render_pass.program,
override_params.unwrap_or(&render_pass.draw_params),
&resources,
element_range,
)
}
}
}

Expand Down
1 change: 1 addition & 0 deletions fyrox-impl/src/renderer/debug_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ impl DebugRenderer {
let material = RenderMaterial::from([binding("properties", &properties)]);

statistics += self.shader.run_pass(
1,
&ImmutableString::new("Primary"),
framebuffer,
&self.geometry,
Expand Down
1 change: 1 addition & 0 deletions fyrox-impl/src/renderer/fxaa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ impl FxaaRenderer {
]);

statistics += self.shader.run_pass(
1,
&ImmutableString::new("Primary"),
frame_buffer,
&self.quad,
Expand Down
1 change: 1 addition & 0 deletions fyrox-impl/src/renderer/gbuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ impl GBuffer {
]);

statistics += self.decal_shader.run_pass(
1,
&ImmutableString::new("Primary"),
&self.decal_framebuffer,
unit_cube,
Expand Down
7 changes: 7 additions & 0 deletions fyrox-impl/src/renderer/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ impl DeferredLightRenderer {
]);

pass_stats += self.skybox_shader.run_pass(
1,
&ImmutableString::new("Primary"),
frame_buffer,
&self.skybox,
Expand Down Expand Up @@ -393,6 +394,7 @@ impl DeferredLightRenderer {
]);

pass_stats += self.ambient_light_shader.run_pass(
1,
&ImmutableString::new("Primary"),
frame_buffer,
&self.quad,
Expand Down Expand Up @@ -533,6 +535,7 @@ impl DeferredLightRenderer {
PropertyGroup::from([property("worldViewProjection", &shape_wvp_matrix)]);
let material = RenderMaterial::from([binding("properties", &properties)]);
pass_stats += self.volume_marker.run_pass(
1,
&ImmutableString::new("Primary"),
frame_buffer,
bounding_shape,
Expand Down Expand Up @@ -560,6 +563,7 @@ impl DeferredLightRenderer {
PropertyGroup::from([property("worldViewProjection", &frame_matrix)]);
let material = RenderMaterial::from([binding("properties", &properties)]);
pass_stats += self.pixel_counter.run_pass(
1,
&ImmutableString::new("Primary"),
frame_buffer,
&self.quad,
Expand Down Expand Up @@ -724,6 +728,7 @@ impl DeferredLightRenderer {
]);

self.spot_light_shader.run_pass(
1,
&ImmutableString::new("Primary"),
frame_buffer,
quad,
Expand Down Expand Up @@ -764,6 +769,7 @@ impl DeferredLightRenderer {
]);

self.point_light_shader.run_pass(
1,
&ImmutableString::new("Primary"),
frame_buffer,
quad,
Expand Down Expand Up @@ -818,6 +824,7 @@ impl DeferredLightRenderer {
]);

self.directional_light_shader.run_pass(
1,
&ImmutableString::new("Primary"),
frame_buffer,
quad,
Expand Down
4 changes: 4 additions & 0 deletions fyrox-impl/src/renderer/light_volume.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ impl LightVolumeRenderer {
let properties = PropertyGroup::from([property("worldViewProjection", &mvp)]);
let material = RenderMaterial::from([binding("properties", &properties)]);
stats += self.volume_marker.run_pass(
1,
&ImmutableString::new("Primary"),
frame_buffer,
&self.cone,
Expand Down Expand Up @@ -165,6 +166,7 @@ impl LightVolumeRenderer {
]);

stats += self.spot_light_shader.run_pass(
1,
&ImmutableString::new("Primary"),
frame_buffer,
quad,
Expand All @@ -189,6 +191,7 @@ impl LightVolumeRenderer {
let properties = PropertyGroup::from([property("worldViewProjection", &mvp)]);
let material = RenderMaterial::from([binding("properties", &properties)]);
stats += self.volume_marker.run_pass(
1,
&ImmutableString::new("Primary"),
frame_buffer,
&self.sphere,
Expand Down Expand Up @@ -217,6 +220,7 @@ impl LightVolumeRenderer {
]);

stats += self.point_light_shader.run_pass(
1,
&ImmutableString::new("Primary"),
frame_buffer,
quad,
Expand Down
1 change: 1 addition & 0 deletions fyrox-impl/src/renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,7 @@ fn blit_pixels(
binding("properties", &properties),
]);
blit_shader.run_pass(
1,
&ImmutableString::new("Primary"),
framebuffer,
quad,
Expand Down
1 change: 1 addition & 0 deletions fyrox-impl/src/renderer/ssao/blur.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ impl Blur {
]);

self.program.run_pass(
1,
&ImmutableString::new("Primary"),
&self.framebuffer,
&self.quad,
Expand Down
1 change: 1 addition & 0 deletions fyrox-impl/src/renderer/ssao/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ impl ScreenSpaceAmbientOcclusionRenderer {
]);

stats += self.program.run_pass(
1,
&ImmutableString::new("Primary"),
&self.framebuffer,
&self.quad,
Expand Down
2 changes: 2 additions & 0 deletions fyrox-impl/src/renderer/ui_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ impl UiRenderer {
let properties = PropertyGroup::from([property("worldViewProjection", &ortho)]);
let material = RenderMaterial::from([binding("properties", &properties)]);
statistics += self.render_passes.run_pass(
1,
&ImmutableString::new("Clip"),
frame_buffer,
&self.geometry_buffer,
Expand Down Expand Up @@ -359,6 +360,7 @@ impl UiRenderer {
]);

statistics += self.render_passes.run_pass(
1,
&ImmutableString::new("Primary"),
frame_buffer,
&self.geometry_buffer,
Expand Down

0 comments on commit 3c8c9b0

Please sign in to comment.