Skip to content

Commit

Permalink
raytracing: Initial Vulkan support
Browse files Browse the repository at this point in the history
- Vulkan implementations in `RenderingDeviceDriverVulkan`
- Raytracing instruction list in `RenderingDeviceGraph`
- Functions to create acceleration structures and raytracing pipelines
  in `RenderingDevice`
- Raygen, Miss, and ClosestHit shader stages support
- GDScript bindings
- Update classes documentation
- Include a-johnston RenderingDeviceDriverMetal changes
  • Loading branch information
Fahien committed Dec 3, 2024
1 parent 893bbdf commit 0338e1f
Show file tree
Hide file tree
Showing 26 changed files with 2,261 additions and 47 deletions.
18 changes: 18 additions & 0 deletions doc/classes/RDShaderSPIRV.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,21 @@
</method>
</methods>
<members>
<member name="bytecode_closest_hit" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray()">
The SPIR-V bytecode for the closest hit shader stage.
</member>
<member name="bytecode_compute" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray()">
The SPIR-V bytecode for the compute shader stage.
</member>
<member name="bytecode_fragment" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray()">
The SPIR-V bytecode for the fragment shader stage.
</member>
<member name="bytecode_miss" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray()">
The SPIR-V bytecode for the miss shader stage.
</member>
<member name="bytecode_raygen" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray()">
The SPIR-V bytecode for the ray generation shader stage.
</member>
<member name="bytecode_tesselation_control" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray()">
The SPIR-V bytecode for the tessellation control shader stage.
</member>
Expand All @@ -57,12 +66,21 @@
<member name="bytecode_vertex" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray()">
The SPIR-V bytecode for the vertex shader stage.
</member>
<member name="compile_error_closest_hit" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
The compilation error message for the closest hit shader stage (set by the SPIR-V compiler and Godot). If empty, shader compilation was successful.
</member>
<member name="compile_error_compute" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
The compilation error message for the compute shader stage (set by the SPIR-V compiler and Godot). If empty, shader compilation was successful.
</member>
<member name="compile_error_fragment" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
The compilation error message for the fragment shader stage (set by the SPIR-V compiler and Godot). If empty, shader compilation was successful.
</member>
<member name="compile_error_miss" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
The compilation error message for the miss shader stage (set by the SPIR-V compiler and Godot). If empty, shader compilation was successful.
</member>
<member name="compile_error_raygen" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
The compilation error message for the ray generation shader stage (set by the SPIR-V compiler and Godot). If empty, shader compilation was successful.
</member>
<member name="compile_error_tesselation_control" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
The compilation error message for the tessellation control shader stage (set by the SPIR-V compiler and Godot). If empty, shader compilation was successful.
</member>
Expand Down
9 changes: 9 additions & 0 deletions doc/classes/RDShaderSource.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,21 @@
<member name="language" type="int" setter="set_language" getter="get_language" enum="RenderingDevice.ShaderLanguage" default="0">
The language the shader is written in.
</member>
<member name="source_closest_hit" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
Source code for the shader's closest hit stage.
</member>
<member name="source_compute" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
Source code for the shader's compute stage.
</member>
<member name="source_fragment" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
Source code for the shader's fragment stage.
</member>
<member name="source_miss" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
Source code for the shader's miss stage;
</member>
<member name="source_raygen" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
Source code for the shader's ray generation stage.
</member>
<member name="source_tesselation_control" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
Source code for the shader's tessellation control stage.
</member>
Expand Down
160 changes: 158 additions & 2 deletions doc/classes/RenderingDevice.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@
This method does nothing.
</description>
</method>
<method name="blas_create">
<return type="RID" />
<param index="0" name="vertex_array" type="RID" />
<param index="1" name="index_array" type="RID" />
<param index="2" name="transform_buffer" type="RID" />
<param index="3" name="transform_offset" type="int" default="0" />
<description>
Creates a new Bottom Level Acceleration Structure. It can be accessed with the RID that is returned.
Once finished with your RID, you will want to free the RID using the RenderingDevice's [method free_rid] method.
</description>
</method>
<method name="buffer_clear">
<return type="int" enum="Error" />
<param index="0" name="buffer" type="RID" />
Expand Down Expand Up @@ -680,6 +691,118 @@
Limits for various graphics hardware can be found in the [url=https://vulkan.gpuinfo.org/]Vulkan Hardware Database[/url].
</description>
</method>
<method name="raytracing_is_supported" qualifiers="const">
<return type="bool" />
<description>
Whether raytracing is supported by the selected device.
</description>
</method>
<method name="raytracing_list_add_barrier">
<return type="void" />
<param index="0" name="raytracing_list" type="int" />
<description>
Raises a Vulkan raytracing barrier in the specified [param raytracing_list].
</description>
</method>
<method name="raytracing_list_begin">
<return type="int" />
<description>
Starts a list of raytracing drawing commands created with the [code]draw_*[/code] methods. The returned value should be passed to other [code]raytracing_list_*[/code] functions.
Multiple raytracing lists cannot be created at the same time; you must finish the previous raytracing list first using [method raytracing_list_end].
A simple raytracing operation might look like this (code is not a complete example):
[codeblock]
var rd = RenderingDevice.new()

# Create a BLAS for a mesh.
blas = rd.blas_create(vertex_array, index_array, transform_buffer)
# Create TLAS with BLASs.
tlas = rd.tlas_create([blas])

var raylist := rd.raytracing_list_begin()

# Build acceleration structures.
rd.raytracing_list_build_acceleration_structure(raylist, blas)
rd.raytracing_list_build_acceleration_structure(raylist, tlas)

# Bind pipeline and uniforms.
rd.raytracing_list_bind_raytracing_pipeline(raylist, raytracing_pipeline)
rd.raytracing_list_bind_uniform_set(raylist, uniform_set, 0)

# Trace rays.
var width = get_viewport().size.x
var height = get_viewport().size.y
rd.raytracing_list_trace_rays(raylist, width, height)
rd.raytracing_list_add_barrier(raylist)

rd.raytracing_list_end()
[/codeblock]
</description>
</method>
<method name="raytracing_list_bind_raytracing_pipeline">
<return type="void" />
<param index="0" name="raytracing_list" type="int" />
<param index="1" name="raytracing_pipeline" type="RID" />
<description>
Binds [param raytracing_pipeline] to the specified [param raytracing_list].
</description>
</method>
<method name="raytracing_list_bind_uniform_set">
<return type="void" />
<param index="0" name="raytracing_list" type="int" />
<param index="1" name="uniform_set" type="RID" />
<param index="2" name="set_index" type="int" />
<description>
Binds the [param uniform_set] to this [param raytracing_list]. Godot ensures that all textures in the uniform set have the correct Vulkan access masks. If Godot had to change access masks of textures, it will raise a Vulkan image memory barrier.
</description>
</method>
<method name="raytracing_list_build_acceleration_structure">
<return type="void" />
<param index="0" name="raytracing_list" type="int" />
<param index="1" name="acceleration_structure" type="RID" />
<description>
Builds the [param acceleration_structure] with the specified [param raytracing_list].
</description>
</method>
<method name="raytracing_list_end">
<return type="void" />
<description>
Finishes a list of raytracing commands created with the [code]raytracing_*[/code] methods.
</description>
</method>
<method name="raytracing_list_set_push_constant">
<return type="void" />
<param index="0" name="raytracing_list" type="int" />
<param index="1" name="buffer" type="PackedByteArray" />
<param index="2" name="size_bytes" type="int" />
<description>
Sets the push constant data to [param buffer] for the specified [param raytracing_list]. The shader determines how this binary data is used. The buffer's size in bytes must also be specified in [param size_bytes] (this can be obtained by calling the [method PackedByteArray.size] method on the passed [param buffer]).
</description>
</method>
<method name="raytracing_list_trace_rays">
<return type="void" />
<param index="0" name="raytracing_list" type="int" />
<param index="1" name="width" type="int" />
<param index="2" name="height" type="int" />
<description>
Initializes a ray tracing dispatch for the specified [param raytracing_list] assembling a group of [param width] x [param height] rays.
</description>
</method>
<method name="raytracing_pipeline_create">
<return type="RID" />
<param index="0" name="shader" type="RID" />
<param index="1" name="specialization_constants" type="RDPipelineSpecializationConstant[]" default="[]" />
<description>
Creates a new raytracing pipeline. It can be accessed with the RID that is returned.
Once finished with your RID, you will want to free the RID using the RenderingDevice's [method free_rid] method.
</description>
</method>
<method name="raytracing_pipeline_is_valid">
<return type="bool" />
<param index="0" name="raytracing_pipeline" type="RID" />
<description>
Returns [code]true[/code] if the raytracing pipeline specified by the [param raytracing_pipeline] RID is valid, [code]false[/code] otherwise.
</description>
</method>
<method name="render_pipeline_create">
<return type="RID" />
<param index="0" name="shader" type="RID" />
Expand Down Expand Up @@ -1011,6 +1134,14 @@
[b]Note:[/b] The existing [param texture] requires the [constant TEXTURE_USAGE_CAN_UPDATE_BIT] to be updatable.
</description>
</method>
<method name="tlas_create">
<return type="RID" />
<param index="0" name="blases" type="RID[]" />
<description>
Creates a new Top Level Acceleration Structure. It can be accessed with the RID that is returned.
Once finished with your RID, you will want to free the RID using the RenderingDevice's [method free_rid] method.
</description>
</method>
<method name="uniform_buffer_create">
<return type="RID" />
<param index="0" name="size_bytes" type="int" />
Expand Down Expand Up @@ -2006,6 +2137,10 @@
</constant>
<constant name="STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT" value="1" enum="StorageBufferUsage" is_bitfield="true">
</constant>
<constant name="STORAGE_BUFFER_USAGE_SHADER_DEVICE_ADDRESS" value="2" enum="StorageBufferUsage" is_bitfield="true">
</constant>
<constant name="STORAGE_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY" value="4" enum="StorageBufferUsage" is_bitfield="true">
</constant>
<constant name="UNIFORM_TYPE_SAMPLER" value="0" enum="UniformType">
Sampler uniform.
</constant>
Expand Down Expand Up @@ -2036,7 +2171,10 @@
<constant name="UNIFORM_TYPE_INPUT_ATTACHMENT" value="9" enum="UniformType">
Input attachment uniform.
</constant>
<constant name="UNIFORM_TYPE_MAX" value="10" enum="UniformType">
<constant name="UNIFORM_TYPE_ACCELERATION_STRUCTURE" value="10" enum="UniformType">
Acceleration structure uniform.
</constant>
<constant name="UNIFORM_TYPE_MAX" value="11" enum="UniformType">
Represents the size of the [enum UniformType] enum.
</constant>
<constant name="RENDER_PRIMITIVE_POINTS" value="0" enum="RenderPrimitive">
Expand Down Expand Up @@ -2344,7 +2482,16 @@
<constant name="SHADER_STAGE_COMPUTE" value="4" enum="ShaderStage">
Compute shader stage. This can be used to run arbitrary computing tasks in a shader, performing them on the GPU instead of the CPU.
</constant>
<constant name="SHADER_STAGE_MAX" value="5" enum="ShaderStage">
<constant name="SHADER_STAGE_RAYGEN" value="5" enum="ShaderStage">
Ray generation shader stage. This can be used to generate primary rays.
</constant>
<constant name="SHADER_STAGE_MISS" value="6" enum="ShaderStage">
Miss shader stage. This can be used to specify what happens if a ray does not hit anything in the scene.
</constant>
<constant name="SHADER_STAGE_CLOSEST_HIT" value="7" enum="ShaderStage">
Closest hit shader stage. This can be used to specify what happens when a ray hits the closest geometry in the scene.
</constant>
<constant name="SHADER_STAGE_MAX" value="8" enum="ShaderStage">
Represents the size of the [enum ShaderStage] enum.
</constant>
<constant name="SHADER_STAGE_VERTEX_BIT" value="1" enum="ShaderStage">
Expand All @@ -2362,6 +2509,15 @@
<constant name="SHADER_STAGE_COMPUTE_BIT" value="16" enum="ShaderStage">
Compute shader stage bit (see also [constant SHADER_STAGE_COMPUTE]).
</constant>
<constant name="SHADER_STAGE_RAYGEN_BIT" value="32" enum="ShaderStage">
Ray generation shader stage bit (see also [constant SHADER_STAGE_RAYGEN]).
</constant>
<constant name="SHADER_STAGE_MISS_BIT" value="64" enum="ShaderStage">
Miss shader stage bit (see also [constant SHADER_STAGE_MISS]).
</constant>
<constant name="SHADER_STAGE_CLOSEST_HIT_BIT" value="128" enum="ShaderStage">
Closest hit shader stage bit (see also [constant SHADER_STAGE_CLOSEST_HIT]).
</constant>
<constant name="SHADER_LANGUAGE_GLSL" value="0" enum="ShaderLanguage">
Khronos' GLSL shading language (used natively by OpenGL and Vulkan). This is the language used for core Godot shaders.
</constant>
Expand Down
20 changes: 20 additions & 0 deletions drivers/metal/rendering_device_driver_metal.h
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,26 @@ class API_AVAILABLE(macos(11.0), ios(14.0)) RenderingDeviceDriverMetal : public

virtual PipelineID compute_pipeline_create(ShaderID p_shader, VectorView<PipelineSpecializationConstant> p_specialization_constants) override final;

#pragma mark - Raytracing

// ----- ACCELERATION STRUCTURE -----

virtual AccelerationStructureID blas_create(BufferID p_vertex_buffer, uint64_t p_vertex_offset, VertexFormatID p_vertex_format, uint32_t p_vertex_count, BufferID p_index_buffer, IndexBufferFormat p_index_format, uint64_t p_index_offset_bytes, uint32_t p_index_count, BufferID p_transform_buffer, uint64_t p_transform_offset) override final;
virtual AccelerationStructureID tlas_create(const LocalVector<AccelerationStructureID> &p_blases) override final;
virtual void acceleration_structure_free(AccelerationStructureID p_acceleration_structure) override final;

// ----- PIPELINE -----

virtual RaytracingPipelineID raytracing_pipeline_create(ShaderID p_shader, VectorView<PipelineSpecializationConstant> p_specialization_constants) override final;
virtual void raytracing_pipeline_free(RaytracingPipelineID p_pipeline) override final;

// ----- COMMANDS -----

virtual void command_build_acceleration_structure(CommandBufferID p_cmd_buffer, AccelerationStructureID p_acceleration_structure) override final;
virtual void command_bind_raytracing_pipeline(CommandBufferID p_cmd_buffer, RaytracingPipelineID p_pipeline) override final;
virtual void command_bind_raytracing_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final;
virtual void command_raytracing_trace_rays(CommandBufferID p_cmd_buffer, RaytracingPipelineID p_pipeline, ShaderID p_shader, uint32_t p_width, uint32_t p_height) override final;

#pragma mark - Queries

// ----- TIMESTAMP -----
Expand Down
Loading

0 comments on commit 0338e1f

Please sign in to comment.