blob: 6f3161110eb0a031e7ed0d3f7c71abc8690f731d (
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
66
67
68
69
70
71
72
|
#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);
}
} // namespace Slang
|