mirror of
https://github.com/RPCSX/SPIRV-Tools.git
synced 2025-03-01 16:05:48 +00:00
Support SPV_KHR_vulkan_memory_model rev2
Support collapsed into one commit: - Asm/Dis support for SPV_KHR_vulkan_memory_model - Add Vulkan mem model image operands to switch - Add TODO for source/validate_image.cpp - val: Image operands NonPrivateTexelKHR, VolatileTexelKHR have no operands This is required for memory model tests to pass SPIR-V validation. - Round trip tests: Test new flags on OpCopyMemory*
This commit is contained in:
parent
21bcb9d8b9
commit
571251c8f8
@ -55,6 +55,13 @@ bool CheckAllImageOperandsHandled() {
|
||||
case SpvImageOperandsConstOffsetsMask:
|
||||
case SpvImageOperandsSampleMask:
|
||||
case SpvImageOperandsMinLodMask:
|
||||
|
||||
// TODO(dneto): Support image operands related to the Vulkan memory model.
|
||||
// https://gitlab.khronos.org/spirv/spirv-tools/issues/32
|
||||
case SpvImageOperandsMakeTexelAvailableKHRMask:
|
||||
case SpvImageOperandsMakeTexelVisibleKHRMask:
|
||||
case SpvImageOperandsNonPrivateTexelKHRMask:
|
||||
case SpvImageOperandsVolatileTexelKHRMask:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -210,7 +217,12 @@ spv_result_t ValidateImageOperands(ValidationState_t& _,
|
||||
const SpvOp opcode = inst->opcode();
|
||||
const size_t num_words = inst->words().size();
|
||||
|
||||
size_t expected_num_image_operand_words = spvtools::utils::CountSetBits(mask);
|
||||
// NonPrivate and Volatile take no operand words.
|
||||
const uint32_t mask_bits_having_operands =
|
||||
mask & ~uint32_t(SpvImageOperandsNonPrivateTexelKHRMask |
|
||||
SpvImageOperandsVolatileTexelKHRMask);
|
||||
size_t expected_num_image_operand_words =
|
||||
spvtools::utils::CountSetBits(mask_bits_having_operands);
|
||||
if (mask & SpvImageOperandsGradMask) {
|
||||
// Grad uses two words.
|
||||
++expected_num_image_operand_words;
|
||||
|
@ -890,8 +890,8 @@ INSTANTIATE_TEST_CASE_P(
|
||||
"Invalid function control operand: 31 has invalid mask component 16"},
|
||||
{"OpLoopMerge %1 %2 !1027",
|
||||
"Invalid loop control operand: 1027 has invalid mask component 1024"},
|
||||
{"%2 = OpImageFetch %1 %image %coord !511",
|
||||
"Invalid image operand: 511 has invalid mask component 256"},
|
||||
{"%2 = OpImageFetch %1 %image %coord !32770",
|
||||
"Invalid image operand: 32770 has invalid mask component 32768"},
|
||||
{"OpSelectionMerge %1 !7",
|
||||
"Invalid selection control operand: 7 has invalid mask component 4"},
|
||||
}), );
|
||||
|
@ -604,16 +604,18 @@ INSTANTIATE_TEST_CASE_P(
|
||||
})), );
|
||||
|
||||
// See SPIR-V Section 3.27 Scope <id>
|
||||
INSTANTIATE_TEST_CASE_P(Scope, EnumCapabilityTest,
|
||||
Combine(Values(SPV_ENV_UNIVERSAL_1_0,
|
||||
SPV_ENV_UNIVERSAL_1_1),
|
||||
ValuesIn(std::vector<EnumCapabilityCase>{
|
||||
CASE0(SCOPE_ID, ScopeCrossDevice),
|
||||
CASE0(SCOPE_ID, ScopeDevice),
|
||||
CASE0(SCOPE_ID, ScopeWorkgroup),
|
||||
CASE0(SCOPE_ID, ScopeSubgroup),
|
||||
CASE0(SCOPE_ID, ScopeInvocation),
|
||||
})), );
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
Scope, EnumCapabilityTest,
|
||||
Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
|
||||
SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_3),
|
||||
ValuesIn(std::vector<EnumCapabilityCase>{
|
||||
CASE0(SCOPE_ID, ScopeCrossDevice),
|
||||
CASE0(SCOPE_ID, ScopeDevice),
|
||||
CASE0(SCOPE_ID, ScopeWorkgroup),
|
||||
CASE0(SCOPE_ID, ScopeSubgroup),
|
||||
CASE0(SCOPE_ID, ScopeInvocation),
|
||||
CASE1(SCOPE_ID, ScopeQueueFamilyKHR, VulkanMemoryModelKHR),
|
||||
})), );
|
||||
|
||||
// See SPIR-V Section 3.28 Group Operation
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
|
@ -89,9 +89,10 @@ INSTANTIATE_TEST_CASE_P(
|
||||
::testing::ValuesIn(std::vector<MaskExpansionCase>{
|
||||
// No bits means no change.
|
||||
{SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, 0, {PREFIX0}, {PREFIX0}},
|
||||
// Unknown bits means no change.
|
||||
// Unknown bits means no change. Use all bits that aren't in the grammar.
|
||||
// The last mask enum is 0x20
|
||||
{SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS,
|
||||
0xfffffffc,
|
||||
0xffffffc0,
|
||||
{PREFIX1},
|
||||
{PREFIX1}},
|
||||
// Volatile has no operands.
|
||||
|
@ -510,6 +510,147 @@ INSTANTIATE_TEST_CASE_P(
|
||||
{SpvCapabilityVariablePointersStorageBuffer})},
|
||||
})), );
|
||||
|
||||
// SPV_KHR_vulkan_memory_model
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SPV_KHR_vulkan_memory_model, ExtensionRoundTripTest,
|
||||
// We'll get coverage over operand tables by trying the universal
|
||||
// environments, and at least one specific environment.
|
||||
//
|
||||
// Note: SPV_KHR_vulkan_memory_model adds scope enum value QueueFamilyKHR.
|
||||
// Scope enums are used in ID defini
|
||||
Combine(
|
||||
Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
|
||||
SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_1),
|
||||
ValuesIn(std::vector<AssemblyCase>{
|
||||
{"OpCapability VulkanMemoryModelKHR\n",
|
||||
MakeInstruction(SpvOpCapability,
|
||||
{SpvCapabilityVulkanMemoryModelKHR})},
|
||||
{"OpCapability VulkanMemoryModelDeviceScopeKHR\n",
|
||||
MakeInstruction(SpvOpCapability,
|
||||
{SpvCapabilityVulkanMemoryModelDeviceScopeKHR})},
|
||||
{"OpMemoryModel Logical VulkanKHR\n",
|
||||
MakeInstruction(SpvOpMemoryModel, {SpvAddressingModelLogical,
|
||||
SpvMemoryModelVulkanKHR})},
|
||||
{"OpStore %1 %2 MakePointerAvailableKHR %3\n",
|
||||
MakeInstruction(SpvOpStore,
|
||||
{1, 2, SpvMemoryAccessMakePointerAvailableKHRMask,
|
||||
3})},
|
||||
{"OpStore %1 %2 Volatile|MakePointerAvailableKHR %3\n",
|
||||
MakeInstruction(SpvOpStore,
|
||||
{1, 2,
|
||||
int(SpvMemoryAccessMakePointerAvailableKHRMask) |
|
||||
int(SpvMemoryAccessVolatileMask),
|
||||
3})},
|
||||
{"OpStore %1 %2 Aligned|MakePointerAvailableKHR 4 %3\n",
|
||||
MakeInstruction(SpvOpStore,
|
||||
{1, 2,
|
||||
int(SpvMemoryAccessMakePointerAvailableKHRMask) |
|
||||
int(SpvMemoryAccessAlignedMask),
|
||||
4, 3})},
|
||||
{"OpStore %1 %2 MakePointerAvailableKHR|NonPrivatePointerKHR %3\n",
|
||||
MakeInstruction(SpvOpStore,
|
||||
{1, 2,
|
||||
int(SpvMemoryAccessMakePointerAvailableKHRMask) |
|
||||
int(SpvMemoryAccessNonPrivatePointerKHRMask),
|
||||
3})},
|
||||
{"%2 = OpLoad %1 %3 MakePointerVisibleKHR %4\n",
|
||||
MakeInstruction(SpvOpLoad,
|
||||
{1, 2, 3, SpvMemoryAccessMakePointerVisibleKHRMask,
|
||||
4})},
|
||||
{"%2 = OpLoad %1 %3 Volatile|MakePointerVisibleKHR %4\n",
|
||||
MakeInstruction(SpvOpLoad,
|
||||
{1, 2, 3,
|
||||
int(SpvMemoryAccessMakePointerVisibleKHRMask) |
|
||||
int(SpvMemoryAccessVolatileMask),
|
||||
4})},
|
||||
{"%2 = OpLoad %1 %3 Aligned|MakePointerVisibleKHR 8 %4\n",
|
||||
MakeInstruction(SpvOpLoad,
|
||||
{1, 2, 3,
|
||||
int(SpvMemoryAccessMakePointerVisibleKHRMask) |
|
||||
int(SpvMemoryAccessAlignedMask),
|
||||
8, 4})},
|
||||
{"%2 = OpLoad %1 %3 MakePointerVisibleKHR|NonPrivatePointerKHR "
|
||||
"%4\n",
|
||||
MakeInstruction(SpvOpLoad,
|
||||
{1, 2, 3,
|
||||
int(SpvMemoryAccessMakePointerVisibleKHRMask) |
|
||||
int(SpvMemoryAccessNonPrivatePointerKHRMask),
|
||||
4})},
|
||||
{"OpCopyMemory %1 %2 "
|
||||
"MakePointerAvailableKHR|"
|
||||
"MakePointerVisibleKHR|"
|
||||
"NonPrivatePointerKHR "
|
||||
"%3 %4\n",
|
||||
MakeInstruction(SpvOpCopyMemory,
|
||||
{1, 2,
|
||||
(int(SpvMemoryAccessMakePointerVisibleKHRMask) |
|
||||
int(SpvMemoryAccessMakePointerAvailableKHRMask) |
|
||||
int(SpvMemoryAccessNonPrivatePointerKHRMask)),
|
||||
3, 4})},
|
||||
{"OpCopyMemorySized %1 %2 %3 "
|
||||
"MakePointerAvailableKHR|"
|
||||
"MakePointerVisibleKHR|"
|
||||
"NonPrivatePointerKHR "
|
||||
"%4 %5\n",
|
||||
MakeInstruction(SpvOpCopyMemorySized,
|
||||
{1, 2, 3,
|
||||
(int(SpvMemoryAccessMakePointerVisibleKHRMask) |
|
||||
int(SpvMemoryAccessMakePointerAvailableKHRMask) |
|
||||
int(SpvMemoryAccessNonPrivatePointerKHRMask)),
|
||||
4, 5})},
|
||||
// Image operands
|
||||
{"OpImageWrite %1 %2 %3 MakeTexelAvailableKHR "
|
||||
"%4\n",
|
||||
MakeInstruction(
|
||||
SpvOpImageWrite,
|
||||
{1, 2, 3, int(SpvImageOperandsMakeTexelAvailableKHRMask), 4})},
|
||||
{"OpImageWrite %1 %2 %3 MakeTexelAvailableKHR|NonPrivateTexelKHR "
|
||||
"%4\n",
|
||||
MakeInstruction(SpvOpImageWrite,
|
||||
{1, 2, 3,
|
||||
int(SpvImageOperandsMakeTexelAvailableKHRMask) |
|
||||
int(SpvImageOperandsNonPrivateTexelKHRMask),
|
||||
4})},
|
||||
{"OpImageWrite %1 %2 %3 "
|
||||
"MakeTexelAvailableKHR|NonPrivateTexelKHR|VolatileTexelKHR "
|
||||
"%4\n",
|
||||
MakeInstruction(SpvOpImageWrite,
|
||||
{1, 2, 3,
|
||||
int(SpvImageOperandsMakeTexelAvailableKHRMask) |
|
||||
int(SpvImageOperandsNonPrivateTexelKHRMask) |
|
||||
int(SpvImageOperandsVolatileTexelKHRMask),
|
||||
4})},
|
||||
{"%2 = OpImageRead %1 %3 %4 MakeTexelVisibleKHR "
|
||||
"%5\n",
|
||||
MakeInstruction(SpvOpImageRead,
|
||||
{1, 2, 3, 4,
|
||||
int(SpvImageOperandsMakeTexelVisibleKHRMask),
|
||||
5})},
|
||||
{"%2 = OpImageRead %1 %3 %4 "
|
||||
"MakeTexelVisibleKHR|NonPrivateTexelKHR "
|
||||
"%5\n",
|
||||
MakeInstruction(SpvOpImageRead,
|
||||
{1, 2, 3, 4,
|
||||
int(SpvImageOperandsMakeTexelVisibleKHRMask) |
|
||||
int(SpvImageOperandsNonPrivateTexelKHRMask),
|
||||
5})},
|
||||
{"%2 = OpImageRead %1 %3 %4 "
|
||||
"MakeTexelVisibleKHR|NonPrivateTexelKHR|VolatileTexelKHR "
|
||||
"%5\n",
|
||||
MakeInstruction(SpvOpImageRead,
|
||||
{1, 2, 3, 4,
|
||||
int(SpvImageOperandsMakeTexelVisibleKHRMask) |
|
||||
int(SpvImageOperandsNonPrivateTexelKHRMask) |
|
||||
int(SpvImageOperandsVolatileTexelKHRMask),
|
||||
5})},
|
||||
|
||||
// Memory semantics ID values are numbers put into a SPIR-V
|
||||
// constant integer referenced by Id. There is no token for
|
||||
// them, and so no assembler or disassembler support required.
|
||||
// Similar for Scope ID.
|
||||
})), );
|
||||
|
||||
// SPV_GOOGLE_decorate_string
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
|
Loading…
x
Reference in New Issue
Block a user