Skip to content

Commit 58884b1

Browse files
author
GBDixonAlex
committed
- raytracing scene example working with some traced output, some d3d warnings to fix and features still to add
1 parent 1b552fc commit 58884b1

File tree

11 files changed

+111
-88
lines changed

11 files changed

+111
-88
lines changed

plugins/ecs_examples/src/draw_cbuffer_instanced.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ pub fn setup_draw_cbuffer_instanced(
5353
for mesh in meshes {
5454
let mut heap = device.create_heap(&gfx::HeapInfo {
5555
heap_type: gfx::HeapType::Shader,
56-
num_descriptors: instance_count as usize
56+
num_descriptors: instance_count as usize,
57+
debug_name: Some("instance_buffer_heap".to_string())
5758
});
5859
let parent = commands.spawn(InstanceBatch {
5960
mesh: MeshComponent(mesh.clone()),

plugins/ecs_examples/src/dynamic_cubemap.rs

-3
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,11 @@ pub fn render_orbit_meshes(
113113

114114
view.cmd_buf.set_heap(pipeline, &pmfx.shader_heap);
115115

116-
let mut mip = 0;
117116
for (world_matrix, mesh) in &mesh_draw_query {
118117
view.cmd_buf.push_render_constants(1, 12, 0, &world_matrix.0);
119118
view.cmd_buf.set_index_buffer(&mesh.0.ib);
120119
view.cmd_buf.set_vertex_buffer(&mesh.0.vb, 0);
121120
view.cmd_buf.draw_indexed_instanced(mesh.0.num_indices, 1, 0, 0, 0);
122-
123-
mip += 1;
124121
}
125122

126123
Ok(())

plugins/ecs_examples/src/raytraced_shadows.rs

+40-26
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// currently windows only because here we need a concrete gfx and os implementation
22
#![cfg(target_os = "windows")]
33

4+
use hotline_rs::gfx::RaytracingTLAS;
5+
46
///
57
/// Raytraced Shadows
68
///
@@ -43,9 +45,9 @@ pub fn blas_from_mesh(device: &mut ResMut<DeviceRes>, mesh: &pmfx::Mesh<gfx_plat
4345
index_buffer: &mesh.ib,
4446
vertex_buffer: &mesh.vb,
4547
transform3x4: None,
46-
index_count: 3,
48+
index_count: mesh.num_indices as usize,
4749
index_format: gfx::Format::R16u,
48-
vertex_count: 3,
50+
vertex_count: mesh.num_indices as usize,
4951
vertex_format: gfx::Format::RGB32f,
5052
vertex_stride: 56
5153
}),
@@ -186,11 +188,11 @@ pub fn setup_raytraced_shadows_scene(
186188
blas_from_mesh(&mut device, &cube_mesh)?
187189
));
188190

189-
commands.spawn((
191+
commands.spawn(
190192
TLAS {
191193
tlas: None
192194
}
193-
));
195+
);
194196

195197
//
196198

@@ -250,8 +252,16 @@ pub fn animate_lights (
250252
Ok(())
251253
}
252254

255+
// TODO_RT
256+
// create tlas with heap?
257+
// update tlas
258+
// mesh vertex count
259+
// fix: Ignoring InitialState D3D12_RESOURCE_STATE_COPY_DEST. Buffers are effectively created in state D3D12_RESOURCE_STATE_COMMON.
260+
// colors from rust compile output?
261+
253262
#[export_compute_fn]
254-
pub fn render_meshes_raytraced(
263+
pub fn render_meshes_raytraced(
264+
device: ResMut<DeviceRes>,
255265
pmfx: &Res<PmfxRes>,
256266
pass: &pmfx::ComputePass<gfx_platform::Device>,
257267
tlas_query: Query<&TLAS>
@@ -262,35 +272,39 @@ pub fn render_meshes_raytraced(
262272
let output_size = pmfx.get_texture_2d_size("staging_output").expect("expected staging_output");
263273
let output_tex = pmfx.get_texture("staging_output").expect("expected staging_output");
264274

265-
let cam = pmfx.get_camera_constants("main_camera");
266-
if let Ok(cam) = cam {
275+
let camera = pmfx.get_camera_constants("main_camera");
276+
if let Ok(camera) = camera {
267277
for t in &tlas_query {
268278
if let Some(tlas) = &t.tlas {
269279

270280
// set pipeline
271-
let rt_pipeline = pmfx.get_raytracing_pipeline(&pass.pass_pipline)?;
272-
pass.cmd_buf.set_raytracing_pipeline(&rt_pipeline.pipeline);
273-
274-
// camera constants TODO:
275-
276-
// resource use constants
277-
let using_slot = rt_pipeline.pipeline.get_pipeline_slot(0, 1, gfx::DescriptorType::PushConstants);
278-
if let Some(slot) = using_slot {
279-
for i in 0..pass.use_indices.len() {
280-
let num_constants = gfx::num_32bit_constants(&pass.use_indices[i]);
281-
pass.cmd_buf.push_compute_constants(
282-
slot.index,
283-
num_constants,
284-
i as u32 * num_constants,
285-
gfx::as_u8_slice(&pass.use_indices[i])
286-
);
287-
}
281+
let raytracing_pipeline = pmfx.get_raytracing_pipeline(&pass.pass_pipline)?;
282+
pass.cmd_buf.set_raytracing_pipeline(&raytracing_pipeline.pipeline);
283+
284+
285+
let slot = raytracing_pipeline.pipeline.get_pipeline_slot(0, 0, gfx::DescriptorType::PushConstants);
286+
if let Some(slot) = slot {
287+
// camera constants
288+
let inv = camera.view_projection_matrix.inverse();
289+
pass.cmd_buf.push_compute_constants(slot.index, 16, 0, &inv);
290+
291+
// output uav
292+
pass.cmd_buf.push_compute_constants(slot.index, 4, 16, gfx::as_u8_slice(&pass.use_indices[0].index));
288293
}
289294

290-
pass.cmd_buf.set_heap(&rt_pipeline.pipeline, &pmfx.shader_heap);
295+
// bind shader heap
296+
if let Some(u0) = raytracing_pipeline.pipeline.get_pipeline_slot(0, 0, gfx::DescriptorType::UnorderedAccess) {
297+
pass.cmd_buf.set_binding(&raytracing_pipeline.pipeline, &pmfx.shader_heap, u0.index, 0);
298+
}
299+
300+
// bind tlas on t1 (device heap)
301+
let srv0 = tlas.get_srv_index().expect("expect tlas to have an srv");
302+
if let Some(t0) = raytracing_pipeline.pipeline.get_pipeline_slot(69, 0, gfx::DescriptorType::ShaderResource) {
303+
pass.cmd_buf.set_binding(&raytracing_pipeline.pipeline, device.get_shader_heap(), t0.index, srv0);
304+
}
291305

292306
// dispatch
293-
pass.cmd_buf.dispatch_rays(&rt_pipeline.sbt, gfx::Size3 {
307+
pass.cmd_buf.dispatch_rays(&raytracing_pipeline.sbt, gfx::Size3 {
294308
x: output_size.0 as u32,
295309
y: output_size.1 as u32,
296310
z: 1

plugins/export_macros/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ pub fn export_update_fn(attr: TokenStream, item: TokenStream) -> TokenStream {
132132
{} ({}).unwrap();
133133
}}).into_configs().{}
134134
}}", parsed.name, moves, parsed.name, pass, order);
135-
let export_tokens : TokenStream = export_fn.parse().unwrap();
136135

137136
let input = parse_macro_input!(item as ItemFn);
138137
let export_tokens : TokenStream = export_fn.parse().unwrap();

shaders/ecs.hlsl

+2-2
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ StructuredBuffer<spot_light_data> spot_lights[] : register(t0, space4);
137137
StructuredBuffer<directional_light_data> directional_lights[] : register(t0, space5);
138138
StructuredBuffer<float4x4> shadow_matrices[] : register(t0, space6);
139139

140-
//
141-
RaytracingAccelerationStructure scene_tlas : register(t1, space0);
140+
// TODO_RT
141+
RaytracingAccelerationStructure scene_tlas : register(t69, space0);
142142

143143
// textures
144144
Texture2D textures[] : register(t0, space7);

shaders/material.hlsl

+31-47
Original file line numberDiff line numberDiff line change
@@ -297,69 +297,53 @@ bool is_occluded(float3 origin, float3 direction, float tMin, float tMax)
297297

298298
struct RayPayload
299299
{
300-
float4 color;
300+
float4 colour;
301+
};
302+
303+
cbuffer ray_tracing_constants : register(b0) {
304+
float4x4 inverse_wvp;
305+
int4 output_uav_index;
301306
};
302307

303308
[shader("raygeneration")]
304309
void scene_raygen_shader()
305310
{
306-
float2 lerp_values = (float2)DispatchRaysIndex() / (float2)DispatchRaysDimensions();
307-
308-
/*
309-
// Orthographic projection since we're raytracing in screen space.
310-
float3 ray_dir = float3(0.0, 0.0, 1.0);
311-
float3 origin = float3(
312-
lerp(
313-
raygen_constants.viewport.left,
314-
raygen_constants.viewport.right,
315-
lerp_values.x
316-
),
317-
lerp(
318-
raygen_constants.viewport.top,
319-
raygen_constants.viewport.bottom,
320-
lerp_values.y
321-
),
322-
0.0f
323-
);
311+
//uv and ndc from dispatch dim
312+
float2 uv = (float2)DispatchRaysIndex() / (float2)DispatchRaysDimensions();
313+
float2 ndc = uv * 2.0 - 1.0;
324314

315+
// unproject ray
316+
float4 near = float4(ndc.x, ndc.y, 0.0, 1.0);
317+
float4 far = float4(ndc.x, ndc.y, 1.0, 1.0);
318+
319+
float4 wnear = mul(inverse_wvp, near);
320+
wnear /= wnear.w;
321+
322+
float4 wfar = mul(inverse_wvp, far);
323+
wfar /= wfar.w;
325324

326-
if (inside_viewport(origin.xy, raygen_constants.stencil))
327-
{
328-
// Trace the ray.
329-
// Set the ray's extents.
330-
RayDesc ray;
331-
ray.Origin = origin;
332-
ray.Direction = ray_dir;
333-
334-
// Set TMin to a non-zero small value to avoid aliasing issues due to floating - point errors.
335-
// TMin should be kept small to prevent missing geometry at close contact areas.
336-
ray.TMin = 0.001;
337-
ray.TMax = 10000.0;
338-
RayPayload payload = { float4(0.0, 0.0, 1.0, 0.0) };
339-
TraceRay(scene, RAY_FLAG_NONE, ~0, 0.0, 1.0, 0.0, ray, payload);
340-
341-
// Write the raytraced color to the output texture.
342-
output_target[DispatchRaysIndex().xy] = payload.color;
343-
}
344-
else
345-
{
346-
// Render interpolated DispatchRaysIndex outside the stencil window
347-
output_target[DispatchRaysIndex().xy] = float4(lerp_values, 1.0, 1.0);
348-
}
349-
*/
350-
351-
rw_textures[resources.input0.index][DispatchRaysIndex().xy] = float4(lerp_values, 1.0, 1.0);
325+
// ray desc
326+
RayDesc ray;
327+
ray.Origin = wnear.xyz;
328+
ray.Direction = normalize(wfar.xyz - wnear.xyz);
329+
ray.TMin = 0.001;
330+
ray.TMax = 10000.0;
331+
332+
RayPayload payload = { float4(0.0, 0.0, 1.0, 0.0) };
333+
TraceRay(scene_tlas, RAY_FLAG_NONE, ~0, 0.0, 1.0, 0.0, ray, payload);
334+
335+
rw_textures[output_uav_index.x][DispatchRaysIndex().xy] = payload.colour;
352336
}
353337

354338
[shader("closesthit")]
355339
void scene_closest_hit_shader(inout RayPayload payload, in BuiltInTriangleIntersectionAttributes attr)
356340
{
357341
float3 barycentrics = float3(1 - attr.barycentrics.x - attr.barycentrics.y, attr.barycentrics.x, attr.barycentrics.y);
358-
payload.color = float4(float3(1.0, 1.0, 1.0) - barycentrics, 1.0);
342+
payload.colour = float4(float3(1.0, 1.0, 1.0) - barycentrics, 1.0);
359343
}
360344

361345
[shader("miss")]
362346
void scene_miss_shader(inout RayPayload payload)
363347
{
364-
payload.color = float4(0.5, 0.5, 0.5, 1.0);
348+
payload.colour = float4(0.5, 0.5, 0.5, 1.0);
365349
}

shaders/material.jsn

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
hit_groups: ["hit_group"],
7272
}
7373
push_constants: [
74-
resources
74+
ray_tracing_constants
7575
]
7676
}
7777
mesh_pbr_ibl: {

src/gfx.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ pub struct HeapInfo {
169169
pub heap_type: HeapType,
170170
/// Total size of the heap in number of resources.
171171
pub num_descriptors: usize,
172+
/// Optional debug name
173+
pub debug_name: Option<String>
172174
}
173175

174176
/// Options for heap types.
@@ -1258,6 +1260,14 @@ pub trait Device: 'static + Send + Sync + Sized + Any + Clone {
12581260
&mut self,
12591261
info: &RaytracingBLASInfo<Self>
12601262
) -> Result<Self::RaytracingBLAS, Error>;
1263+
/*
1264+
/// Create a top level acceleration structure from array of `RaytracingInstanceInfo` with specificed heap
1265+
fn create_raytracing_tlas_with_heap(
1266+
&mut self,
1267+
info: &RaytracingTLASInfo<Self>,
1268+
heap: &mut Self::Heap
1269+
) -> Result<Self::RaytracingTLAS, Error>;
1270+
*/
12611271
/// Create a top level acceleration structure from array of `RaytracingInstanceInfo`
12621272
fn create_raytracing_tlas(
12631273
&mut self,
@@ -1392,9 +1402,9 @@ pub trait CmdBuf<D: Device>: Send + Sync + Clone {
13921402
fn set_binding<T: Pipeline>(&self, pipeline: &T, heap: &D::Heap, slot: u32, offset: usize);
13931403
// TODO:
13941404
fn set_tlas(&self, tlas: &D::RaytracingTLAS);
1395-
/// Push a small amount of data into the command buffer for a render pipeline, num values and dest offset are the numbr of 32bit values
1405+
/// Push a small amount of data into the command buffer for a render pipeline, num values and dest offset are the number of 32bit values
13961406
fn push_render_constants<T: Sized>(&self, slot: u32, num_values: u32, dest_offset: u32, data: &[T]);
1397-
/// Push a small amount of data into the command buffer for a compute pipeline, num values and dest offset are the numbr of 32bit values
1407+
/// Push a small amount of data into the command buffer for a compute pipeline, num values and dest offset are the number of 32bit values
13981408
fn push_compute_constants<T: Sized>(&self, slot: u32, num_values: u32, dest_offset: u32, data: &[T]);
13991409
/// Make a non-indexed draw call supplying vertex and instance counts
14001410
fn draw_instanced(

src/gfx/d3d12.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -1806,10 +1806,10 @@ impl super::Device for Device {
18061806
&HeapInfo {
18071807
heap_type: super::HeapType::Shader,
18081808
num_descriptors: info.shader_heap_size,
1809+
debug_name: Some("device_shader_heap".to_string())
18091810
},
18101811
heap_id
18111812
);
1812-
d3d12_debug_name!(shader_heap.heap, "device_shader_heap");
18131813

18141814
// rtv
18151815
heap_id += 1;
@@ -1818,10 +1818,10 @@ impl super::Device for Device {
18181818
&HeapInfo {
18191819
heap_type: super::HeapType::RenderTarget,
18201820
num_descriptors: info.render_target_heap_size,
1821+
debug_name: Some("device_render_target_heap".to_string())
18211822
},
18221823
heap_id
18231824
);
1824-
d3d12_debug_name!(rtv_heap.heap, "device_render_target_heap");
18251825

18261826
// dsv
18271827
heap_id += 1;
@@ -1830,10 +1830,10 @@ impl super::Device for Device {
18301830
&HeapInfo {
18311831
heap_type: super::HeapType::DepthStencil,
18321832
num_descriptors: info.depth_stencil_heap_size,
1833+
debug_name: Some("device_depth_stencil_heap".to_string())
18331834
},
18341835
heap_id
18351836
);
1836-
d3d12_debug_name!(dsv_heap.heap, "device_depth_stencil_heap");
18371837

18381838
// query feature flags
18391839
let mut feature_flags = DeviceFeatureFlags::NONE;
@@ -1889,7 +1889,13 @@ impl super::Device for Device {
18891889

18901890
fn create_heap(&mut self, info: &HeapInfo) -> Heap {
18911891
self.heap_id += 1; // bump heap id
1892-
create_heap(&self.device, info, self.heap_id)
1892+
let heap = create_heap(&self.device, info, self.heap_id);
1893+
if let Some(debug_name) = &info.debug_name {
1894+
unsafe {
1895+
d3d12_debug_name!(heap.heap, debug_name);
1896+
}
1897+
}
1898+
heap
18931899
}
18941900

18951901
fn create_query_heap(&self, info: &QueryHeapInfo) -> QueryHeap {

src/plugin.rs

+11
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,17 @@ impl reloader::ReloadResponder for PluginReloadResponder {
9999
.expect("hotline::hot_lib:: hot lib failed to build!")
100100
}
101101
else {
102+
/*
103+
let hotline_path = super::get_data_path("../..");
104+
let pmbuild = super::get_data_path("../../hotline-data/pmbuild.cmd");
105+
std::process::Command::new(pmbuild)
106+
.current_dir(hotline_path)
107+
.arg("win32-debug")
108+
.arg("-plugins")
109+
.output()
110+
.expect("hotline::hot_lib:: hot pmfx failed to compile!")
111+
*/
112+
102113
Command::new("cargo")
103114
.current_dir(&self.path)
104115
.arg("build")

src/pmfx.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ struct RaytracingShaderBindingTableInfo {
351351
}
352352

353353
#[derive(Clone)]
354-
enum PipelineType {
354+
pub enum PipelineType {
355355
None,
356356
Render,
357357
Compute,
@@ -983,6 +983,7 @@ impl<D> Pmfx<D> where D: gfx::Device {
983983
let shader_heap = device.create_heap(&gfx::HeapInfo {
984984
heap_type: gfx::HeapType::Shader,
985985
num_descriptors: shader_heap_size,
986+
debug_name: Some("pmfx_shader_heap".to_string())
986987
});
987988
Pmfx {
988989
pmfx: File::new(),

0 commit comments

Comments
 (0)