Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ray Tracing Pipeline (KHR) #2564

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions examples/triangle-util/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ vulkano-util = { workspace = true }
# The Vulkan library doesn't provide any functionality to create and handle windows, as
# this would be out of scope. In order to open a window, we are going to use the `winit` crate.
winit = { workspace = true, default-features = true }
ash = { workspace = true }
glam = { workspace = true }
10 changes: 10 additions & 0 deletions examples/triangle-util/raytrace.rchit
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#version 460
#extension GL_EXT_ray_tracing : require

layout(location = 0) rayPayloadInEXT vec3 hitValue;
hitAttributeEXT vec2 attribs;

void main() {
vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
hitValue = barycentrics;
}
43 changes: 43 additions & 0 deletions examples/triangle-util/raytrace.rgen
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#version 460
#extension GL_EXT_ray_tracing : require

struct Camera {
mat4 viewProj; // Camera view * projection
mat4 viewInverse; // Camera inverse view matrix
mat4 projInverse; // Camera inverse projection matrix
};

layout(location = 0) rayPayloadEXT vec3 hitValue;

layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;
layout(set = 0, binding = 1) uniform _Camera { Camera camera; };
layout(set = 1, binding = 0, rgba32f) uniform image2D image;

void main() {
const vec2 pixelCenter = vec2(gl_LaunchIDEXT.xy) + vec2(0.5);
const vec2 inUV = pixelCenter / vec2(gl_LaunchSizeEXT.xy);
vec2 d = inUV * 2.0 - 1.0;

vec4 origin = camera.viewInverse * vec4(0, 0, 0, 1);
vec4 target = camera.projInverse * vec4(d.x, d.y, 1, 1);
vec4 direction = camera.viewInverse * vec4(normalize(target.xyz), 0);

uint rayFlags = gl_RayFlagsOpaqueEXT;
float tMin = 0.001;
float tMax = 10000.0;

traceRayEXT(topLevelAS, // acceleration structure
rayFlags, // rayFlags
0xFF, // cullMask
0, // sbtRecordOffset
0, // sbtRecordStride
0, // missIndex
origin.xyz, // ray origin
tMin, // ray min range
direction.xyz, // ray direction
tMax, // ray max range
0 // payload (location = 0)
);

imageStore(image, ivec2(gl_LaunchIDEXT.xy), vec4(hitValue, 1.0));
}
6 changes: 6 additions & 0 deletions examples/triangle-util/raytrace.rmiss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#version 460
#extension GL_EXT_ray_tracing : require

layout(location = 0) rayPayloadInEXT vec3 hitValue;

void main() { hitValue = vec3(0.0, 0.0, 0.2); }
4 changes: 2 additions & 2 deletions vulkano/src/buffer/usage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,13 @@ vulkan_bitflags! {
RequiresAllOf([DeviceExtension(khr_acceleration_structure)]),
]),

/* TODO: enable

// TODO: document
SHADER_BINDING_TABLE = SHADER_BINDING_TABLE_KHR
RequiresOneOf([
RequiresAllOf([DeviceExtension(khr_ray_tracing_pipeline)]),
RequiresAllOf([DeviceExtension(nv_ray_tracing)]),
]),*/
]),

/* TODO: enable
// TODO: document
Expand Down
2 changes: 2 additions & 0 deletions vulkano/src/command_buffer/auto/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use crate::{
vertex_input::VertexInputState,
viewport::{Scissor, Viewport},
},
ray_tracing::RayTracingPipeline,
ComputePipeline, DynamicState, GraphicsPipeline, PipelineBindPoint, PipelineLayout,
},
query::{QueryControlFlags, QueryPool, QueryType},
Expand Down Expand Up @@ -1292,6 +1293,7 @@ pub(in crate::command_buffer) struct CommandBufferBuilderState {
pub(in crate::command_buffer) index_buffer: Option<IndexBuffer>,
pub(in crate::command_buffer) pipeline_compute: Option<Arc<ComputePipeline>>,
pub(in crate::command_buffer) pipeline_graphics: Option<Arc<GraphicsPipeline>>,
pub(in crate::command_buffer) pipeline_ray_tracing: Option<Arc<RayTracingPipeline>>,
pub(in crate::command_buffer) vertex_buffers: HashMap<u32, Subbuffer<[u8]>>,
pub(in crate::command_buffer) push_constants: RangeSet<u32>,
pub(in crate::command_buffer) push_constants_pipeline_layout: Option<Arc<PipelineLayout>>,
Expand Down
30 changes: 28 additions & 2 deletions vulkano/src/command_buffer/commands/bind_push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use crate::{
device::{DeviceOwned, QueueFlags},
memory::is_aligned,
pipeline::{
graphics::vertex_input::VertexBuffersCollection, ComputePipeline, GraphicsPipeline,
PipelineBindPoint, PipelineLayout,
graphics::vertex_input::VertexBuffersCollection, ray_tracing::RayTracingPipeline,
ComputePipeline, GraphicsPipeline, PipelineBindPoint, PipelineLayout,
},
DeviceSize, Requires, RequiresAllOf, RequiresOneOf, ValidationError, Version, VulkanObject,
};
Expand Down Expand Up @@ -794,6 +794,9 @@ impl RecordingCommandBuffer {
}));
}
}
PipelineBindPoint::RayTracing => {
// TODO: RayTracing: Validation
}
}

if first_set + descriptor_sets as u32 > pipeline_layout.set_layouts().len() as u32 {
Expand Down Expand Up @@ -1018,6 +1021,26 @@ impl RecordingCommandBuffer {
self
}

pub unsafe fn bind_pipeline_ray_tracing(&mut self, pipeline: &RayTracingPipeline) -> &mut Self {
// TODO: RayTracing: Validation
self.bind_pipeline_ray_tracing_unchecked(pipeline)
}

#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn bind_pipeline_ray_tracing_unchecked(
&mut self,
pipeline: &RayTracingPipeline,
) -> &mut Self {
let fns = self.device().fns();
(fns.v1_0.cmd_bind_pipeline)(
self.handle(),
ash::vk::PipelineBindPoint::RAY_TRACING_KHR,
pipeline.handle(),
);

self
}

#[inline]
pub unsafe fn bind_vertex_buffers(
&mut self,
Expand Down Expand Up @@ -1395,6 +1418,9 @@ impl RecordingCommandBuffer {
}));
}
}
PipelineBindPoint::RayTracing => {
// TODO: RayTracing
}
}

// VUID-vkCmdPushDescriptorSetKHR-commonparent
Expand Down
104 changes: 104 additions & 0 deletions vulkano/src/command_buffer/commands/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::{
subpass::PipelineSubpassType,
vertex_input::{RequiredVertexInputsVUIDs, VertexInputRate},
},
ray_tracing::ShaderBindingTable,
DynamicState, GraphicsPipeline, Pipeline, PipelineLayout,
},
query::QueryType,
Expand Down Expand Up @@ -1592,6 +1593,53 @@ impl<L> AutoCommandBufferBuilder<L> {
self
}

pub unsafe fn trace_rays(
&mut self,
shader_binding_table: ShaderBindingTable,
width: u32,
height: u32,
depth: u32,
) -> Result<&mut Self, Box<ValidationError>> {
// TODO: RayTrace: Validation

Ok(self.trace_rays_unchecked(shader_binding_table, width, height, depth))
}

#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn trace_rays_unchecked(
&mut self,
shader_binding_table: ShaderBindingTable,
width: u32,
height: u32,
depth: u32,
) -> &mut Self {
// TODO: RayTracing: as_deref()
let pipeline = self.builder_state.pipeline_ray_tracing.as_deref().unwrap();

let mut used_resources = Vec::new();
self.add_descriptor_sets_resources(&mut used_resources, pipeline);
self.add_shader_binding_table_buffer_resources(
&mut used_resources,
shader_binding_table.buffer(),
);

self.add_command("ray_trace", used_resources, move |out| {
out.trace_rays_unchecked(&shader_binding_table, width, height, depth);
});

self
}

fn validate_trace_rays(
&self,
shader_binding_table: &ShaderBindingTable,
width: u32,
height: u32,
depth: u32,
) -> Result<(), Box<ValidationError>> {
todo!()
}

fn validate_pipeline_descriptor_sets<Pl: Pipeline>(
&self,
vuid_type: VUIDType,
Expand Down Expand Up @@ -3714,6 +3762,21 @@ impl<L> AutoCommandBufferBuilder<L> {
},
));
}

fn add_shader_binding_table_buffer_resources(
&self,
used_resources: &mut Vec<(ResourceUseRef2, Resource)>,
sbt_buffer: &Subbuffer<[u8]>,
) {
used_resources.push((
ResourceInCommand::ShaderBindingTableBuffer.into(),
Resource::Buffer {
buffer: sbt_buffer.clone(),
range: 0..sbt_buffer.size(),
memory_access: PipelineStageAccessFlags::RayTracingShader_ShaderBindingTableRead,
},
));
}
}

impl RecordingCommandBuffer {
Expand Down Expand Up @@ -4947,6 +5010,47 @@ impl RecordingCommandBuffer {

self
}

pub unsafe fn trace_rays(
&mut self,
shader_binding_table: &ShaderBindingTable,
width: u32,
height: u32,
depth: u32,
) -> Result<&mut Self, Box<ValidationError>> {
// self.validate_trace_ray()?;
// TODO: RayTracing: Validation

Ok(self.trace_rays_unchecked(shader_binding_table, width, height, depth))
}

fn validate_trace_rays(&self) -> Result<(), Box<ValidationError>> {
todo!()
}

#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn trace_rays_unchecked(
&mut self,
shader_binding_table: &ShaderBindingTable,
width: u32,
height: u32,
depth: u32,
) -> &mut Self {
let fns = self.device().fns();

(fns.khr_ray_tracing_pipeline.cmd_trace_rays_khr)(
self.handle(),
shader_binding_table.raygen(),
shader_binding_table.miss(),
shader_binding_table.hit(),
shader_binding_table.callable(),
width,
height,
depth,
);

self
}
}

#[derive(Clone, Copy)]
Expand Down
1 change: 1 addition & 0 deletions vulkano/src/command_buffer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1617,6 +1617,7 @@ pub enum ResourceInCommand {
SecondaryCommandBuffer { index: u32 },
Source,
VertexBuffer { binding: u32 },
ShaderBindingTableBuffer,
}

#[doc(hidden)]
Expand Down
Loading
Loading