[spirv] Fix Memory Barrier mappings to SPIR-V. (#917)
This commit is contained in:
Родитель
9a502c0e10
Коммит
8c5a38ba22
|
@ -5473,24 +5473,66 @@ uint32_t SPIRVEmitter::processIntrinsicMemoryBarrier(const CallExpr *callExpr,
|
|||
bool isDevice,
|
||||
bool groupSync,
|
||||
bool isAllBarrier) {
|
||||
// Execution Barrier scope:
|
||||
// Device = 1
|
||||
// Workgroup = 2
|
||||
// Memory Barrier scope:
|
||||
// Device = 1
|
||||
// Workgroup = 2
|
||||
// Memory Semantics Barrier scope:
|
||||
// WorkgroupMemory = 0x100 = 256
|
||||
// CrossWorkgroupMemory = 0x200 = 512
|
||||
// 'All Memory Barrier' must place barrier at several different levels, so
|
||||
// several flags must be turned on:
|
||||
// 0x10 | 0x40 | 0x80 | 0x100 | 0x200 | 0x400 | 0x800 = 0xFD0 = 4048.
|
||||
const uint32_t memSemaMask = isAllBarrier ? 0xFD0 : isDevice ? 0x200 : 0x100;
|
||||
const auto memSema = theBuilder.getConstantUint32(memSemaMask);
|
||||
const auto memScope = isDevice ? theBuilder.getConstantUint32(1)
|
||||
: theBuilder.getConstantUint32(2);
|
||||
const auto execScope = groupSync ? memScope : 0;
|
||||
theBuilder.createBarrier(execScope, memScope, memSema);
|
||||
// * DeviceMemoryBarrier =
|
||||
// OpMemoryBarrier (memScope=Device,
|
||||
// sem=Image|Uniform|AcquireRelease)
|
||||
//
|
||||
// * DeviceMemoryBarrierWithGroupSync =
|
||||
// OpControlBarrier(execScope = Workgroup,
|
||||
// memScope=Device,
|
||||
// sem=Image|Uniform|AcquireRelease)
|
||||
const spv::MemorySemanticsMask deviceMemoryBarrierSema =
|
||||
spv::MemorySemanticsMask::ImageMemory |
|
||||
spv::MemorySemanticsMask::UniformMemory |
|
||||
spv::MemorySemanticsMask::AcquireRelease;
|
||||
|
||||
// * GroupMemoryBarrier =
|
||||
// OpMemoryBarrier (memScope=Workgroup,
|
||||
// sem = Workgroup|AcquireRelease)
|
||||
//
|
||||
// * GroupMemoryBarrierWithGroupSync =
|
||||
// OpControlBarrier (execScope = Workgroup,
|
||||
// memScope = Workgroup,
|
||||
// sem = Workgroup|AcquireRelease)
|
||||
const spv::MemorySemanticsMask groupMemoryBarrierSema =
|
||||
spv::MemorySemanticsMask::WorkgroupMemory |
|
||||
spv::MemorySemanticsMask::AcquireRelease;
|
||||
|
||||
// * AllMemoryBarrier =
|
||||
// OpMemoryBarrier(memScope = Device,
|
||||
// sem = Image|Uniform|Workgroup|AcquireRelease)
|
||||
//
|
||||
// * AllMemoryBarrierWithGroupSync =
|
||||
// OpControlBarrier(execScope = Workgroup,
|
||||
// memScope = Device,
|
||||
// sem = Image|Uniform|Workgroup|AcquireRelease)
|
||||
const spv::MemorySemanticsMask allMemoryBarrierSema =
|
||||
spv::MemorySemanticsMask::ImageMemory |
|
||||
spv::MemorySemanticsMask::UniformMemory |
|
||||
spv::MemorySemanticsMask::WorkgroupMemory |
|
||||
spv::MemorySemanticsMask::AtomicCounterMemory |
|
||||
spv::MemorySemanticsMask::AcquireRelease;
|
||||
|
||||
// Get <result-id> for execution scope.
|
||||
// If present, execution scope is always Workgroup!
|
||||
const uint32_t execScopeId =
|
||||
groupSync ? theBuilder.getConstantUint32(
|
||||
static_cast<uint32_t>(spv::Scope::Workgroup))
|
||||
: 0;
|
||||
|
||||
// Get <result-id> for memory scope
|
||||
const spv::Scope memScope =
|
||||
(isDevice || isAllBarrier) ? spv::Scope::Device : spv::Scope::Workgroup;
|
||||
const uint32_t memScopeId =
|
||||
theBuilder.getConstantUint32(static_cast<uint32_t>(memScope));
|
||||
|
||||
// Get <result-id> for memory semantics
|
||||
const auto memSemaMask = isAllBarrier ? allMemoryBarrierSema
|
||||
: isDevice ? deviceMemoryBarrierSema
|
||||
: groupMemoryBarrierSema;
|
||||
const uint32_t memSema =
|
||||
theBuilder.getConstantUint32(static_cast<uint32_t>(memSemaMask));
|
||||
theBuilder.createBarrier(execScopeId, memScopeId, memSema);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
// Run: %dxc -T cs_6_0 -E main
|
||||
|
||||
// Memory scope : Device = 0x1 = 1
|
||||
// Semantics: ImageMemory | AtomicCounterMemory | UniformMemory | WorkgroupMemory | AcquireRelease = 0x800 | 0x400 | 0x40 | 0x100 | 0x8 = 3400
|
||||
|
||||
void main() {
|
||||
// CHECK: OpMemoryBarrier %uint_1 %uint_4048
|
||||
// CHECK: OpMemoryBarrier %uint_1 %uint_3400
|
||||
AllMemoryBarrier();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Run: %dxc -T cs_6_0 -E main
|
||||
|
||||
// Execution scope : Workgroup = 0x2 = 2
|
||||
// Memory scope : Device = 0x1 = 1
|
||||
// Semantics: ImageMemory | AtomicCounterMemory | UniformMemory | WorkgroupMemory | AcquireRelease = 0x800 | 0x400 | 0x40 | 0x100 | 0x8 = 3400
|
||||
|
||||
void main() {
|
||||
// CHECK: OpControlBarrier %uint_1 %uint_1 %uint_4048
|
||||
// CHECK: OpControlBarrier %uint_2 %uint_1 %uint_3400
|
||||
AllMemoryBarrierWithGroupSync();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
// Run: %dxc -T cs_6_0 -E main
|
||||
|
||||
// Memory scope : Device = 0x1 = 1
|
||||
// Semantics: ImageMemory | UniformMemory | AcquireRelease = 0x800 | 0x40 | 0x8 = 2120
|
||||
|
||||
void main() {
|
||||
// CHECK: OpMemoryBarrier %uint_1 %uint_512
|
||||
// CHECK: OpMemoryBarrier %uint_1 %uint_2120
|
||||
DeviceMemoryBarrier();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Run: %dxc -T cs_6_0 -E main
|
||||
|
||||
// Execution scope : Workgroup = 0x2 = 2
|
||||
// Memory scope : Device = 0x1 = 1
|
||||
// Semantics: ImageMemory | UniformMemory | AcquireRelease = 0x800 | 0x40 | 0x8 = 2120
|
||||
|
||||
void main() {
|
||||
// CHECK: OpControlBarrier %uint_1 %uint_1 %uint_512
|
||||
// CHECK: OpControlBarrier %uint_2 %uint_1 %uint_2120
|
||||
DeviceMemoryBarrierWithGroupSync();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
// Run: %dxc -T cs_6_0 -E main
|
||||
|
||||
// Memory scope : Workgroup = 0x2 = 2
|
||||
// Semantics: WorkgroupMemory | AcquireRelease = 0x100 | 0x8 = 264
|
||||
|
||||
void main() {
|
||||
// CHECK: OpMemoryBarrier %uint_2 %uint_256
|
||||
// CHECK: OpMemoryBarrier %uint_2 %uint_264
|
||||
GroupMemoryBarrier();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Run: %dxc -T cs_6_0 -E main
|
||||
|
||||
// Execution scope : Workgroup = 0x2 = 2
|
||||
// Memory scope : Workgroup = 0x2 = 2
|
||||
// Semantics: WorkgroupMemory | AcquireRelease = 0x100 | 0x8 = 264
|
||||
|
||||
void main() {
|
||||
// CHECK: OpControlBarrier %uint_2 %uint_2 %uint_256
|
||||
// CHECK: OpControlBarrier %uint_2 %uint_2 %uint_264
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче