VK_KHR_ray_query implementation

This commit is contained in:
Konstantin Pail 2022-03-15 21:54:29 +03:00
parent 53d94a982e
commit 251361bd6f
5 changed files with 833 additions and 0 deletions

View File

@ -0,0 +1,242 @@
RWByteAddressBuffer _17 : register(u0);
uniform RaytracingAccelerationStructure rtas;
static RayQuery<RAY_FLAG_NONE> rayQuery;
static float3x4 _362;
static float4x3 _364;
void comp_main()
{
RayDesc _1ident = {0.0f.xxx, 0.0f, float3(1.0f, 0.0f, 0.0f), 9999.0f};
rayQuery.TraceRayInline(rtas, 0u, 255u, _1ident);
float3x4 _361;
float4x3 _363;
_363 = _364;
_361 = _362;
float3x4 _387;
float4x3 _398;
for (;;)
{
bool _67 = rayQuery.Proceed();
if (_67)
{
uint _71 = rayQuery.CandidateType();
switch (_71)
{
case 0u:
{
rayQuery.Abort();
float4x3 _79 = rayQuery.CandidateObjectToWorld4x3();
rayQuery.CommitNonOpaqueTriangleHit();
bool _87 = rayQuery.CommittedTriangleFrontFace();
if (_87)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
float2 _92 = rayQuery.CommittedTriangleBarycentrics();
if (_92.x == 0.0f)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
int _98 = rayQuery.CommittedInstanceID();
if (_98 > 0)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
int _103 = rayQuery.CommittedInstanceIndex();
if (_103 > 0)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
float3 _108 = rayQuery.CommittedObjectRayDirection();
if (_108.x > 0.0f)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
float3 _114 = rayQuery.CommittedObjectRayOrigin();
if (_114.x > 0.0f)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
int _120 = rayQuery.CommittedPrimitiveIndex();
if (_120 > 0)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
float _125 = rayQuery.CommittedRayT();
if (_125 > 0.0f)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
uint _130 = rayQuery.CommittedInstanceContributionToHitGroupIndex();
if (_130 > 0u)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
_398 = _79;
_387 = transpose(_79);
break;
}
case 1u:
{
float4x3 _136 = rayQuery.CandidateObjectToWorld4x3();
bool _139 = rayQuery.CandidateProceduralPrimitiveNonOpaque();
if (_139)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
rayQuery.CommitProceduralPrimitiveHit(144);
rayQuery.Abort();
_398 = _136;
_387 = transpose(_136);
break;
}
default:
{
_398 = _363;
_387 = _361;
break;
}
}
_363 = _398;
_361 = _387;
continue;
}
else
{
break;
}
}
if (_361[0].x == _363[0].x)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
uint _157 = rayQuery.CommittedStatus();
float3x4 _365;
float4x3 _376;
switch (_157)
{
case 0u:
{
float4x3 _163 = rayQuery.CandidateWorldToObject4x3();
_376 = _163;
_365 = transpose(_163);
break;
}
case 1u:
{
float4x3 _167 = rayQuery.CommittedWorldToObject4x3();
bool _170 = rayQuery.CommittedTriangleFrontFace();
if (_170)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
float2 _174 = rayQuery.CommittedTriangleBarycentrics();
if (_174.y == 0.0f)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
_376 = _167;
_365 = transpose(_167);
break;
}
case 2u:
{
int _182 = rayQuery.CommittedGeometryIndex();
if (_182 > 0)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
int _187 = rayQuery.CommittedInstanceIndex();
if (_187 > 0)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
int _192 = rayQuery.CommittedInstanceID();
if (_192 > 0)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
float3 _197 = rayQuery.CommittedObjectRayDirection();
if (_197.z > 0.0f)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
float3 _204 = rayQuery.CommittedObjectRayOrigin();
if (_204.x > 0.0f)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
int _210 = rayQuery.CommittedPrimitiveIndex();
if (_210 > 0)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
float _215 = rayQuery.CommittedRayT();
if (_215 > 0.0f)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
_376 = _363;
_365 = _361;
break;
}
default:
{
_376 = _363;
_365 = _361;
break;
}
}
if (_365[0].x == _376[0].x)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
uint _230 = rayQuery.RayFlags();
if (_230 > 256u)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
float _236 = rayQuery.RayTMin();
if (_236 > 0.0f)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
float3 _242 = rayQuery.WorldRayOrigin();
float3 _244 = rayQuery.WorldRayDirection();
if (_242.x == _244.z)
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
}
[numthreads(1, 1, 1)]
void main()
{
comp_main();
}

View File

@ -0,0 +1,224 @@
struct Ray
{
float3 pos;
float tmin;
float3 dir;
float tmax;
};
RWByteAddressBuffer _17 : register(u0);
RWByteAddressBuffer _257 : register(u2);
uniform RaytracingAccelerationStructure rtas;
static RayQuery<RAY_FLAG_NONE> rayQuery;
Ray makeRayDesc()
{
Ray ray;
ray.pos = 0.0f.xxx;
ray.dir = float3(1.0f, 0.0f, 0.0f);
ray.tmin = 0.0f;
ray.tmax = 9999.0f;
return ray;
}
void doSomething()
{
_17.Store(0, 0u);
_17.Store(4, 0u);
}
void comp_main()
{
Ray ray = makeRayDesc();
RayDesc _1ident = {ray.pos, ray.tmin, ray.dir, ray.tmax};
rayQuery.TraceRayInline(rtas, 0u, 255u, _1ident);
float4x3 _mat4x3;
float3x4 _mat3x4;
for (;;)
{
bool _67 = rayQuery.Proceed();
if (_67)
{
uint _71 = rayQuery.CandidateType();
uint candidateType = _71;
switch (candidateType)
{
case 0u:
{
rayQuery.Abort();
float4x3 _79 = rayQuery.CandidateObjectToWorld4x3();
_mat4x3 = _79;
_mat3x4 = transpose(_mat4x3);
rayQuery.CommitNonOpaqueTriangleHit();
bool _87 = rayQuery.CommittedTriangleFrontFace();
if (_87)
{
doSomething();
}
float2 _92 = rayQuery.CommittedTriangleBarycentrics();
if (_92.x == 0.0f)
{
doSomething();
}
int _98 = rayQuery.CommittedInstanceID();
if (_98 > 0)
{
doSomething();
}
int _103 = rayQuery.CommittedInstanceIndex();
if (_103 > 0)
{
doSomething();
}
float3 _108 = rayQuery.CommittedObjectRayDirection();
if (_108.x > 0.0f)
{
doSomething();
}
float3 _114 = rayQuery.CommittedObjectRayOrigin();
if (_114.x > 0.0f)
{
doSomething();
}
int _120 = rayQuery.CommittedPrimitiveIndex();
if (_120 > 0)
{
doSomething();
}
float _125 = rayQuery.CommittedRayT();
if (_125 > 0.0f)
{
doSomething();
}
uint _130 = rayQuery.CommittedInstanceContributionToHitGroupIndex();
if (_130 > 0u)
{
doSomething();
}
break;
}
case 1u:
{
float4x3 _136 = rayQuery.CandidateObjectToWorld4x3();
_mat4x3 = _136;
_mat3x4 = transpose(_mat4x3);
bool _139 = rayQuery.CandidateProceduralPrimitiveNonOpaque();
if (_139)
{
doSomething();
}
float t = 0.5f;
rayQuery.CommitProceduralPrimitiveHit(145);
rayQuery.Abort();
break;
}
}
continue;
}
else
{
break;
}
}
if (_mat3x4[0].x == _mat4x3[0].x)
{
doSomething();
}
uint _157 = rayQuery.CommittedStatus();
uint committedStatus = _157;
switch (committedStatus)
{
case 0u:
{
float4x3 _163 = rayQuery.CandidateWorldToObject4x3();
_mat4x3 = _163;
_mat3x4 = transpose(_mat4x3);
break;
}
case 1u:
{
float4x3 _167 = rayQuery.CommittedWorldToObject4x3();
_mat4x3 = _167;
_mat3x4 = transpose(_mat4x3);
bool _170 = rayQuery.CommittedTriangleFrontFace();
if (_170)
{
doSomething();
}
float2 _174 = rayQuery.CommittedTriangleBarycentrics();
if (_174.y == 0.0f)
{
doSomething();
}
break;
}
case 2u:
{
int _182 = rayQuery.CommittedGeometryIndex();
if (_182 > 0)
{
doSomething();
}
int _187 = rayQuery.CommittedInstanceIndex();
if (_187 > 0)
{
doSomething();
}
int _192 = rayQuery.CommittedInstanceID();
if (_192 > 0)
{
doSomething();
}
float3 _197 = rayQuery.CommittedObjectRayDirection();
if (_197.z > 0.0f)
{
doSomething();
}
float3 _204 = rayQuery.CommittedObjectRayOrigin();
if (_204.x > 0.0f)
{
doSomething();
}
int _210 = rayQuery.CommittedPrimitiveIndex();
if (_210 > 0)
{
doSomething();
}
float _215 = rayQuery.CommittedRayT();
if (_215 > 0.0f)
{
doSomething();
}
break;
}
}
if (_mat3x4[0].x == _mat4x3[0].x)
{
doSomething();
}
uint _230 = rayQuery.RayFlags();
if (_230 > 256u)
{
doSomething();
}
float _236 = rayQuery.RayTMin();
if (_236 > 0.0f)
{
doSomething();
}
float3 _242 = rayQuery.WorldRayOrigin();
float3 o = _242;
float3 _244 = rayQuery.WorldRayDirection();
float3 d = _244;
if (o.x == d.z)
{
doSomething();
}
}
[numthreads(1, 1, 1)]
void main()
{
comp_main();
}

View File

@ -0,0 +1,213 @@
#version 460
#extension GL_EXT_ray_query : enable
#extension GL_EXT_ray_flags_primitive_culling : enable
layout(primitive_culling);
struct Ray
{
vec3 pos;
float tmin;
vec3 dir;
float tmax;
};
layout(std430, set = 0, binding = 0) buffer Log
{
uint x;
uint y;
};
layout(binding = 1, set = 0) uniform accelerationStructureEXT rtas;
layout(std430, set = 0, binding = 2) buffer Rays { Ray rays[]; };
void doSomething()
{
x = 0;
y = 0;
}
Ray makeRayDesc()
{
Ray ray;
ray.pos= vec3(0,0,0);
ray.dir = vec3(1,0,0);
ray.tmin = 0.0f;
ray.tmax = 9999.0;
return ray;
}
void main()
{
Ray ray = makeRayDesc();
rayQueryEXT rayQuery;
rayQueryInitializeEXT(rayQuery, rtas, gl_RayFlagsNoneEXT, 0xFF, ray.pos, ray.tmin, ray.dir, ray.tmax);
mat4x3 _mat4x3;
mat3x4 _mat3x4;
while (rayQueryProceedEXT(rayQuery))
{
uint candidateType = rayQueryGetIntersectionTypeEXT(rayQuery, false);
switch(candidateType)
{
case gl_RayQueryCandidateIntersectionTriangleEXT:
rayQueryTerminateEXT(rayQuery);
_mat4x3 = rayQueryGetIntersectionObjectToWorldEXT(rayQuery, false);
_mat3x4 = transpose(_mat4x3);
rayQueryConfirmIntersectionEXT(rayQuery);
if (rayQueryGetIntersectionFrontFaceEXT(rayQuery, true))
{
doSomething();
}
if (rayQueryGetIntersectionBarycentricsEXT(rayQuery, true).x == 0)
{
doSomething();
}
if (rayQueryGetIntersectionInstanceCustomIndexEXT(rayQuery, true) > 0)
{
doSomething();
}
if (rayQueryGetIntersectionInstanceIdEXT(rayQuery, true) > 0)
{
doSomething();
}
if (rayQueryGetIntersectionObjectRayDirectionEXT(rayQuery, true).x > 0)
{
doSomething();
}
if (rayQueryGetIntersectionObjectRayOriginEXT(rayQuery, true).x > 0)
{
doSomething();
}
if (rayQueryGetIntersectionPrimitiveIndexEXT(rayQuery, true) > 0)
{
doSomething();
}
if (rayQueryGetIntersectionTEXT(rayQuery, true) > 0.f)
{
doSomething();
}
if (rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT(rayQuery, true) > 0)
{
doSomething();
}
break;
case gl_RayQueryCandidateIntersectionAABBEXT:
{
_mat4x3 = rayQueryGetIntersectionObjectToWorldEXT(rayQuery, false);
_mat3x4 = transpose(_mat4x3);
if (rayQueryGetIntersectionCandidateAABBOpaqueEXT(rayQuery))
{
doSomething();
}
float t = 0.5;
rayQueryGenerateIntersectionEXT(rayQuery, t);
rayQueryTerminateEXT(rayQuery);
break;
}
}
}
if(_mat3x4[0][0] == _mat4x3[0][0])
{
doSomething();
}
uint committedStatus = rayQueryGetIntersectionTypeEXT(rayQuery, true);
switch(committedStatus)
{
case gl_RayQueryCommittedIntersectionNoneEXT :
_mat4x3 = rayQueryGetIntersectionWorldToObjectEXT(rayQuery, false);
_mat3x4 = transpose(_mat4x3);
break;
case gl_RayQueryCommittedIntersectionTriangleEXT :
_mat4x3 = rayQueryGetIntersectionWorldToObjectEXT(rayQuery, true);
_mat3x4 = transpose(_mat4x3);
if (rayQueryGetIntersectionFrontFaceEXT(rayQuery, true))
{
doSomething();
}
if (rayQueryGetIntersectionBarycentricsEXT(rayQuery, true).y == 0)
{
doSomething();
}
break;
case gl_RayQueryCommittedIntersectionGeneratedEXT :
if(rayQueryGetIntersectionGeometryIndexEXT(rayQuery, true) > 0)
{
doSomething();
}
if(rayQueryGetIntersectionInstanceIdEXT(rayQuery, true) > 0)
{
doSomething();
}
if(rayQueryGetIntersectionInstanceCustomIndexEXT(rayQuery, true) > 0)
{
doSomething();
}
if(rayQueryGetIntersectionObjectRayDirectionEXT(rayQuery, true).z > 0)
{
doSomething();
}
if(rayQueryGetIntersectionObjectRayOriginEXT(rayQuery, true).x > 0)
{
doSomething();
}
if(rayQueryGetIntersectionPrimitiveIndexEXT(rayQuery, true) > 0)
{
doSomething();
}
if(rayQueryGetIntersectionTEXT(rayQuery, true) > 0.f)
{
doSomething();
}
break;
}
if (_mat3x4[0][0] == _mat4x3[0][0])
{
doSomething();
}
if (rayQueryGetRayFlagsEXT(rayQuery) > gl_RayFlagsSkipTrianglesEXT)
{
doSomething();
}
if (rayQueryGetRayTMinEXT(rayQuery) > 0.0)
{
doSomething();
}
vec3 o = rayQueryGetWorldRayOriginEXT(rayQuery);
vec3 d = rayQueryGetWorldRayDirectionEXT(rayQuery);
if (o.x == d.z)
{
doSomething();
}
}

View File

@ -462,6 +462,10 @@ string CompilerHLSL::type_to_glsl(const SPIRType &type, uint32_t id)
if (hlsl_options.shader_model < 60)
SPIRV_CROSS_THROW("64-bit integers only supported in SM 6.0.");
return "uint64_t";
case SPIRType::AccelerationStructure:
return "RaytracingAccelerationStructure";
case SPIRType::RayQuery:
return "RayQuery<RAY_FLAG_NONE>";
default:
return "???";
}
@ -2096,6 +2100,13 @@ void CompilerHLSL::emit_struct_member(const SPIRType &type, uint32_t member_type
variable_decl(membertype, to_member_name(type, index)), packing_offset, ";");
}
void CompilerHLSL::emit_rayquery_function(const char *commited, const char *candidate, const uint32_t *ops)
{
flush_variable_declaration(ops[0]);
uint32_t is_commited = evaluate_constant_u32(ops[3]);
emit_op(ops[0], ops[1], join(to_expression(ops[2]), is_commited ? commited : candidate), false);
}
void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
{
auto &type = get<SPIRType>(var.basetype);
@ -3267,6 +3278,11 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
resource_flags = HLSL_BINDING_AUTO_SAMPLER_BIT;
break;
case SPIRType::AccelerationStructure:
space = 't'; // SRV
resource_flags = HLSL_BINDING_AUTO_SRV_BIT;
break;
case SPIRType::Struct:
{
auto storage = type.storage;
@ -5585,6 +5601,143 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
SPIRV_CROSS_THROW("Rasterizer order views require Shader Model 5.1.");
break; // Nothing to do in the body
case OpRayQueryInitializeKHR:
{
flush_variable_declaration(ops[0]);
std::string ray_desc_name = get_unique_identifier();
statement("RayDesc ", ray_desc_name, " = {", to_expression(ops[4]), ", ", to_expression(ops[5]), ", ",
to_expression(ops[6]), ", ", to_expression(ops[7]), "};");
statement(to_expression(ops[0]), ".TraceRayInline(",
to_expression(ops[1]), ", ", // acc structure
to_expression(ops[2]), ", ", // ray flags
to_expression(ops[3]), ", ", // mask
ray_desc_name, ");"); // ray
break;
}
case OpRayQueryProceedKHR:
{
flush_variable_declaration(ops[0]);
emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".Proceed()"), false);
break;
}
case OpRayQueryTerminateKHR:
{
flush_variable_declaration(ops[0]);
statement(to_expression(ops[0]), ".Abort();");
break;
}
case OpRayQueryGenerateIntersectionKHR:
{
flush_variable_declaration(ops[0]);
statement(to_expression(ops[0]), ".CommitProceduralPrimitiveHit(", ops[1], ");");
break;
}
case OpRayQueryConfirmIntersectionKHR:
{
flush_variable_declaration(ops[0]);
statement(to_expression(ops[0]), ".CommitNonOpaqueTriangleHit();");
break;
}
case OpRayQueryGetIntersectionTypeKHR:
{
emit_rayquery_function(".CommittedStatus()", ".CandidateType()", ops);
break;
}
case OpRayQueryGetIntersectionTKHR:
{
emit_rayquery_function(".CommittedRayT()", ".CandidateTriangleRayT()", ops);
break;
}
case OpRayQueryGetIntersectionInstanceCustomIndexKHR:
{
emit_rayquery_function(".CommittedInstanceID()", ".CandidateInstanceID()", ops);
break;
}
case OpRayQueryGetIntersectionInstanceIdKHR:
{
emit_rayquery_function(".CommittedInstanceIndex()", ".CandidateInstanceIndex()", ops);
break;
}
case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR:
{
emit_rayquery_function(".CommittedInstanceContributionToHitGroupIndex()",
".CandidateInstanceContributionToHitGroupIndex()", ops);
break;
}
case OpRayQueryGetIntersectionGeometryIndexKHR:
{
emit_rayquery_function(".CommittedGeometryIndex()",
".CandidateGeometryIndex()", ops);
break;
}
case OpRayQueryGetIntersectionPrimitiveIndexKHR:
{
emit_rayquery_function(".CommittedPrimitiveIndex()", ".CandidatePrimitiveIndex()", ops);
break;
}
case OpRayQueryGetIntersectionBarycentricsKHR:
{
emit_rayquery_function(".CommittedTriangleBarycentrics()", ".CandidateTriangleBarycentrics()", ops);
break;
}
case OpRayQueryGetIntersectionFrontFaceKHR:
{
emit_rayquery_function(".CommittedTriangleFrontFace()", ".CandidateTriangleFrontFace()", ops);
break;
}
case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR:
{
flush_variable_declaration(ops[0]);
emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".CandidateProceduralPrimitiveNonOpaque()"), false);
break;
}
case OpRayQueryGetIntersectionObjectRayDirectionKHR:
{
emit_rayquery_function(".CommittedObjectRayDirection()", ".CandidateObjectRayDirection()", ops);
break;
}
case OpRayQueryGetIntersectionObjectRayOriginKHR:
{
flush_variable_declaration(ops[0]);
emit_rayquery_function(".CommittedObjectRayOrigin()", ".CandidateObjectRayOrigin()", ops);
break;
}
case OpRayQueryGetIntersectionObjectToWorldKHR:
{
emit_rayquery_function(".CommittedObjectToWorld4x3()", ".CandidateObjectToWorld4x3()", ops);
break;
}
case OpRayQueryGetIntersectionWorldToObjectKHR:
{
emit_rayquery_function(".CommittedWorldToObject4x3()", ".CandidateWorldToObject4x3()", ops);
break;
}
case OpRayQueryGetRayFlagsKHR:
{
flush_variable_declaration(ops[0]);
emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".RayFlags()"), false);
break;
}
case OpRayQueryGetRayTMinKHR:
{
flush_variable_declaration(ops[0]);
emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".RayTMin()"), false);
break;
}
case OpRayQueryGetWorldRayOriginKHR:
{
flush_variable_declaration(ops[0]);
emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".WorldRayOrigin()"), false);
break;
}
case OpRayQueryGetWorldRayDirectionKHR:
{
flush_variable_declaration(ops[0]);
emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".WorldRayDirection()"), false);
break;
}
default:
CompilerGLSL::emit_instruction(instruction);
break;

View File

@ -267,6 +267,7 @@ private:
void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index, const std::string &qualifier,
uint32_t base_offset = 0) override;
void emit_rayquery_function(const char *commited, const char *candidate, const uint32_t *ops);
const char *to_storage_qualifiers_glsl(const SPIRVariable &var) override;
void replace_illegal_names() override;