mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-09-19 14:19:59 +00:00
task shader initial
This commit is contained in:
parent
d26c233e1c
commit
dd8839c6f9
@ -0,0 +1,24 @@
|
||||
struct TaskPayload
|
||||
{
|
||||
float a;
|
||||
float b;
|
||||
int c;
|
||||
};
|
||||
|
||||
static const uint3 gl_WorkGroupSize = uint3(1u, 1u, 1u);
|
||||
|
||||
groupshared TaskPayload _payload;
|
||||
|
||||
void task_main()
|
||||
{
|
||||
_payload.a = 1.2000000476837158203125f;
|
||||
_payload.b = 2.2999999523162841796875f;
|
||||
_payload.c = 3;
|
||||
DispatchMesh(1u, 2u, 3u, _payload);
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void main()
|
||||
{
|
||||
task_main();
|
||||
}
|
22
shaders-hlsl/task/task-basic.spv14.vk.nocompat.task
Normal file
22
shaders-hlsl/task/task-basic.spv14.vk.nocompat.task
Normal file
@ -0,0 +1,22 @@
|
||||
#version 450
|
||||
#extension GL_EXT_mesh_shader : require
|
||||
|
||||
layout(local_size_x = 1) in;
|
||||
|
||||
struct TaskPayload
|
||||
{
|
||||
float a;
|
||||
float b;
|
||||
int c;
|
||||
};
|
||||
|
||||
taskPayloadSharedEXT TaskPayload payload;
|
||||
|
||||
void main()
|
||||
{
|
||||
payload.a = 1.2;
|
||||
payload.b = 2.3;
|
||||
payload.c = 3;
|
||||
|
||||
EmitMeshTasksEXT(1, 2, 3);
|
||||
}
|
@ -845,7 +845,6 @@ struct SPIRBlock : IVariant
|
||||
// If terminator is EmitMeshTasksEXT.
|
||||
struct
|
||||
{
|
||||
ID groups[3];
|
||||
ID payload;
|
||||
} mesh = {};
|
||||
|
||||
|
@ -14316,6 +14316,10 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
statement("SetMeshOutputsEXT(", to_unpacked_expression(ops[0]), ", ", to_unpacked_expression(ops[1]), ");");
|
||||
break;
|
||||
|
||||
case OpEmitMeshTasksEXT:
|
||||
statement("EmitMeshTasksEXT(", to_unpacked_expression(ops[0]), ", ", to_unpacked_expression(ops[1]), ", ", to_unpacked_expression(ops[2]), ");");
|
||||
break;
|
||||
|
||||
case OpReadClockKHR:
|
||||
{
|
||||
auto &type = get<SPIRType>(ops[0]);
|
||||
@ -16873,10 +16877,6 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
||||
break;
|
||||
|
||||
case SPIRBlock::EmitMeshTasks:
|
||||
statement("EmitMeshTasksEXT(",
|
||||
to_unpacked_expression(block.mesh.groups[0]), ", ",
|
||||
to_unpacked_expression(block.mesh.groups[1]), ", ",
|
||||
to_unpacked_expression(block.mesh.groups[2]), ");");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1635,7 +1635,7 @@ void CompilerHLSL::emit_resources()
|
||||
auto &type = this->get<SPIRType>(var.basetype);
|
||||
|
||||
if (var.storage != StorageClassFunction && !var.remapped_variable && type.pointer &&
|
||||
(var.storage == StorageClassInput || var.storage == StorageClassOutput) && !is_builtin_variable(var) &&
|
||||
(var.storage == StorageClassInput || var.storage == StorageClassOutput) && !is_builtin_variable(var) &&
|
||||
interface_variable_exists_in_entry_point(var.self))
|
||||
{
|
||||
// Builtin variables are handled separately.
|
||||
@ -1808,8 +1808,10 @@ void CompilerHLSL::emit_resources()
|
||||
if (is_hidden_variable(var, true))
|
||||
continue;
|
||||
|
||||
if (var.storage != StorageClassOutput &&
|
||||
var.storage != StorageClassTaskPayloadWorkgroupEXT)
|
||||
if (var.storage == StorageClassTaskPayloadWorkgroupEXT && is_mesh_shader)
|
||||
continue;
|
||||
|
||||
if (var.storage != StorageClassOutput)
|
||||
{
|
||||
if (!variable_is_lut(var))
|
||||
{
|
||||
@ -1819,6 +1821,7 @@ void CompilerHLSL::emit_resources()
|
||||
switch (var.storage)
|
||||
{
|
||||
case StorageClassWorkgroup:
|
||||
case StorageClassTaskPayloadWorkgroupEXT:
|
||||
storage = "groupshared";
|
||||
break;
|
||||
|
||||
@ -2818,6 +2821,8 @@ string CompilerHLSL::get_inner_entry_point_name() const
|
||||
return "comp_main";
|
||||
else if (execution.model == ExecutionModelMeshEXT)
|
||||
return "mesh_main";
|
||||
else if (execution.model == ExecutionModelTaskEXT)
|
||||
return "task_main";
|
||||
else
|
||||
SPIRV_CROSS_THROW("Unsupported execution model.");
|
||||
}
|
||||
@ -2931,8 +2936,8 @@ void CompilerHLSL::emit_hlsl_entry_point()
|
||||
|
||||
switch (execution.model)
|
||||
{
|
||||
case spv::ExecutionModelTaskEXT:
|
||||
case ExecutionModelMeshEXT:
|
||||
case ExecutionModelMeshNV:
|
||||
case ExecutionModelGLCompute:
|
||||
{
|
||||
if (execution.model == ExecutionModelMeshEXT)
|
||||
@ -3204,8 +3209,9 @@ void CompilerHLSL::emit_hlsl_entry_point()
|
||||
// Run the shader.
|
||||
if (execution.model == ExecutionModelVertex ||
|
||||
execution.model == ExecutionModelFragment ||
|
||||
execution.model == ExecutionModelGLCompute ||
|
||||
execution.model == ExecutionModelMeshEXT)
|
||||
execution.model == ExecutionModelGLCompute ||
|
||||
execution.model == ExecutionModelMeshEXT ||
|
||||
execution.model == ExecutionModelTaskEXT)
|
||||
{
|
||||
// For mesh shaders, we receive special arguments that we must pass down as function arguments.
|
||||
// HLSL does not support proper reference types for passing these IO blocks,
|
||||
@ -6355,6 +6361,19 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
statement("SetMeshOutputCounts(", to_unpacked_expression(ops[0]), ", ", to_unpacked_expression(ops[1]), ");");
|
||||
break;
|
||||
}
|
||||
case OpEmitMeshTasksEXT:
|
||||
{
|
||||
if (instruction.length==4)
|
||||
{
|
||||
statement("DispatchMesh(", to_unpacked_expression(ops[0]), ", ", to_unpacked_expression(ops[1]), ", ",
|
||||
to_unpacked_expression(ops[2]), ", ", to_unpacked_expression(ops[3]), ");");
|
||||
}
|
||||
else
|
||||
{
|
||||
SPIRV_CROSS_THROW("Amplification shader in HLSL must have payload");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
CompilerGLSL::emit_instruction(instruction);
|
||||
|
@ -1123,16 +1123,22 @@ void Parser::parse(const Instruction &instruction)
|
||||
break;
|
||||
|
||||
case OpEmitMeshTasksEXT:
|
||||
{
|
||||
if (!current_block)
|
||||
SPIRV_CROSS_THROW("Trying to end a non-existing block.");
|
||||
|
||||
const auto *type = maybe_get<SPIRType>(ops[0]);
|
||||
if (type)
|
||||
ir.load_type_width.insert({ ops[1], type->width });
|
||||
current_block->ops.push_back(instruction);
|
||||
|
||||
current_block->terminator = SPIRBlock::EmitMeshTasks;
|
||||
for (uint32_t i = 0; i < 3; i++)
|
||||
current_block->mesh.groups[i] = ops[i];
|
||||
current_block->mesh.payload = length >= 4 ? ops[3] : 0;
|
||||
current_block = nullptr;
|
||||
// Currently glslang is bugged and does not treat EmitMeshTasksEXT as a terminator.
|
||||
ignore_trailing_block_opcodes = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case OpReturn:
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user