blob: 71833c838efe7a391af8f01627d56472c7d033a5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
#include "slang-ir-check-shader-parameter-type.h"
#include "slang-ir-util.h"
namespace Slang
{
void checkForInvalidShaderParameterTypeForMetal(IRModule* module, DiagnosticSink* sink)
{
HashSet<IRInst*> workListSet;
List<IRInst*> workList;
for (auto inst : module->getGlobalInsts())
{
if (inst->getOp() == kIROp_ParameterBlockType)
{
auto type = inst->getOperand(0);
if (workListSet.add(type))
workList.add(type);
// Diagnose an error on `ParameterBlock<ConstantBuffer<T>>`.
if (type->getOp() == kIROp_ConstantBufferType)
{
bool foundUseSite = false;
for (auto use = inst->firstUse; use; use = use->nextUse)
{
auto user = use->getUser();
if (user->sourceLoc.isValid())
{
sink->diagnose(user, Diagnostics::constantBufferInParameterBlockNotAllowedOnMetal);
foundUseSite = true;
break;
}
}
if (!foundUseSite)
sink->diagnose(inst, Diagnostics::constantBufferInParameterBlockNotAllowedOnMetal);
}
}
}
// Diagnose an error any any struct fields whose type is `ConstantBuffer<T>` if the
// struct is used inside a `ParameterBlock`.
for (Index i = 0; i < workList.getCount(); i++)
{
auto type = workList[i];
if (auto structType = as<IRStructType>(type))
{
for (auto field : structType->getFields())
{
auto fieldType = field->getFieldType();
if (fieldType->getOp() == kIROp_ConstantBufferType)
{
sink->diagnose(field->getKey(), Diagnostics::constantBufferInParameterBlockNotAllowedOnMetal);
}
if (workListSet.add(fieldType))
workList.add(fieldType);
}
}
}
}
void checkForInvalidShaderParameterType(
TargetRequest* target,
IRModule* module,
DiagnosticSink* sink)
{
if (isMetalTarget(target))
checkForInvalidShaderParameterTypeForMetal(module, sink);
}
}
|