[spirv] Support SPV_KHR_shader_draw_parameters (#1127)

Added support for the following SPIR-V builtins exposed in
SPV_KHR_shader_draw_parameters:
* BaseVertex
* BaseInstance
* DrawIndex
This commit is contained in:
Lei Zhang 2018-03-13 10:07:54 -04:00 коммит произвёл GitHub
Родитель 9beafa70b4
Коммит c859bb040f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 72 добавлений и 2 удалений

Просмотреть файл

@ -231,10 +231,16 @@ Builtin variables
Some of the Vulkan builtin variables have no equivalents in native HLSL
language. To support them, ``[[vk::builtin("<builtin>")]]`` is introduced.
Right now only two ``<builtin>`` are supported:
Right now the following ``<builtin>`` are supported:
* ``PointSize``: The GLSL equivalent is ``gl_PointSize``.
* ``HelperInvocation``: The GLSL equivalent is ``gl_HelperInvocation``.
* ``BaseVertex``: The GLSL equivalent is ``gl_BaseVertexARB``.
Need ``SPV_KHR_shader_draw_parameters`` extension.
* ``BaseInstance``: The GLSL equivalent is ``gl_BaseInstanceARB``.
Need ``SPV_KHR_shader_draw_parameters`` extension.
* ``DrawIndex``: The GLSL equivalent is ``gl_DrawIDARB``.
Need ``SPV_KHR_shader_draw_parameters`` extension.
Please see Vulkan spec. `14.6. Built-In Variables <https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#interfaces-builtin-variables>`_
for detailed explanation of these builtins.

Просмотреть файл

@ -1763,10 +1763,22 @@ uint32_t DeclResultIdMapper::createSpirvStageVar(StageVar *stageVar,
llvm::StringSwitch<BuiltIn>(builtinAttr->getBuiltIn())
.Case("PointSize", BuiltIn::PointSize)
.Case("HelperInvocation", BuiltIn::HelperInvocation)
.Case("BaseVertex", BuiltIn::BaseVertex)
.Case("BaseInstance", BuiltIn::BaseInstance)
.Case("DrawIndex", BuiltIn::DrawIndex)
.Default(BuiltIn::Max);
assert(spvBuiltIn != BuiltIn::Max); // The frontend should guarantee this.
switch (spvBuiltIn) {
case BuiltIn::BaseVertex:
case BuiltIn::BaseInstance:
case BuiltIn::DrawIndex:
theBuilder.addExtension("SPV_KHR_shader_draw_parameters");
theBuilder.requireCapability(spv::Capability::DrawParameters);
break;
}
return theBuilder.addStageBuiltinVar(type, sc, spvBuiltIn);
}
@ -2147,6 +2159,20 @@ bool DeclResultIdMapper::validateVKBuiltins(const NamedDecl *decl,
<< sigPoint->GetName();
success = false;
}
} else if (builtin == "BaseVertex" || builtin == "BaseInstance" ||
builtin == "DrawIndex") {
if (!declType->isSpecificBuiltinType(BuiltinType::Kind::Int) &&
!declType->isSpecificBuiltinType(BuiltinType::Kind::UInt)) {
emitError("%0 builtin must be of 32-bit scalar integer type", loc)
<< builtin;
success = false;
}
if (sigPoint->GetKind() != hlsl::SigPoint::Kind::VSIn) {
emitError("%0 builtin can only be used in vertex shader input", loc)
<< builtin;
success = false;
}
}
}

Просмотреть файл

@ -10446,7 +10446,7 @@ void hlsl::HandleDeclAttributeForHLSL(Sema &S, Decl *D, const AttributeList &A,
{
case AttributeList::AT_VKBuiltIn:
declAttr = ::new (S.Context) VKBuiltInAttr(A.getRange(), S.Context,
ValidateAttributeStringArg(S, A, "PointSize,HelperInvocation"),
ValidateAttributeStringArg(S, A, "PointSize,HelperInvocation,BaseVertex,BaseInstance,DrawIndex"),
A.getAttributeSpellingListIndex());
break;
case AttributeList::AT_VKLocation:

Просмотреть файл

@ -0,0 +1,21 @@
// Run: %dxc -T vs_6_0 -E main
// CHECK: OpCapability DrawParameters
// CHECK: OpExtension "SPV_KHR_shader_draw_parameters"
// CHECK: OpDecorate [[a:%\d+]] BuiltIn BaseVertex
// CHECK: OpDecorate [[b:%\d+]] BuiltIn BaseInstance
// CHECK: OpDecorate [[c:%\d+]] BuiltIn DrawIndex
float main(
// CHECK: [[a]] = OpVariable %_ptr_Input_int Input
[[vk::builtin("BaseVertex")]] int baseVertex : A,
// CHECK: [[b]] = OpVariable %_ptr_Input_uint Input
[[vk::builtin("BaseInstance")]] uint baseInstance : B,
// CHECK: [[c]] = OpVariable %_ptr_Input_int Input
[[vk::builtin("DrawIndex")]] int drawIndex : C
) : OUTPUT {
return baseVertex + baseInstance + drawIndex;
}

Просмотреть файл

@ -0,0 +1,10 @@
// Run: %dxc -T ps_6_0 -E main
float4 main(
[[vk::builtin("BaseVertex")]] float baseVertex : A
) : SV_Target {
return baseVertex;
}
// CHECK: :4:7: error: BaseVertex builtin must be of 32-bit scalar integer type
// CHECK: :4:7: error: BaseVertex builtin can only be used in vertex shader input

Просмотреть файл

@ -1021,6 +1021,13 @@ TEST_F(FileTest, SpirvBuiltInHelperInvocationInvalidUsage) {
TEST_F(FileTest, SpirvBuiltInPointSizeInvalidUsage) {
runFileTest("spirv.builtin.point-size.invalid.hlsl", Expect::Failure);
}
TEST_F(FileTest, SpirvBuiltInShaderDrawParameters) {
runFileTest("spirv.builtin.shader-draw-parameters.hlsl");
}
TEST_F(FileTest, SpirvBuiltInShaderDrawParametersInvalidUsage) {
runFileTest("spirv.builtin.shader-draw-parameters.invalid.hlsl",
Expect::Failure);
}
// For shader stage input/output interface
// For semantic SV_Position, SV_ClipDistance, SV_CullDistance