Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
glslang
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
glslang
Commits
738314fe
Commit
738314fe
authored
Jun 05, 2016
by
Dejan Mircevski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert SpvBuilder.* to master versions.
parent
e5926526
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
267 additions
and
396 deletions
+267
-396
SpvBuilder.cpp
SPIRV/SpvBuilder.cpp
+218
-334
SpvBuilder.h
SPIRV/SpvBuilder.h
+49
-62
No files found.
SPIRV/SpvBuilder.cpp
View file @
738314fe
...
@@ -47,7 +47,7 @@
...
@@ -47,7 +47,7 @@
#include "SpvBuilder.h"
#include "SpvBuilder.h"
#ifndef _WIN32
#ifndef _WIN32
#include <cstdio>
#include <cstdio>
#endif
#endif
namespace
spv
{
namespace
spv
{
...
@@ -67,12 +67,15 @@ Builder::Builder(unsigned int magicNumber, SpvBuildLogger* buildLogger) :
...
@@ -67,12 +67,15 @@ Builder::Builder(unsigned int magicNumber, SpvBuildLogger* buildLogger) :
clearAccessChain
();
clearAccessChain
();
}
}
Builder
::~
Builder
()
{}
Builder
::~
Builder
()
{
}
Id
Builder
::
import
(
const
char
*
name
)
Id
Builder
::
import
(
const
char
*
name
)
{
{
Instruction
*
import
=
new
Instruction
(
getUniqueId
(),
NoType
,
OpExtInstImport
);
Instruction
*
import
=
new
Instruction
(
getUniqueId
(),
NoType
,
OpExtInstImport
);
import
->
addStringOperand
(
name
);
import
->
addStringOperand
(
name
);
imports
.
push_back
(
std
::
unique_ptr
<
Instruction
>
(
import
));
imports
.
push_back
(
std
::
unique_ptr
<
Instruction
>
(
import
));
return
import
->
getResultId
();
return
import
->
getResultId
();
}
}
...
@@ -81,8 +84,7 @@ Id Builder::import(const char* name)
...
@@ -81,8 +84,7 @@ Id Builder::import(const char* name)
Id
Builder
::
makeVoidType
()
Id
Builder
::
makeVoidType
()
{
{
Instruction
*
type
;
Instruction
*
type
;
if
(
groupedTypes
[
OpTypeVoid
].
size
()
==
0
)
if
(
groupedTypes
[
OpTypeVoid
].
size
()
==
0
)
{
{
type
=
new
Instruction
(
getUniqueId
(),
NoType
,
OpTypeVoid
);
type
=
new
Instruction
(
getUniqueId
(),
NoType
,
OpTypeVoid
);
groupedTypes
[
OpTypeVoid
].
push_back
(
type
);
groupedTypes
[
OpTypeVoid
].
push_back
(
type
);
constantsTypesGlobals
.
push_back
(
std
::
unique_ptr
<
Instruction
>
(
type
));
constantsTypesGlobals
.
push_back
(
std
::
unique_ptr
<
Instruction
>
(
type
));
...
@@ -96,8 +98,7 @@ Id Builder::makeVoidType()
...
@@ -96,8 +98,7 @@ Id Builder::makeVoidType()
Id
Builder
::
makeBoolType
()
Id
Builder
::
makeBoolType
()
{
{
Instruction
*
type
;
Instruction
*
type
;
if
(
groupedTypes
[
OpTypeBool
].
size
()
==
0
)
if
(
groupedTypes
[
OpTypeBool
].
size
()
==
0
)
{
{
type
=
new
Instruction
(
getUniqueId
(),
NoType
,
OpTypeBool
);
type
=
new
Instruction
(
getUniqueId
(),
NoType
,
OpTypeBool
);
groupedTypes
[
OpTypeBool
].
push_back
(
type
);
groupedTypes
[
OpTypeBool
].
push_back
(
type
);
constantsTypesGlobals
.
push_back
(
std
::
unique_ptr
<
Instruction
>
(
type
));
constantsTypesGlobals
.
push_back
(
std
::
unique_ptr
<
Instruction
>
(
type
));
...
@@ -111,8 +112,7 @@ Id Builder::makeBoolType()
...
@@ -111,8 +112,7 @@ Id Builder::makeBoolType()
Id
Builder
::
makeSamplerType
()
Id
Builder
::
makeSamplerType
()
{
{
Instruction
*
type
;
Instruction
*
type
;
if
(
groupedTypes
[
OpTypeSampler
].
size
()
==
0
)
if
(
groupedTypes
[
OpTypeSampler
].
size
()
==
0
)
{
{
type
=
new
Instruction
(
getUniqueId
(),
NoType
,
OpTypeSampler
);
type
=
new
Instruction
(
getUniqueId
(),
NoType
,
OpTypeSampler
);
groupedTypes
[
OpTypeSampler
].
push_back
(
type
);
groupedTypes
[
OpTypeSampler
].
push_back
(
type
);
constantsTypesGlobals
.
push_back
(
std
::
unique_ptr
<
Instruction
>
(
type
));
constantsTypesGlobals
.
push_back
(
std
::
unique_ptr
<
Instruction
>
(
type
));
...
@@ -127,8 +127,7 @@ Id Builder::makePointer(StorageClass storageClass, Id pointee)
...
@@ -127,8 +127,7 @@ Id Builder::makePointer(StorageClass storageClass, Id pointee)
{
{
// try to find it
// try to find it
Instruction
*
type
;
Instruction
*
type
;
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypePointer
].
size
();
++
t
)
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypePointer
].
size
();
++
t
)
{
{
type
=
groupedTypes
[
OpTypePointer
][
t
];
type
=
groupedTypes
[
OpTypePointer
][
t
];
if
(
type
->
getImmediateOperand
(
0
)
==
(
unsigned
)
storageClass
&&
if
(
type
->
getImmediateOperand
(
0
)
==
(
unsigned
)
storageClass
&&
type
->
getIdOperand
(
1
)
==
pointee
)
type
->
getIdOperand
(
1
)
==
pointee
)
...
@@ -150,8 +149,7 @@ Id Builder::makeIntegerType(int width, bool hasSign)
...
@@ -150,8 +149,7 @@ Id Builder::makeIntegerType(int width, bool hasSign)
{
{
// try to find it
// try to find it
Instruction
*
type
;
Instruction
*
type
;
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeInt
].
size
();
++
t
)
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeInt
].
size
();
++
t
)
{
{
type
=
groupedTypes
[
OpTypeInt
][
t
];
type
=
groupedTypes
[
OpTypeInt
][
t
];
if
(
type
->
getImmediateOperand
(
0
)
==
(
unsigned
)
width
&&
if
(
type
->
getImmediateOperand
(
0
)
==
(
unsigned
)
width
&&
type
->
getImmediateOperand
(
1
)
==
(
hasSign
?
1u
:
0u
))
type
->
getImmediateOperand
(
1
)
==
(
hasSign
?
1u
:
0u
))
...
@@ -167,8 +165,7 @@ Id Builder::makeIntegerType(int width, bool hasSign)
...
@@ -167,8 +165,7 @@ Id Builder::makeIntegerType(int width, bool hasSign)
module
.
mapInstruction
(
type
);
module
.
mapInstruction
(
type
);
// deal with capabilities
// deal with capabilities
switch
(
width
)
switch
(
width
)
{
{
case
16
:
case
16
:
addCapability
(
CapabilityInt16
);
addCapability
(
CapabilityInt16
);
break
;
break
;
...
@@ -186,8 +183,7 @@ Id Builder::makeFloatType(int width)
...
@@ -186,8 +183,7 @@ Id Builder::makeFloatType(int width)
{
{
// try to find it
// try to find it
Instruction
*
type
;
Instruction
*
type
;
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeFloat
].
size
();
++
t
)
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeFloat
].
size
();
++
t
)
{
{
type
=
groupedTypes
[
OpTypeFloat
][
t
];
type
=
groupedTypes
[
OpTypeFloat
][
t
];
if
(
type
->
getImmediateOperand
(
0
)
==
(
unsigned
)
width
)
if
(
type
->
getImmediateOperand
(
0
)
==
(
unsigned
)
width
)
return
type
->
getResultId
();
return
type
->
getResultId
();
...
@@ -201,8 +197,7 @@ Id Builder::makeFloatType(int width)
...
@@ -201,8 +197,7 @@ Id Builder::makeFloatType(int width)
module
.
mapInstruction
(
type
);
module
.
mapInstruction
(
type
);
// deal with capabilities
// deal with capabilities
switch
(
width
)
switch
(
width
)
{
{
case
16
:
case
16
:
addCapability
(
CapabilityFloat16
);
addCapability
(
CapabilityFloat16
);
break
;
break
;
...
@@ -243,12 +238,12 @@ Id Builder::makeStructResultType(Id type0, Id type1)
...
@@ -243,12 +238,12 @@ Id Builder::makeStructResultType(Id type0, Id type1)
{
{
// try to find it
// try to find it
Instruction
*
type
;
Instruction
*
type
;
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeStruct
].
size
();
++
t
)
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeStruct
].
size
();
++
t
)
{
{
type
=
groupedTypes
[
OpTypeStruct
][
t
];
type
=
groupedTypes
[
OpTypeStruct
][
t
];
if
(
type
->
getNumOperands
()
!=
2
)
if
(
type
->
getNumOperands
()
!=
2
)
continue
;
continue
;
if
(
type
->
getIdOperand
(
0
)
!=
type0
||
type
->
getIdOperand
(
1
)
!=
type1
)
if
(
type
->
getIdOperand
(
0
)
!=
type0
||
type
->
getIdOperand
(
1
)
!=
type1
)
continue
;
continue
;
return
type
->
getResultId
();
return
type
->
getResultId
();
}
}
...
@@ -265,10 +260,10 @@ Id Builder::makeVectorType(Id component, int size)
...
@@ -265,10 +260,10 @@ Id Builder::makeVectorType(Id component, int size)
{
{
// try to find it
// try to find it
Instruction
*
type
;
Instruction
*
type
;
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeVector
].
size
();
++
t
)
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeVector
].
size
();
++
t
)
{
{
type
=
groupedTypes
[
OpTypeVector
][
t
];
type
=
groupedTypes
[
OpTypeVector
][
t
];
if
(
type
->
getIdOperand
(
0
)
==
component
&&
type
->
getImmediateOperand
(
1
)
==
(
unsigned
)
size
)
if
(
type
->
getIdOperand
(
0
)
==
component
&&
type
->
getImmediateOperand
(
1
)
==
(
unsigned
)
size
)
return
type
->
getResultId
();
return
type
->
getResultId
();
}
}
...
@@ -291,10 +286,10 @@ Id Builder::makeMatrixType(Id component, int cols, int rows)
...
@@ -291,10 +286,10 @@ Id Builder::makeMatrixType(Id component, int cols, int rows)
// try to find it
// try to find it
Instruction
*
type
;
Instruction
*
type
;
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeMatrix
].
size
();
++
t
)
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeMatrix
].
size
();
++
t
)
{
{
type
=
groupedTypes
[
OpTypeMatrix
][
t
];
type
=
groupedTypes
[
OpTypeMatrix
][
t
];
if
(
type
->
getIdOperand
(
0
)
==
column
&&
type
->
getImmediateOperand
(
1
)
==
(
unsigned
)
cols
)
if
(
type
->
getIdOperand
(
0
)
==
column
&&
type
->
getImmediateOperand
(
1
)
==
(
unsigned
)
cols
)
return
type
->
getResultId
();
return
type
->
getResultId
();
}
}
...
@@ -316,13 +311,12 @@ Id Builder::makeMatrixType(Id component, int cols, int rows)
...
@@ -316,13 +311,12 @@ Id Builder::makeMatrixType(Id component, int cols, int rows)
Id
Builder
::
makeArrayType
(
Id
element
,
Id
sizeId
,
int
stride
)
Id
Builder
::
makeArrayType
(
Id
element
,
Id
sizeId
,
int
stride
)
{
{
Instruction
*
type
;
Instruction
*
type
;
if
(
stride
==
0
)
if
(
stride
==
0
)
{
{
// try to find existing type
// try to find existing type
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeArray
].
size
();
++
t
)
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeArray
].
size
();
++
t
)
{
{
type
=
groupedTypes
[
OpTypeArray
][
t
];
type
=
groupedTypes
[
OpTypeArray
][
t
];
if
(
type
->
getIdOperand
(
0
)
==
element
&&
type
->
getIdOperand
(
1
)
==
sizeId
)
if
(
type
->
getIdOperand
(
0
)
==
element
&&
type
->
getIdOperand
(
1
)
==
sizeId
)
return
type
->
getResultId
();
return
type
->
getResultId
();
}
}
}
}
...
@@ -352,22 +346,18 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
...
@@ -352,22 +346,18 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
{
{
// try to find it
// try to find it
Instruction
*
type
;
Instruction
*
type
;
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeFunction
].
size
();
++
t
)
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeFunction
].
size
();
++
t
)
{
{
type
=
groupedTypes
[
OpTypeFunction
][
t
];
type
=
groupedTypes
[
OpTypeFunction
][
t
];
if
(
type
->
getIdOperand
(
0
)
!=
returnType
||
if
(
type
->
getIdOperand
(
0
)
!=
returnType
||
(
int
)
paramTypes
.
size
()
!=
type
->
getNumOperands
()
-
1
)
(
int
)
paramTypes
.
size
()
!=
type
->
getNumOperands
()
-
1
)
continue
;
continue
;
bool
mismatch
=
false
;
bool
mismatch
=
false
;
for
(
int
p
=
0
;
p
<
(
int
)
paramTypes
.
size
();
++
p
)
for
(
int
p
=
0
;
p
<
(
int
)
paramTypes
.
size
();
++
p
)
{
{
if
(
paramTypes
[
p
]
!=
type
->
getIdOperand
(
p
+
1
))
{
if
(
paramTypes
[
p
]
!=
type
->
getIdOperand
(
p
+
1
))
{
mismatch
=
true
;
mismatch
=
true
;
break
;
break
;
}
}
}
}
if
(
!
mismatch
)
if
(
!
mismatch
)
return
type
->
getResultId
();
return
type
->
getResultId
();
}
}
...
@@ -383,19 +373,17 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
...
@@ -383,19 +373,17 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
return
type
->
getResultId
();
return
type
->
getResultId
();
}
}
Id
Builder
::
makeImageType
(
Id
sampledType
,
Dim
dim
,
bool
depth
,
bool
arrayed
,
bool
ms
,
Id
Builder
::
makeImageType
(
Id
sampledType
,
Dim
dim
,
bool
depth
,
bool
arrayed
,
bool
ms
,
unsigned
sampled
,
ImageFormat
format
)
unsigned
sampled
,
ImageFormat
format
)
{
{
// try to find it
// try to find it
Instruction
*
type
;
Instruction
*
type
;
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeImage
].
size
();
++
t
)
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeImage
].
size
();
++
t
)
{
{
type
=
groupedTypes
[
OpTypeImage
][
t
];
type
=
groupedTypes
[
OpTypeImage
][
t
];
if
(
type
->
getIdOperand
(
0
)
==
sampledType
&&
if
(
type
->
getIdOperand
(
0
)
==
sampledType
&&
type
->
getImmediateOperand
(
1
)
==
(
unsigned
int
)
dim
&&
type
->
getImmediateOperand
(
1
)
==
(
unsigned
int
)
dim
&&
type
->
getImmediateOperand
(
2
)
==
(
depth
?
1u
:
0u
)
&&
type
->
getImmediateOperand
(
2
)
==
(
depth
?
1u
:
0u
)
&&
type
->
getImmediateOperand
(
3
)
==
(
arrayed
?
1u
:
0u
)
&&
type
->
getImmediateOperand
(
3
)
==
(
arrayed
?
1u
:
0u
)
&&
type
->
getImmediateOperand
(
4
)
==
(
ms
?
1u
:
0u
)
&&
type
->
getImmediateOperand
(
4
)
==
(
ms
?
1u
:
0u
)
&&
type
->
getImmediateOperand
(
5
)
==
sampled
&&
type
->
getImmediateOperand
(
5
)
==
sampled
&&
type
->
getImmediateOperand
(
6
)
==
(
unsigned
int
)
format
)
type
->
getImmediateOperand
(
6
)
==
(
unsigned
int
)
format
)
return
type
->
getResultId
();
return
type
->
getResultId
();
...
@@ -404,10 +392,10 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
...
@@ -404,10 +392,10 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
// not found, make it
// not found, make it
type
=
new
Instruction
(
getUniqueId
(),
NoType
,
OpTypeImage
);
type
=
new
Instruction
(
getUniqueId
(),
NoType
,
OpTypeImage
);
type
->
addIdOperand
(
sampledType
);
type
->
addIdOperand
(
sampledType
);
type
->
addImmediateOperand
(
dim
);
type
->
addImmediateOperand
(
dim
);
type
->
addImmediateOperand
(
depth
?
1
:
0
);
type
->
addImmediateOperand
(
depth
?
1
:
0
);
type
->
addImmediateOperand
(
arrayed
?
1
:
0
);
type
->
addImmediateOperand
(
arrayed
?
1
:
0
);
type
->
addImmediateOperand
(
ms
?
1
:
0
);
type
->
addImmediateOperand
(
ms
?
1
:
0
);
type
->
addImmediateOperand
(
sampled
);
type
->
addImmediateOperand
(
sampled
);
type
->
addImmediateOperand
((
unsigned
int
)
format
);
type
->
addImmediateOperand
((
unsigned
int
)
format
);
...
@@ -416,8 +404,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
...
@@ -416,8 +404,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
module
.
mapInstruction
(
type
);
module
.
mapInstruction
(
type
);
// deal with capabilities
// deal with capabilities
switch
(
dim
)
switch
(
dim
)
{
{
case
DimBuffer
:
case
DimBuffer
:
if
(
sampled
)
if
(
sampled
)
addCapability
(
CapabilitySampledBuffer
);
addCapability
(
CapabilitySampledBuffer
);
...
@@ -431,8 +418,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
...
@@ -431,8 +418,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
addCapability
(
CapabilityImage1D
);
addCapability
(
CapabilityImage1D
);
break
;
break
;
case
DimCube
:
case
DimCube
:
if
(
arrayed
)
if
(
arrayed
)
{
{
if
(
sampled
)
if
(
sampled
)
addCapability
(
CapabilitySampledCubeArray
);
addCapability
(
CapabilitySampledCubeArray
);
else
else
...
@@ -452,11 +438,10 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
...
@@ -452,11 +438,10 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
break
;
break
;
}
}
if
(
ms
)
if
(
ms
)
{
{
if
(
arrayed
)
if
(
arrayed
)
addCapability
(
CapabilityImageMSArray
);
addCapability
(
CapabilityImageMSArray
);
if
(
!
sampled
)
if
(
!
sampled
)
addCapability
(
CapabilityStorageImageMultisample
);
addCapability
(
CapabilityStorageImageMultisample
);
}
}
...
@@ -467,8 +452,7 @@ Id Builder::makeSampledImageType(Id imageType)
...
@@ -467,8 +452,7 @@ Id Builder::makeSampledImageType(Id imageType)
{
{
// try to find it
// try to find it
Instruction
*
type
;
Instruction
*
type
;
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeSampledImage
].
size
();
++
t
)
for
(
int
t
=
0
;
t
<
(
int
)
groupedTypes
[
OpTypeSampledImage
].
size
();
++
t
)
{
{
type
=
groupedTypes
[
OpTypeSampledImage
][
t
];
type
=
groupedTypes
[
OpTypeSampledImage
][
t
];
if
(
type
->
getIdOperand
(
0
)
==
imageType
)
if
(
type
->
getIdOperand
(
0
)
==
imageType
)
return
type
->
getResultId
();
return
type
->
getResultId
();
...
@@ -597,16 +581,20 @@ Id Builder::getContainedTypeId(Id typeId, int member) const
...
@@ -597,16 +581,20 @@ Id Builder::getContainedTypeId(Id typeId, int member) const
}
}
// Return the immediately contained type of a given composite type.
// Return the immediately contained type of a given composite type.
Id
Builder
::
getContainedTypeId
(
Id
typeId
)
const
{
return
getContainedTypeId
(
typeId
,
0
);
}
Id
Builder
::
getContainedTypeId
(
Id
typeId
)
const
{
return
getContainedTypeId
(
typeId
,
0
);
}
// See if a scalar constant of this type has already been created, so it
// See if a scalar constant of this type has already been created, so it
// can be reused rather than duplicated. (Required by the specification).
// can be reused rather than duplicated. (Required by the specification).
Id
Builder
::
findScalarConstant
(
Op
typeClass
,
Op
opcode
,
Id
typeId
,
unsigned
value
)
const
Id
Builder
::
findScalarConstant
(
Op
typeClass
,
Op
opcode
,
Id
typeId
,
unsigned
value
)
const
{
{
Instruction
*
constant
;
Instruction
*
constant
;
for
(
int
i
=
0
;
i
<
(
int
)
groupedConstants
[
typeClass
].
size
();
++
i
)
for
(
int
i
=
0
;
i
<
(
int
)
groupedConstants
[
typeClass
].
size
();
++
i
)
{
{
constant
=
groupedConstants
[
typeClass
][
i
];
constant
=
groupedConstants
[
typeClass
][
i
];
if
(
constant
->
getOpCode
()
==
opcode
&&
constant
->
getTypeId
()
==
typeId
&&
if
(
constant
->
getOpCode
()
==
opcode
&&
constant
->
getTypeId
()
==
typeId
&&
constant
->
getImmediateOperand
(
0
)
==
value
)
constant
->
getImmediateOperand
(
0
)
==
value
)
return
constant
->
getResultId
();
return
constant
->
getResultId
();
}
}
...
@@ -618,11 +606,12 @@ Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned valu
...
@@ -618,11 +606,12 @@ Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned valu
Id
Builder
::
findScalarConstant
(
Op
typeClass
,
Op
opcode
,
Id
typeId
,
unsigned
v1
,
unsigned
v2
)
const
Id
Builder
::
findScalarConstant
(
Op
typeClass
,
Op
opcode
,
Id
typeId
,
unsigned
v1
,
unsigned
v2
)
const
{
{
Instruction
*
constant
;
Instruction
*
constant
;
for
(
int
i
=
0
;
i
<
(
int
)
groupedConstants
[
typeClass
].
size
();
++
i
)
for
(
int
i
=
0
;
i
<
(
int
)
groupedConstants
[
typeClass
].
size
();
++
i
)
{
{
constant
=
groupedConstants
[
typeClass
][
i
];
constant
=
groupedConstants
[
typeClass
][
i
];
if
(
constant
->
getOpCode
()
==
opcode
&&
constant
->
getTypeId
()
==
typeId
&&
if
(
constant
->
getOpCode
()
==
opcode
&&
constant
->
getImmediateOperand
(
0
)
==
v1
&&
constant
->
getImmediateOperand
(
1
)
==
v2
)
constant
->
getTypeId
()
==
typeId
&&
constant
->
getImmediateOperand
(
0
)
==
v1
&&
constant
->
getImmediateOperand
(
1
)
==
v2
)
return
constant
->
getResultId
();
return
constant
->
getResultId
();
}
}
...
@@ -634,9 +623,8 @@ Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1,
...
@@ -634,9 +623,8 @@ Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1,
// the value consumed will be a constant, so includes specialization.
// the value consumed will be a constant, so includes specialization.
bool
Builder
::
isConstantOpCode
(
Op
opcode
)
const
bool
Builder
::
isConstantOpCode
(
Op
opcode
)
const
{
{
switch
(
opcode
)
switch
(
opcode
)
{
{
case
OpUndef
:
case
OpUndef
:
case
OpConstantTrue
:
case
OpConstantTrue
:
case
OpConstantFalse
:
case
OpConstantFalse
:
case
OpConstant
:
case
OpConstant
:
...
@@ -673,16 +661,13 @@ Id Builder::makeBoolConstant(bool b, bool specConstant)
...
@@ -673,16 +661,13 @@ Id Builder::makeBoolConstant(bool b, bool specConstant)
{
{
Id
typeId
=
makeBoolType
();
Id
typeId
=
makeBoolType
();
Instruction
*
constant
;
Instruction
*
constant
;
Op
opcode
=
specConstant
?
(
b
?
OpSpecConstantTrue
:
OpSpecConstantFalse
)
Op
opcode
=
specConstant
?
(
b
?
OpSpecConstantTrue
:
OpSpecConstantFalse
)
:
(
b
?
OpConstantTrue
:
OpConstantFalse
);
:
(
b
?
OpConstantTrue
:
OpConstantFalse
);
// See if we already made it. Applies only to regular constants, because specialization constants
// See if we already made it. Applies only to regular constants, because specialization constants
// must remain distinct for the purpose of applying a SpecId decoration.
// must remain distinct for the purpose of applying a SpecId decoration.
if
(
!
specConstant
)
if
(
!
specConstant
)
{
{
Id
existing
=
0
;
Id
existing
=
0
;
for
(
int
i
=
0
;
i
<
(
int
)
groupedConstants
[
OpTypeBool
].
size
();
++
i
)
for
(
int
i
=
0
;
i
<
(
int
)
groupedConstants
[
OpTypeBool
].
size
();
++
i
)
{
{
constant
=
groupedConstants
[
OpTypeBool
][
i
];
constant
=
groupedConstants
[
OpTypeBool
][
i
];
if
(
constant
->
getTypeId
()
==
typeId
&&
constant
->
getOpCode
()
==
opcode
)
if
(
constant
->
getTypeId
()
==
typeId
&&
constant
->
getOpCode
()
==
opcode
)
existing
=
constant
->
getResultId
();
existing
=
constant
->
getResultId
();
...
@@ -707,8 +692,7 @@ Id Builder::makeIntConstant(Id typeId, unsigned value, bool specConstant)
...
@@ -707,8 +692,7 @@ Id Builder::makeIntConstant(Id typeId, unsigned value, bool specConstant)
// See if we already made it. Applies only to regular constants, because specialization constants
// See if we already made it. Applies only to regular constants, because specialization constants
// must remain distinct for the purpose of applying a SpecId decoration.
// must remain distinct for the purpose of applying a SpecId decoration.
if
(
!
specConstant
)
if
(
!
specConstant
)
{
{
Id
existing
=
findScalarConstant
(
OpTypeInt
,
opcode
,
typeId
,
value
);
Id
existing
=
findScalarConstant
(
OpTypeInt
,
opcode
,
typeId
,
value
);
if
(
existing
)
if
(
existing
)
return
existing
;
return
existing
;
...
@@ -752,17 +736,13 @@ Id Builder::makeFloatConstant(float f, bool specConstant)
...
@@ -752,17 +736,13 @@ Id Builder::makeFloatConstant(float f, bool specConstant)
{
{
Op
opcode
=
specConstant
?
OpSpecConstant
:
OpConstant
;
Op
opcode
=
specConstant
?
OpSpecConstant
:
OpConstant
;
Id
typeId
=
makeFloatType
(
32
);
Id
typeId
=
makeFloatType
(
32
);
union
{
union
{
float
fl
;
unsigned
int
ui
;
}
u
;
float
fl
;
unsigned
int
ui
;
}
u
;
u
.
fl
=
f
;
u
.
fl
=
f
;
unsigned
value
=
u
.
ui
;
unsigned
value
=
u
.
ui
;
// See if we already made it. Applies only to regular constants, because specialization constants
// See if we already made it. Applies only to regular constants, because specialization constants
// must remain distinct for the purpose of applying a SpecId decoration.
// must remain distinct for the purpose of applying a SpecId decoration.
if
(
!
specConstant
)
if
(
!
specConstant
)
{
{
Id
existing
=
findScalarConstant
(
OpTypeFloat
,
opcode
,
typeId
,
value
);
Id
existing
=
findScalarConstant
(
OpTypeFloat
,
opcode
,
typeId
,
value
);
if
(
existing
)
if
(
existing
)
return
existing
;
return
existing
;
...
@@ -781,10 +761,7 @@ Id Builder::makeDoubleConstant(double d, bool specConstant)
...
@@ -781,10 +761,7 @@ Id Builder::makeDoubleConstant(double d, bool specConstant)
{
{
Op
opcode
=
specConstant
?
OpSpecConstant
:
OpConstant
;
Op
opcode
=
specConstant
?
OpSpecConstant
:
OpConstant
;
Id
typeId
=
makeFloatType
(
64
);
Id
typeId
=
makeFloatType
(
64
);
union
{
union
{
double
db
;
unsigned
long
long
ull
;
}
u
;
double
db
;
unsigned
long
long
ull
;
}
u
;
u
.
db
=
d
;
u
.
db
=
d
;
unsigned
long
long
value
=
u
.
ull
;
unsigned
long
long
value
=
u
.
ull
;
unsigned
op1
=
value
&
0xFFFFFFFF
;
unsigned
op1
=
value
&
0xFFFFFFFF
;
...
@@ -792,8 +769,7 @@ Id Builder::makeDoubleConstant(double d, bool specConstant)
...
@@ -792,8 +769,7 @@ Id Builder::makeDoubleConstant(double d, bool specConstant)
// See if we already made it. Applies only to regular constants, because specialization constants
// See if we already made it. Applies only to regular constants, because specialization constants
// must remain distinct for the purpose of applying a SpecId decoration.
// must remain distinct for the purpose of applying a SpecId decoration.
if
(
!
specConstant
)
if
(
!
specConstant
)
{
{
Id
existing
=
findScalarConstant
(
OpTypeFloat
,
opcode
,
typeId
,
op1
,
op2
);
Id
existing
=
findScalarConstant
(
OpTypeFloat
,
opcode
,
typeId
,
op1
,
op2
);
if
(
existing
)
if
(
existing
)
return
existing
;
return
existing
;
...
@@ -813,8 +789,7 @@ Id Builder::findCompositeConstant(Op typeClass, std::vector<Id>& comps) const
...
@@ -813,8 +789,7 @@ Id Builder::findCompositeConstant(Op typeClass, std::vector<Id>& comps) const
{
{
Instruction
*
constant
=
0
;
Instruction
*
constant
=
0
;
bool
found
=
false
;
bool
found
=
false
;
for
(
int
i
=
0
;
i
<
(
int
)
groupedConstants
[
typeClass
].
size
();
++
i
)
for
(
int
i
=
0
;
i
<
(
int
)
groupedConstants
[
typeClass
].
size
();
++
i
)
{
{
constant
=
groupedConstants
[
typeClass
][
i
];
constant
=
groupedConstants
[
typeClass
][
i
];
// same shape?
// same shape?
...
@@ -823,16 +798,13 @@ Id Builder::findCompositeConstant(Op typeClass, std::vector<Id>& comps) const
...
@@ -823,16 +798,13 @@ Id Builder::findCompositeConstant(Op typeClass, std::vector<Id>& comps) const
// same contents?
// same contents?
bool
mismatch
=
false
;
bool
mismatch
=
false
;
for
(
int
op
=
0
;
op
<
constant
->
getNumOperands
();
++
op
)
for
(
int
op
=
0
;
op
<
constant
->
getNumOperands
();
++
op
)
{
{
if
(
constant
->
getIdOperand
(
op
)
!=
comps
[
op
])
{
if
(
constant
->
getIdOperand
(
op
)
!=
comps
[
op
])
{
mismatch
=
true
;
mismatch
=
true
;
break
;
break
;
}
}
}
}
if
(
!
mismatch
)
if
(
!
mismatch
)
{
{
found
=
true
;
found
=
true
;
break
;
break
;
}
}
...
@@ -848,8 +820,7 @@ Id Builder::makeCompositeConstant(Id typeId, std::vector<Id>& members, bool spec
...
@@ -848,8 +820,7 @@ Id Builder::makeCompositeConstant(Id typeId, std::vector<Id>& members, bool spec
assert
(
typeId
);
assert
(
typeId
);
Op
typeClass
=
getTypeClass
(
typeId
);
Op
typeClass
=
getTypeClass
(
typeId
);
switch
(
typeClass
)
switch
(
typeClass
)
{
{
case
OpTypeVector
:
case
OpTypeVector
:
case
OpTypeArray
:
case
OpTypeArray
:
case
OpTypeStruct
:
case
OpTypeStruct
:
...
@@ -860,8 +831,7 @@ Id Builder::makeCompositeConstant(Id typeId, std::vector<Id>& members, bool spec
...
@@ -860,8 +831,7 @@ Id Builder::makeCompositeConstant(Id typeId, std::vector<Id>& members, bool spec
return
makeFloatConstant
(
0.0
);
return
makeFloatConstant
(
0.0
);
}
}
if
(
!
specConstant
)
if
(
!
specConstant
)
{
{
Id
existing
=
findCompositeConstant
(
typeClass
,
members
);
Id
existing
=
findCompositeConstant
(
typeClass
,
members
);
if
(
existing
)
if
(
existing
)
return
existing
;
return
existing
;
...
@@ -890,8 +860,7 @@ Instruction* Builder::addEntryPoint(ExecutionModel model, Function* function, co
...
@@ -890,8 +860,7 @@ Instruction* Builder::addEntryPoint(ExecutionModel model, Function* function, co
}
}
// Currently relying on the fact that all 'value' of interest are small non-negative values.
// Currently relying on the fact that all 'value' of interest are small non-negative values.
void
Builder
::
addExecutionMode
(
Function
*
entryPoint
,
ExecutionMode
mode
,
int
value1
,
int
value2
,
void
Builder
::
addExecutionMode
(
Function
*
entryPoint
,
ExecutionMode
mode
,
int
value1
,
int
value2
,
int
value3
)
int
value3
)
{
{
Instruction
*
instr
=
new
Instruction
(
OpExecutionMode
);
Instruction
*
instr
=
new
Instruction
(
OpExecutionMode
);
instr
->
addIdOperand
(
entryPoint
->
getId
());
instr
->
addIdOperand
(
entryPoint
->
getId
());
...
@@ -964,7 +933,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
...
@@ -964,7 +933,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
// Comments in header
// Comments in header
Function
*
Builder
::
makeEntrypoint
(
const
char
*
entryPoint
)
Function
*
Builder
::
makeEntrypoint
(
const
char
*
entryPoint
)
{
{
assert
(
!
mainFunction
);
assert
(
!
mainFunction
);
Block
*
entry
;
Block
*
entry
;
std
::
vector
<
Id
>
params
;
std
::
vector
<
Id
>
params
;
...
@@ -977,8 +946,7 @@ Function* Builder::makeEntrypoint(const char* entryPoint)
...
@@ -977,8 +946,7 @@ Function* Builder::makeEntrypoint(const char* entryPoint)
// Comments in header
// Comments in header
Function
*
Builder
::
makeFunctionEntry
(
Decoration
precision
,
Id
returnType
,
const
char
*
name
,
Function
*
Builder
::
makeFunctionEntry
(
Decoration
precision
,
Id
returnType
,
const
char
*
name
,
const
std
::
vector
<
Id
>&
paramTypes
,
const
std
::
vector
<
Id
>&
paramTypes
,
const
std
::
vector
<
Decoration
>&
precisions
,
Block
**
entry
)
const
std
::
vector
<
Decoration
>&
precisions
,
Block
**
entry
)
{
{
// Make the function and initial instructions in it
// Make the function and initial instructions in it
Id
typeId
=
makeFunctionType
(
returnType
,
paramTypes
);
Id
typeId
=
makeFunctionType
(
returnType
,
paramTypes
);
...
@@ -991,8 +959,7 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
...
@@ -991,8 +959,7 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
setPrecision
(
firstParamId
+
p
,
precisions
[
p
]);
setPrecision
(
firstParamId
+
p
,
precisions
[
p
]);
// CFG
// CFG
if
(
entry
)
if
(
entry
)
{
{
*
entry
=
new
Block
(
getUniqueId
(),
*
function
);
*
entry
=
new
Block
(
getUniqueId
(),
*
function
);
function
->
addBlock
(
*
entry
);
function
->
addBlock
(
*
entry
);
setBuildPoint
(
*
entry
);
setBuildPoint
(
*
entry
);
...
@@ -1009,16 +976,14 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
...
@@ -1009,16 +976,14 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
// Comments in header
// Comments in header
void
Builder
::
makeReturn
(
bool
implicit
,
Id
retVal
)
void
Builder
::
makeReturn
(
bool
implicit
,
Id
retVal
)
{
{
if
(
retVal
)
if
(
retVal
)
{
{
Instruction
*
inst
=
new
Instruction
(
NoResult
,
NoType
,
OpReturnValue
);
Instruction
*
inst
=
new
Instruction
(
NoResult
,
NoType
,
OpReturnValue
);
inst
->
addIdOperand
(
retVal
);
inst
->
addIdOperand
(
retVal
);
buildPoint
->
addInstruction
(
std
::
unique_ptr
<
Instruction
>
(
inst
));
buildPoint
->
addInstruction
(
std
::
unique_ptr
<
Instruction
>
(
inst
));
}
else
}
else
buildPoint
->
addInstruction
(
buildPoint
->
addInstruction
(
std
::
unique_ptr
<
Instruction
>
(
new
Instruction
(
NoResult
,
NoType
,
OpReturn
)));
std
::
unique_ptr
<
Instruction
>
(
new
Instruction
(
NoResult
,
NoType
,
OpReturn
)));
if
(
!
implicit
)
if
(
!
implicit
)
createAndSetNoPredecessorBlock
(
"post-return"
);
createAndSetNoPredecessorBlock
(
"post-return"
);
}
}
...
@@ -1030,12 +995,10 @@ void Builder::leaveFunction()
...
@@ -1030,12 +995,10 @@ void Builder::leaveFunction()
assert
(
block
);
assert
(
block
);
// If our function did not contain a return, add a return void now.
// If our function did not contain a return, add a return void now.
if
(
!
block
->
isTerminated
())
if
(
!
block
->
isTerminated
())
{
{
if
(
function
.
getReturnType
()
==
makeVoidType
())
if
(
function
.
getReturnType
()
==
makeVoidType
())
makeReturn
(
true
);
makeReturn
(
true
);
else
else
{
{
makeReturn
(
true
,
createUndefined
(
function
.
getReturnType
()));
makeReturn
(
true
,
createUndefined
(
function
.
getReturnType
()));
}
}
}
}
...
@@ -1055,8 +1018,7 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name)
...
@@ -1055,8 +1018,7 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name)
Instruction
*
inst
=
new
Instruction
(
getUniqueId
(),
pointerType
,
OpVariable
);
Instruction
*
inst
=
new
Instruction
(
getUniqueId
(),
pointerType
,
OpVariable
);
inst
->
addImmediateOperand
(
storageClass
);
inst
->
addImmediateOperand
(
storageClass
);
switch
(
storageClass
)
switch
(
storageClass
)
{
{
case
StorageClassFunction
:
case
StorageClassFunction
:
// Validation rules require the declaration in the entry block
// Validation rules require the declaration in the entry block
buildPoint
->
getParent
().
addLocalVariable
(
std
::
unique_ptr
<
Instruction
>
(
inst
));
buildPoint
->
getParent
().
addLocalVariable
(
std
::
unique_ptr
<
Instruction
>
(
inst
));
...
@@ -1077,9 +1039,9 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name)
...
@@ -1077,9 +1039,9 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name)
// Comments in header
// Comments in header
Id
Builder
::
createUndefined
(
Id
type
)
Id
Builder
::
createUndefined
(
Id
type
)
{
{
Instruction
*
inst
=
new
Instruction
(
getUniqueId
(),
type
,
OpUndef
);
Instruction
*
inst
=
new
Instruction
(
getUniqueId
(),
type
,
OpUndef
);
buildPoint
->
addInstruction
(
std
::
unique_ptr
<
Instruction
>
(
inst
));
buildPoint
->
addInstruction
(
std
::
unique_ptr
<
Instruction
>
(
inst
));
return
inst
->
getResultId
();
return
inst
->
getResultId
();
}
}
// Comments in header
// Comments in header
...
@@ -1108,10 +1070,8 @@ Id Builder::createAccessChain(StorageClass storageClass, Id base, std::vector<Id
...
@@ -1108,10 +1070,8 @@ Id Builder::createAccessChain(StorageClass storageClass, Id base, std::vector<Id
spv
::
Id
typeId
=
getTypeId
(
base
);
spv
::
Id
typeId
=
getTypeId
(
base
);
assert
(
isPointerType
(
typeId
)
&&
offsets
.
size
()
>
0
);
assert
(
isPointerType
(
typeId
)
&&
offsets
.
size
()
>
0
);
typeId
=
getContainedTypeId
(
typeId
);
typeId
=
getContainedTypeId
(
typeId
);
for
(
int
i
=
0
;
i
<
(
int
)
offsets
.
size
();
++
i
)
for
(
int
i
=
0
;
i
<
(
int
)
offsets
.
size
();
++
i
)
{
{
if
(
isStructType
(
typeId
))
{
if
(
isStructType
(
typeId
))
{
assert
(
isConstantScalar
(
offsets
[
i
]));
assert
(
isConstantScalar
(
offsets
[
i
]));
typeId
=
getContainedTypeId
(
typeId
,
getConstantScalar
(
offsets
[
i
]));
typeId
=
getContainedTypeId
(
typeId
,
getConstantScalar
(
offsets
[
i
]));
}
else
}
else
...
@@ -1181,8 +1141,7 @@ Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, unsigned i
...
@@ -1181,8 +1141,7 @@ Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, unsigned i
return
insert
->
getResultId
();
return
insert
->
getResultId
();
}
}
Id
Builder
::
createCompositeInsert
(
Id
object
,
Id
composite
,
Id
typeId
,
Id
Builder
::
createCompositeInsert
(
Id
object
,
Id
composite
,
Id
typeId
,
std
::
vector
<
unsigned
>&
indexes
)
std
::
vector
<
unsigned
>&
indexes
)
{
{
Instruction
*
insert
=
new
Instruction
(
getUniqueId
(),
typeId
,
OpCompositeInsert
);
Instruction
*
insert
=
new
Instruction
(
getUniqueId
(),
typeId
,
OpCompositeInsert
);
insert
->
addIdOperand
(
object
);
insert
->
addIdOperand
(
object
);
...
@@ -1345,8 +1304,7 @@ Id Builder::createFunctionCall(spv::Function* function, std::vector<spv::Id>& ar
...
@@ -1345,8 +1304,7 @@ Id Builder::createFunctionCall(spv::Function* function, std::vector<spv::Id>& ar
}
}
// Comments in header
// Comments in header
Id
Builder
::
createRvalueSwizzle
(
Decoration
precision
,
Id
typeId
,
Id
source
,
Id
Builder
::
createRvalueSwizzle
(
Decoration
precision
,
Id
typeId
,
Id
source
,
std
::
vector
<
unsigned
>&
channels
)
std
::
vector
<
unsigned
>&
channels
)
{
{
if
(
channels
.
size
()
==
1
)
if
(
channels
.
size
()
==
1
)
return
setPrecision
(
createCompositeExtract
(
source
,
typeId
,
channels
.
front
()),
precision
);
return
setPrecision
(
createCompositeExtract
(
source
,
typeId
,
channels
.
front
()),
precision
);
...
@@ -1404,11 +1362,9 @@ void Builder::promoteScalar(Decoration precision, Id& left, Id& right)
...
@@ -1404,11 +1362,9 @@ void Builder::promoteScalar(Decoration precision, Id& left, Id& right)
int
direction
=
getNumComponents
(
right
)
-
getNumComponents
(
left
);
int
direction
=
getNumComponents
(
right
)
-
getNumComponents
(
left
);
if
(
direction
>
0
)
if
(
direction
>
0
)
left
=
left
=
smearScalar
(
precision
,
left
,
makeVectorType
(
getTypeId
(
left
),
getNumComponents
(
right
)));
smearScalar
(
precision
,
left
,
makeVectorType
(
getTypeId
(
left
),
getNumComponents
(
right
)));
else
if
(
direction
<
0
)
else
if
(
direction
<
0
)
right
=
right
=
smearScalar
(
precision
,
right
,
makeVectorType
(
getTypeId
(
right
),
getNumComponents
(
left
)));
smearScalar
(
precision
,
right
,
makeVectorType
(
getTypeId
(
right
),
getNumComponents
(
left
)));
return
;
return
;
}
}
...
@@ -1462,9 +1418,7 @@ Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, std::v
...
@@ -1462,9 +1418,7 @@ Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, std::v
// Accept all parameters needed to create a texture instruction.
// Accept all parameters needed to create a texture instruction.
// Create the correct instruction based on the inputs, and make the call.
// Create the correct instruction based on the inputs, and make the call.
Id
Builder
::
createTextureCall
(
Decoration
precision
,
Id
resultType
,
bool
sparse
,
bool
fetch
,
Id
Builder
::
createTextureCall
(
Decoration
precision
,
Id
resultType
,
bool
sparse
,
bool
fetch
,
bool
proj
,
bool
gather
,
bool
noImplicitLod
,
const
TextureParameters
&
parameters
)
bool
proj
,
bool
gather
,
bool
noImplicitLod
,
const
TextureParameters
&
parameters
)
{
{
static
const
int
maxTextureArgs
=
10
;
static
const
int
maxTextureArgs
=
10
;
Id
texArgs
[
maxTextureArgs
]
=
{};
Id
texArgs
[
maxTextureArgs
]
=
{};
...
@@ -1484,36 +1438,30 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
...
@@ -1484,36 +1438,30 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
//
//
// Set up the optional arguments
// Set up the optional arguments
//
//
int
optArgNum
=
int
optArgNum
=
numArgs
;
// track which operand, if it exists, is the mask of optional arguments
numArgs
;
// track which operand, if it exists, is the mask of optional arguments
++
numArgs
;
// speculatively make room for the mask operand
++
numArgs
;
// speculatively make room for the mask operand
ImageOperandsMask
mask
=
ImageOperandsMaskNone
;
// the mask operand
ImageOperandsMask
mask
=
ImageOperandsMaskNone
;
// the mask operand
if
(
parameters
.
bias
)
{
if
(
parameters
.
bias
)
{
mask
=
(
ImageOperandsMask
)(
mask
|
ImageOperandsBiasMask
);
mask
=
(
ImageOperandsMask
)(
mask
|
ImageOperandsBiasMask
);
texArgs
[
numArgs
++
]
=
parameters
.
bias
;
texArgs
[
numArgs
++
]
=
parameters
.
bias
;
}
}
if
(
parameters
.
lod
)
if
(
parameters
.
lod
)
{
{
mask
=
(
ImageOperandsMask
)(
mask
|
ImageOperandsLodMask
);
mask
=
(
ImageOperandsMask
)(
mask
|
ImageOperandsLodMask
);
texArgs
[
numArgs
++
]
=
parameters
.
lod
;
texArgs
[
numArgs
++
]
=
parameters
.
lod
;
explicitLod
=
true
;
explicitLod
=
true
;
}
else
if
(
parameters
.
gradX
)
}
else
if
(
parameters
.
gradX
)
{
{
mask
=
(
ImageOperandsMask
)(
mask
|
ImageOperandsGradMask
);
mask
=
(
ImageOperandsMask
)(
mask
|
ImageOperandsGradMask
);
texArgs
[
numArgs
++
]
=
parameters
.
gradX
;
texArgs
[
numArgs
++
]
=
parameters
.
gradX
;
texArgs
[
numArgs
++
]
=
parameters
.
gradY
;
texArgs
[
numArgs
++
]
=
parameters
.
gradY
;
explicitLod
=
true
;
explicitLod
=
true
;
}
else
if
(
noImplicitLod
&&
!
fetch
&&
!
gather
)
}
else
if
(
noImplicitLod
&&
!
fetch
&&
!
gather
)
{
{
// have to explicitly use lod of 0 if not allowed to have them be implicit, and
// have to explicitly use lod of 0 if not allowed to have them be implicit, and
// we would otherwise be about to issue an implicit instruction
// we would otherwise be about to issue an implicit instruction
mask
=
(
ImageOperandsMask
)(
mask
|
ImageOperandsLodMask
);
mask
=
(
ImageOperandsMask
)(
mask
|
ImageOperandsLodMask
);
texArgs
[
numArgs
++
]
=
makeFloatConstant
(
0.0
);
texArgs
[
numArgs
++
]
=
makeFloatConstant
(
0.0
);
explicitLod
=
true
;
explicitLod
=
true
;
}
}
if
(
parameters
.
offset
)
if
(
parameters
.
offset
)
{
{
if
(
isConstant
(
parameters
.
offset
))
if
(
isConstant
(
parameters
.
offset
))
mask
=
(
ImageOperandsMask
)(
mask
|
ImageOperandsConstOffsetMask
);
mask
=
(
ImageOperandsMask
)(
mask
|
ImageOperandsConstOffsetMask
);
else
{
else
{
...
@@ -1522,18 +1470,15 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
...
@@ -1522,18 +1470,15 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
}
}
texArgs
[
numArgs
++
]
=
parameters
.
offset
;
texArgs
[
numArgs
++
]
=
parameters
.
offset
;
}
}
if
(
parameters
.
offsets
)
if
(
parameters
.
offsets
)
{
{
mask
=
(
ImageOperandsMask
)(
mask
|
ImageOperandsConstOffsetsMask
);
mask
=
(
ImageOperandsMask
)(
mask
|
ImageOperandsConstOffsetsMask
);
texArgs
[
numArgs
++
]
=
parameters
.
offsets
;
texArgs
[
numArgs
++
]
=
parameters
.
offsets
;
}
}
if
(
parameters
.
sample
)
if
(
parameters
.
sample
)
{
{
mask
=
(
ImageOperandsMask
)(
mask
|
ImageOperandsSampleMask
);
mask
=
(
ImageOperandsMask
)(
mask
|
ImageOperandsSampleMask
);
texArgs
[
numArgs
++
]
=
parameters
.
sample
;
texArgs
[
numArgs
++
]
=
parameters
.
sample
;
}
}
if
(
parameters
.
lodClamp
)
if
(
parameters
.
lodClamp
)
{
{
// capability if this bit is used
// capability if this bit is used
addCapability
(
CapabilityMinLod
);
addCapability
(
CapabilityMinLod
);
...
@@ -1549,72 +1494,69 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
...
@@ -1549,72 +1494,69 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
// Set up the instruction
// Set up the instruction
//
//
Op
opCode
=
OpNop
;
// All paths below need to set this
Op
opCode
=
OpNop
;
// All paths below need to set this
if
(
fetch
)
if
(
fetch
)
{
{
if
(
sparse
)
if
(
sparse
)
opCode
=
OpImageSparseFetch
;
opCode
=
OpImageSparseFetch
;
else
else
opCode
=
OpImageFetch
;
opCode
=
OpImageFetch
;
}
else
if
(
gather
)
}
else
if
(
gather
)
{
{
if
(
parameters
.
Dref
)
if
(
parameters
.
Dref
)
if
(
sparse
)
if
(
sparse
)
opCode
=
OpImageSparseDrefGather
;
opCode
=
OpImageSparseDrefGather
;
else
else
opCode
=
OpImageDrefGather
;
opCode
=
OpImageDrefGather
;
else
if
(
sparse
)
opCode
=
OpImageSparseGather
;
else
else
opCode
=
OpImageGather
;
if
(
sparse
)
}
else
if
(
explicitLod
)
opCode
=
OpImageSparseGather
;
{
else
if
(
parameters
.
Dref
)
opCode
=
OpImageGather
;
{
}
else
if
(
explicitLod
)
{
if
(
parameters
.
Dref
)
{
if
(
proj
)
if
(
proj
)
if
(
sparse
)
if
(
sparse
)
opCode
=
OpImageSparseSampleProjDrefExplicitLod
;
opCode
=
OpImageSparseSampleProjDrefExplicitLod
;
else
else
opCode
=
OpImageSampleProjDrefExplicitLod
;
opCode
=
OpImageSampleProjDrefExplicitLod
;
else
if
(
sparse
)
opCode
=
OpImageSparseSampleDrefExplicitLod
;
else
else
opCode
=
OpImageSampleDrefExplicitLod
;
if
(
sparse
)
}
else
opCode
=
OpImageSparseSampleDrefExplicitLod
;
{
else
opCode
=
OpImageSampleDrefExplicitLod
;
}
else
{
if
(
proj
)
if
(
proj
)
if
(
sparse
)
if
(
sparse
)
opCode
=
OpImageSparseSampleProjExplicitLod
;
opCode
=
OpImageSparseSampleProjExplicitLod
;
else
else
opCode
=
OpImageSampleProjExplicitLod
;
opCode
=
OpImageSampleProjExplicitLod
;
else
if
(
sparse
)
opCode
=
OpImageSparseSampleExplicitLod
;
else
else
opCode
=
OpImageSampleExplicitLod
;
if
(
sparse
)
opCode
=
OpImageSparseSampleExplicitLod
;
else
opCode
=
OpImageSampleExplicitLod
;
}
}
}
else
}
else
{
{
if
(
parameters
.
Dref
)
{
if
(
parameters
.
Dref
)
{
if
(
proj
)
if
(
proj
)
if
(
sparse
)
if
(
sparse
)
opCode
=
OpImageSparseSampleProjDrefImplicitLod
;
opCode
=
OpImageSparseSampleProjDrefImplicitLod
;
else
else
opCode
=
OpImageSampleProjDrefImplicitLod
;
opCode
=
OpImageSampleProjDrefImplicitLod
;
else
if
(
sparse
)
opCode
=
OpImageSparseSampleDrefImplicitLod
;
else
else
opCode
=
OpImageSampleDrefImplicitLod
;
if
(
sparse
)
}
else
opCode
=
OpImageSparseSampleDrefImplicitLod
;
{
else
opCode
=
OpImageSampleDrefImplicitLod
;
}
else
{
if
(
proj
)
if
(
proj
)
if
(
sparse
)
if
(
sparse
)
opCode
=
OpImageSparseSampleProjImplicitLod
;
opCode
=
OpImageSparseSampleProjImplicitLod
;
else
else
opCode
=
OpImageSampleProjImplicitLod
;
opCode
=
OpImageSampleProjImplicitLod
;
else
if
(
sparse
)
opCode
=
OpImageSparseSampleImplicitLod
;
else
else
opCode
=
OpImageSampleImplicitLod
;
if
(
sparse
)
opCode
=
OpImageSparseSampleImplicitLod
;
else
opCode
=
OpImageSampleImplicitLod
;
}
}
}
}
...
@@ -1622,10 +1564,8 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
...
@@ -1622,10 +1564,8 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
// This happens when a legacy shadow*() call is made, which
// This happens when a legacy shadow*() call is made, which
// gets a vec4 back instead of a float.
// gets a vec4 back instead of a float.
Id
smearedType
=
resultType
;
Id
smearedType
=
resultType
;
if
(
!
isScalarType
(
resultType
))
if
(
!
isScalarType
(
resultType
))
{
{
switch
(
opCode
)
{
switch
(
opCode
)
{
case
OpImageSampleDrefImplicitLod
:
case
OpImageSampleDrefImplicitLod
:
case
OpImageSampleDrefExplicitLod
:
case
OpImageSampleDrefExplicitLod
:
case
OpImageSampleProjDrefImplicitLod
:
case
OpImageSampleProjDrefImplicitLod
:
...
@@ -1640,8 +1580,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
...
@@ -1640,8 +1580,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
Id
typeId0
=
0
;
Id
typeId0
=
0
;
Id
typeId1
=
0
;
Id
typeId1
=
0
;
if
(
sparse
)
if
(
sparse
)
{
{
typeId0
=
resultType
;
typeId0
=
resultType
;
typeId1
=
getDerefTypeId
(
parameters
.
texelOut
);
typeId1
=
getDerefTypeId
(
parameters
.
texelOut
);
resultType
=
makeStructResultType
(
typeId0
,
typeId1
);
resultType
=
makeStructResultType
(
typeId0
,
typeId1
);
...
@@ -1660,8 +1599,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
...
@@ -1660,8 +1599,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
Id
resultId
=
textureInst
->
getResultId
();
Id
resultId
=
textureInst
->
getResultId
();
if
(
sparse
)
if
(
sparse
)
{
{
// set capability
// set capability
addCapability
(
CapabilitySparseResidency
);
addCapability
(
CapabilitySparseResidency
);
...
@@ -1669,8 +1607,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
...
@@ -1669,8 +1607,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
createStore
(
createCompositeExtract
(
resultId
,
typeId1
,
1
),
parameters
.
texelOut
);
createStore
(
createCompositeExtract
(
resultId
,
typeId1
,
1
),
parameters
.
texelOut
);
resultId
=
createCompositeExtract
(
resultId
,
typeId0
,
0
);
resultId
=
createCompositeExtract
(
resultId
,
typeId0
,
0
);
setPrecision
(
resultId
,
precision
);
setPrecision
(
resultId
,
precision
);
}
else
}
else
{
{
// When a smear is needed, do it, as per what was computed
// When a smear is needed, do it, as per what was computed
// above when resultType was changed to a scalar type.
// above when resultType was changed to a scalar type.
if
(
resultType
!=
smearedType
)
if
(
resultType
!=
smearedType
)
...
@@ -1688,14 +1625,12 @@ Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameter
...
@@ -1688,14 +1625,12 @@ Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameter
// Figure out the result type
// Figure out the result type
Id
resultType
=
0
;
Id
resultType
=
0
;
switch
(
opCode
)
switch
(
opCode
)
{
{
case
OpImageQuerySize
:
case
OpImageQuerySize
:
case
OpImageQuerySizeLod
:
case
OpImageQuerySizeLod
:
{
{
int
numComponents
=
0
;
int
numComponents
=
0
;
switch
(
getTypeDimensionality
(
getImageType
(
parameters
.
sampler
)))
switch
(
getTypeDimensionality
(
getImageType
(
parameters
.
sampler
)))
{
{
case
Dim1D
:
case
Dim1D
:
case
DimBuffer
:
case
DimBuffer
:
numComponents
=
1
;
numComponents
=
1
;
...
@@ -1759,14 +1694,12 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
...
@@ -1759,14 +1694,12 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
// Scalars and Vectors
// Scalars and Vectors
if
(
isScalarType
(
valueType
)
||
isVectorType
(
valueType
))
if
(
isScalarType
(
valueType
)
||
isVectorType
(
valueType
))
{
{
assert
(
valueType
==
getTypeId
(
value2
));
assert
(
valueType
==
getTypeId
(
value2
));
// These just need a single comparison, just have
// These just need a single comparison, just have
// to figure out what it is.
// to figure out what it is.
Op
op
;
Op
op
;
switch
(
getMostBasicTypeClass
(
valueType
))
switch
(
getMostBasicTypeClass
(
valueType
))
{
{
case
OpTypeFloat
:
case
OpTypeFloat
:
op
=
equal
?
OpFOrdEqual
:
OpFOrdNotEqual
;
op
=
equal
?
OpFOrdEqual
:
OpFOrdNotEqual
;
break
;
break
;
...
@@ -1780,12 +1713,10 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
...
@@ -1780,12 +1713,10 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
break
;
break
;
}
}
if
(
isScalarType
(
valueType
))
if
(
isScalarType
(
valueType
))
{
{
// scalar
// scalar
resultId
=
createBinOp
(
op
,
boolType
,
value1
,
value2
);
resultId
=
createBinOp
(
op
,
boolType
,
value1
,
value2
);
}
else
}
else
{
{
// vector
// vector
resultId
=
createBinOp
(
op
,
makeVectorType
(
boolType
,
numConstituents
),
value1
,
value2
);
resultId
=
createBinOp
(
op
,
makeVectorType
(
boolType
,
numConstituents
),
value1
,
value2
);
setPrecision
(
resultId
,
precision
);
setPrecision
(
resultId
,
precision
);
...
@@ -1801,8 +1732,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
...
@@ -1801,8 +1732,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
assert
(
isAggregateType
(
valueType
)
||
isMatrixType
(
valueType
));
assert
(
isAggregateType
(
valueType
)
||
isMatrixType
(
valueType
));
// Compare each pair of constituents
// Compare each pair of constituents
for
(
int
constituent
=
0
;
constituent
<
numConstituents
;
++
constituent
)
for
(
int
constituent
=
0
;
constituent
<
numConstituents
;
++
constituent
)
{
{
std
::
vector
<
unsigned
>
indexes
(
1
,
constituent
);
std
::
vector
<
unsigned
>
indexes
(
1
,
constituent
);
Id
constituentType1
=
getContainedTypeId
(
getTypeId
(
value1
),
constituent
);
Id
constituentType1
=
getContainedTypeId
(
getTypeId
(
value1
),
constituent
);
Id
constituentType2
=
getContainedTypeId
(
getTypeId
(
value2
),
constituent
);
Id
constituentType2
=
getContainedTypeId
(
getTypeId
(
value2
),
constituent
);
...
@@ -1814,9 +1744,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
...
@@ -1814,9 +1744,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
if
(
constituent
==
0
)
if
(
constituent
==
0
)
resultId
=
subResultId
;
resultId
=
subResultId
;
else
else
resultId
=
setPrecision
(
resultId
=
setPrecision
(
createBinOp
(
equal
?
OpLogicalAnd
:
OpLogicalOr
,
boolType
,
resultId
,
subResultId
),
precision
);
createBinOp
(
equal
?
OpLogicalAnd
:
OpLogicalOr
,
boolType
,
resultId
,
subResultId
),
precision
);
}
}
return
resultId
;
return
resultId
;
...
@@ -1825,8 +1753,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
...
@@ -1825,8 +1753,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
// OpCompositeConstruct
// OpCompositeConstruct
Id
Builder
::
createCompositeConstruct
(
Id
typeId
,
std
::
vector
<
Id
>&
constituents
)
Id
Builder
::
createCompositeConstruct
(
Id
typeId
,
std
::
vector
<
Id
>&
constituents
)
{
{
assert
(
isAggregateType
(
typeId
)
||
(
getNumTypeConstituents
(
typeId
)
>
1
&&
assert
(
isAggregateType
(
typeId
)
||
(
getNumTypeConstituents
(
typeId
)
>
1
&&
getNumTypeConstituents
(
typeId
)
==
(
int
)
constituents
.
size
()));
getNumTypeConstituents
(
typeId
)
==
(
int
)
constituents
.
size
()));
if
(
generatingOpCodeForSpecConst
)
{
if
(
generatingOpCodeForSpecConst
)
{
// Sometime, even in spec-constant-op mode, the constant composite to be
// Sometime, even in spec-constant-op mode, the constant composite to be
...
@@ -1864,19 +1791,16 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc
...
@@ -1864,19 +1791,16 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc
Id
scalarTypeId
=
getScalarTypeId
(
resultTypeId
);
Id
scalarTypeId
=
getScalarTypeId
(
resultTypeId
);
std
::
vector
<
Id
>
constituents
;
// accumulate the arguments for OpCompositeConstruct
std
::
vector
<
Id
>
constituents
;
// accumulate the arguments for OpCompositeConstruct
for
(
unsigned
int
i
=
0
;
i
<
sources
.
size
();
++
i
)
for
(
unsigned
int
i
=
0
;
i
<
sources
.
size
();
++
i
)
{
{
assert
(
!
isAggregate
(
sources
[
i
]));
assert
(
!
isAggregate
(
sources
[
i
]));
unsigned
int
sourceSize
=
getNumComponents
(
sources
[
i
]);
unsigned
int
sourceSize
=
getNumComponents
(
sources
[
i
]);
unsigned
int
sourcesToUse
=
sourceSize
;
unsigned
int
sourcesToUse
=
sourceSize
;
if
(
sourcesToUse
+
targetComponent
>
numTargetComponents
)
if
(
sourcesToUse
+
targetComponent
>
numTargetComponents
)
sourcesToUse
=
numTargetComponents
-
targetComponent
;
sourcesToUse
=
numTargetComponents
-
targetComponent
;
for
(
unsigned
int
s
=
0
;
s
<
sourcesToUse
;
++
s
)
for
(
unsigned
int
s
=
0
;
s
<
sourcesToUse
;
++
s
)
{
{
Id
arg
=
sources
[
i
];
Id
arg
=
sources
[
i
];
if
(
sourceSize
>
1
)
if
(
sourceSize
>
1
)
{
{
std
::
vector
<
unsigned
>
swiz
;
std
::
vector
<
unsigned
>
swiz
;
swiz
.
push_back
(
s
);
swiz
.
push_back
(
s
);
arg
=
createRvalueSwizzle
(
precision
,
scalarTypeId
,
arg
,
swiz
);
arg
=
createRvalueSwizzle
(
precision
,
scalarTypeId
,
arg
,
swiz
);
...
@@ -1900,8 +1824,7 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc
...
@@ -1900,8 +1824,7 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc
}
}
// Comments in header
// Comments in header
Id
Builder
::
createMatrixConstructor
(
Decoration
precision
,
const
std
::
vector
<
Id
>&
sources
,
Id
Builder
::
createMatrixConstructor
(
Decoration
precision
,
const
std
::
vector
<
Id
>&
sources
,
Id
resultTypeId
)
Id
resultTypeId
)
{
{
Id
componentTypeId
=
getScalarTypeId
(
resultTypeId
);
Id
componentTypeId
=
getScalarTypeId
(
resultTypeId
);
int
numCols
=
getTypeNumColumns
(
resultTypeId
);
int
numCols
=
getTypeNumColumns
(
resultTypeId
);
...
@@ -1930,49 +1853,39 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
...
@@ -1930,49 +1853,39 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
}
}
// modify components as dictated by the arguments
// modify components as dictated by the arguments
if
(
sources
.
size
()
==
1
&&
isScalar
(
sources
[
0
]))
if
(
sources
.
size
()
==
1
&&
isScalar
(
sources
[
0
]))
{
{
// a single scalar; resets the diagonals
// a single scalar; resets the diagonals
for
(
int
col
=
0
;
col
<
4
;
++
col
)
for
(
int
col
=
0
;
col
<
4
;
++
col
)
ids
[
col
][
col
]
=
sources
[
0
];
ids
[
col
][
col
]
=
sources
[
0
];
}
else
if
(
isMatrix
(
sources
[
0
]))
}
else
if
(
isMatrix
(
sources
[
0
]))
{
{
// constructing from another matrix; copy over the parts that exist in both the argument and constructee
// constructing from another matrix; copy over the parts that exist in both the argument and
// constructee
Id
matrix
=
sources
[
0
];
Id
matrix
=
sources
[
0
];
int
minCols
=
std
::
min
(
numCols
,
getNumColumns
(
matrix
));
int
minCols
=
std
::
min
(
numCols
,
getNumColumns
(
matrix
));
int
minRows
=
std
::
min
(
numRows
,
getNumRows
(
matrix
));
int
minRows
=
std
::
min
(
numRows
,
getNumRows
(
matrix
));
for
(
int
col
=
0
;
col
<
minCols
;
++
col
)
for
(
int
col
=
0
;
col
<
minCols
;
++
col
)
{
{
std
::
vector
<
unsigned
>
indexes
;
std
::
vector
<
unsigned
>
indexes
;
indexes
.
push_back
(
col
);
indexes
.
push_back
(
col
);
for
(
int
row
=
0
;
row
<
minRows
;
++
row
)
for
(
int
row
=
0
;
row
<
minRows
;
++
row
)
{
{
indexes
.
push_back
(
row
);
indexes
.
push_back
(
row
);
ids
[
col
][
row
]
=
createCompositeExtract
(
matrix
,
componentTypeId
,
indexes
);
ids
[
col
][
row
]
=
createCompositeExtract
(
matrix
,
componentTypeId
,
indexes
);
indexes
.
pop_back
();
indexes
.
pop_back
();
setPrecision
(
ids
[
col
][
row
],
precision
);
setPrecision
(
ids
[
col
][
row
],
precision
);
}
}
}
}
}
else
}
else
{
{
// fill in the matrix in column-major order with whatever argument components are available
// fill in the matrix in column-major order with whatever argument components are available
int
row
=
0
;
int
row
=
0
;
int
col
=
0
;
int
col
=
0
;
for
(
int
arg
=
0
;
arg
<
(
int
)
sources
.
size
();
++
arg
)
for
(
int
arg
=
0
;
arg
<
(
int
)
sources
.
size
();
++
arg
)
{
{
Id
argComp
=
sources
[
arg
];
Id
argComp
=
sources
[
arg
];
for
(
int
comp
=
0
;
comp
<
getNumComponents
(
sources
[
arg
]);
++
comp
)
for
(
int
comp
=
0
;
comp
<
getNumComponents
(
sources
[
arg
]);
++
comp
)
{
{
if
(
getNumComponents
(
sources
[
arg
])
>
1
)
{
if
(
getNumComponents
(
sources
[
arg
])
>
1
)
{
argComp
=
createCompositeExtract
(
sources
[
arg
],
componentTypeId
,
comp
);
argComp
=
createCompositeExtract
(
sources
[
arg
],
componentTypeId
,
comp
);
setPrecision
(
argComp
,
precision
);
setPrecision
(
argComp
,
precision
);
}
}
ids
[
col
][
row
++
]
=
argComp
;
ids
[
col
][
row
++
]
=
argComp
;
if
(
row
==
numRows
)
if
(
row
==
numRows
)
{
{
row
=
0
;
row
=
0
;
col
++
;
col
++
;
}
}
...
@@ -1980,14 +1893,14 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
...
@@ -1980,14 +1893,14 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
}
}
}
}
// Step 2: Construct a matrix from that array.
// Step 2: Construct a matrix from that array.
// First make the column vectors, then make the matrix.
// First make the column vectors, then make the matrix.
// make the column vectors
// make the column vectors
Id
columnTypeId
=
getContainedTypeId
(
resultTypeId
);
Id
columnTypeId
=
getContainedTypeId
(
resultTypeId
);
std
::
vector
<
Id
>
matrixColumns
;
std
::
vector
<
Id
>
matrixColumns
;
for
(
int
col
=
0
;
col
<
numCols
;
++
col
)
for
(
int
col
=
0
;
col
<
numCols
;
++
col
)
{
{
std
::
vector
<
Id
>
vectorComponents
;
std
::
vector
<
Id
>
vectorComponents
;
for
(
int
row
=
0
;
row
<
numRows
;
++
row
)
for
(
int
row
=
0
;
row
<
numRows
;
++
row
)
vectorComponents
.
push_back
(
ids
[
col
][
row
]);
vectorComponents
.
push_back
(
ids
[
col
][
row
]);
...
@@ -2001,7 +1914,10 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
...
@@ -2001,7 +1914,10 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
}
}
// Comments in header
// Comments in header
Builder
::
If
::
If
(
Id
cond
,
Builder
&
gb
)
:
builder
(
gb
),
condition
(
cond
),
elseBlock
(
0
)
Builder
::
If
::
If
(
Id
cond
,
Builder
&
gb
)
:
builder
(
gb
),
condition
(
cond
),
elseBlock
(
0
)
{
{
function
=
&
builder
.
getBuildPoint
()
->
getParent
();
function
=
&
builder
.
getBuildPoint
()
->
getParent
();
...
@@ -2053,8 +1969,7 @@ void Builder::If::makeEndIf()
...
@@ -2053,8 +1969,7 @@ void Builder::If::makeEndIf()
}
}
// Comments in header
// Comments in header
void
Builder
::
makeSwitch
(
Id
selector
,
int
numSegments
,
std
::
vector
<
int
>&
caseValues
,
void
Builder
::
makeSwitch
(
Id
selector
,
int
numSegments
,
std
::
vector
<
int
>&
caseValues
,
std
::
vector
<
int
>&
valueIndexToSegment
,
int
defaultSegment
,
std
::
vector
<
int
>&
valueIndexToSegment
,
int
defaultSegment
,
std
::
vector
<
Block
*>&
segmentBlocks
)
std
::
vector
<
Block
*>&
segmentBlocks
)
{
{
Function
&
function
=
buildPoint
->
getParent
();
Function
&
function
=
buildPoint
->
getParent
();
...
@@ -2074,8 +1989,7 @@ void Builder::makeSwitch(Id selector, int numSegments, std::vector<int>& caseVal
...
@@ -2074,8 +1989,7 @@ void Builder::makeSwitch(Id selector, int numSegments, std::vector<int>& caseVal
auto
defaultOrMerge
=
(
defaultSegment
>=
0
)
?
segmentBlocks
[
defaultSegment
]
:
mergeBlock
;
auto
defaultOrMerge
=
(
defaultSegment
>=
0
)
?
segmentBlocks
[
defaultSegment
]
:
mergeBlock
;
switchInst
->
addIdOperand
(
defaultOrMerge
->
getId
());
switchInst
->
addIdOperand
(
defaultOrMerge
->
getId
());
defaultOrMerge
->
addPredecessor
(
buildPoint
);
defaultOrMerge
->
addPredecessor
(
buildPoint
);
for
(
int
i
=
0
;
i
<
(
int
)
caseValues
.
size
();
++
i
)
for
(
int
i
=
0
;
i
<
(
int
)
caseValues
.
size
();
++
i
)
{
{
switchInst
->
addImmediateOperand
(
caseValues
[
i
]);
switchInst
->
addImmediateOperand
(
caseValues
[
i
]);
switchInst
->
addIdOperand
(
segmentBlocks
[
valueIndexToSegment
[
i
]]
->
getId
());
switchInst
->
addIdOperand
(
segmentBlocks
[
valueIndexToSegment
[
i
]]
->
getId
());
segmentBlocks
[
valueIndexToSegment
[
i
]]
->
addPredecessor
(
buildPoint
);
segmentBlocks
[
valueIndexToSegment
[
i
]]
->
addPredecessor
(
buildPoint
);
...
@@ -2098,10 +2012,9 @@ void Builder::addSwitchBreak()
...
@@ -2098,10 +2012,9 @@ void Builder::addSwitchBreak()
void
Builder
::
nextSwitchSegment
(
std
::
vector
<
Block
*>&
segmentBlock
,
int
nextSegment
)
void
Builder
::
nextSwitchSegment
(
std
::
vector
<
Block
*>&
segmentBlock
,
int
nextSegment
)
{
{
int
lastSegment
=
nextSegment
-
1
;
int
lastSegment
=
nextSegment
-
1
;
if
(
lastSegment
>=
0
)
if
(
lastSegment
>=
0
)
{
{
// Close out previous segment by jumping, if necessary, to next segment
// Close out previous segment by jumping, if necessary, to next segment
if
(
!
buildPoint
->
isTerminated
())
if
(
!
buildPoint
->
isTerminated
())
createBranch
(
segmentBlock
[
nextSegment
]);
createBranch
(
segmentBlock
[
nextSegment
]);
}
}
Block
*
block
=
segmentBlock
[
nextSegment
];
Block
*
block
=
segmentBlock
[
nextSegment
];
...
@@ -2113,7 +2026,7 @@ void Builder::nextSwitchSegment(std::vector<Block*>& segmentBlock, int nextSegme
...
@@ -2113,7 +2026,7 @@ void Builder::nextSwitchSegment(std::vector<Block*>& segmentBlock, int nextSegme
void
Builder
::
endSwitch
(
std
::
vector
<
Block
*>&
/*segmentBlock*/
)
void
Builder
::
endSwitch
(
std
::
vector
<
Block
*>&
/*segmentBlock*/
)
{
{
// Close out previous segment by jumping, if necessary, to next segment
// Close out previous segment by jumping, if necessary, to next segment
if
(
!
buildPoint
->
isTerminated
())
if
(
!
buildPoint
->
isTerminated
())
addSwitchBreak
();
addSwitchBreak
();
switchMerges
.
top
()
->
getParent
().
addBlock
(
switchMerges
.
top
());
switchMerges
.
top
()
->
getParent
().
addBlock
(
switchMerges
.
top
());
...
@@ -2152,7 +2065,11 @@ void Builder::createLoopExit()
...
@@ -2152,7 +2065,11 @@ void Builder::createLoopExit()
createAndSetNoPredecessorBlock
(
"post-loop-break"
);
createAndSetNoPredecessorBlock
(
"post-loop-break"
);
}
}
void
Builder
::
closeLoop
()
{
loops
.
pop
();
}
void
Builder
::
closeLoop
()
{
loops
.
pop
();
}
void
Builder
::
clearAccessChain
()
void
Builder
::
clearAccessChain
()
{
{
accessChain
.
base
=
NoResult
;
accessChain
.
base
=
NoResult
;
...
@@ -2173,12 +2090,10 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz
...
@@ -2173,12 +2090,10 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz
accessChain
.
preSwizzleBaseType
=
preSwizzleBaseType
;
accessChain
.
preSwizzleBaseType
=
preSwizzleBaseType
;
// if needed, propagate the swizzle for the current access chain
// if needed, propagate the swizzle for the current access chain
if
(
accessChain
.
swizzle
.
size
())
if
(
accessChain
.
swizzle
.
size
())
{
{
std
::
vector
<
unsigned
>
oldSwizzle
=
accessChain
.
swizzle
;
std
::
vector
<
unsigned
>
oldSwizzle
=
accessChain
.
swizzle
;
accessChain
.
swizzle
.
resize
(
0
);
accessChain
.
swizzle
.
resize
(
0
);
for
(
unsigned
int
i
=
0
;
i
<
swizzle
.
size
();
++
i
)
for
(
unsigned
int
i
=
0
;
i
<
swizzle
.
size
();
++
i
)
{
{
accessChain
.
swizzle
.
push_back
(
oldSwizzle
[
swizzle
[
i
]]);
accessChain
.
swizzle
.
push_back
(
oldSwizzle
[
swizzle
[
i
]]);
}
}
}
else
}
else
...
@@ -2202,19 +2117,15 @@ void Builder::accessChainStore(Id rvalue)
...
@@ -2202,19 +2117,15 @@ void Builder::accessChainStore(Id rvalue)
// If swizzle still exists, it is out-of-order or not full, we must load the target vector,
// If swizzle still exists, it is out-of-order or not full, we must load the target vector,
// extract and insert elements to perform writeMask and/or swizzle.
// extract and insert elements to perform writeMask and/or swizzle.
Id
source
=
NoResult
;
Id
source
=
NoResult
;
if
(
accessChain
.
swizzle
.
size
())
if
(
accessChain
.
swizzle
.
size
())
{
{
Id
tempBaseId
=
createLoad
(
base
);
Id
tempBaseId
=
createLoad
(
base
);
source
=
source
=
createLvalueSwizzle
(
getTypeId
(
tempBaseId
),
tempBaseId
,
rvalue
,
accessChain
.
swizzle
);
createLvalueSwizzle
(
getTypeId
(
tempBaseId
),
tempBaseId
,
rvalue
,
accessChain
.
swizzle
);
}
}
// dynamic component selection
// dynamic component selection
if
(
accessChain
.
component
!=
NoResult
)
if
(
accessChain
.
component
!=
NoResult
)
{
{
Id
tempBaseId
=
(
source
==
NoResult
)
?
createLoad
(
base
)
:
source
;
Id
tempBaseId
=
(
source
==
NoResult
)
?
createLoad
(
base
)
:
source
;
source
=
createVectorInsertDynamic
(
tempBaseId
,
getTypeId
(
tempBaseId
),
rvalue
,
source
=
createVectorInsertDynamic
(
tempBaseId
,
getTypeId
(
tempBaseId
),
rvalue
,
accessChain
.
component
);
accessChain
.
component
);
}
}
if
(
source
==
NoResult
)
if
(
source
==
NoResult
)
...
@@ -2228,25 +2139,19 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
...
@@ -2228,25 +2139,19 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
{
{
Id
id
;
Id
id
;
if
(
accessChain
.
isRValue
)
if
(
accessChain
.
isRValue
)
{
{
// transfer access chain, but keep it static, so we can stay in registers
// transfer access chain, but keep it static, so we can stay in registers
transferAccessChainSwizzle
(
false
);
transferAccessChainSwizzle
(
false
);
if
(
accessChain
.
indexChain
.
size
()
>
0
)
if
(
accessChain
.
indexChain
.
size
()
>
0
)
{
{
Id
swizzleBase
=
accessChain
.
preSwizzleBaseType
!=
NoType
?
accessChain
.
preSwizzleBaseType
:
resultType
;
Id
swizzleBase
=
accessChain
.
preSwizzleBaseType
!=
NoType
?
accessChain
.
preSwizzleBaseType
:
resultType
;
// if all the accesses are constants, we can use OpCompositeExtract
// if all the accesses are constants, we can use OpCompositeExtract
std
::
vector
<
unsigned
>
indexes
;
std
::
vector
<
unsigned
>
indexes
;
bool
constant
=
true
;
bool
constant
=
true
;
for
(
int
i
=
0
;
i
<
(
int
)
accessChain
.
indexChain
.
size
();
++
i
)
for
(
int
i
=
0
;
i
<
(
int
)
accessChain
.
indexChain
.
size
();
++
i
)
{
{
if
(
isConstantScalar
(
accessChain
.
indexChain
[
i
]))
if
(
isConstantScalar
(
accessChain
.
indexChain
[
i
]))
indexes
.
push_back
(
getConstantScalar
(
accessChain
.
indexChain
[
i
]));
indexes
.
push_back
(
getConstantScalar
(
accessChain
.
indexChain
[
i
]));
else
else
{
{
constant
=
false
;
constant
=
false
;
break
;
break
;
}
}
...
@@ -2254,11 +2159,9 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
...
@@ -2254,11 +2159,9 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
if
(
constant
)
if
(
constant
)
id
=
createCompositeExtract
(
accessChain
.
base
,
swizzleBase
,
indexes
);
id
=
createCompositeExtract
(
accessChain
.
base
,
swizzleBase
,
indexes
);
else
else
{
{
// make a new function variable for this r-value
// make a new function variable for this r-value
Id
lValue
=
Id
lValue
=
createVariable
(
StorageClassFunction
,
getTypeId
(
accessChain
.
base
),
"indexable"
);
createVariable
(
StorageClassFunction
,
getTypeId
(
accessChain
.
base
),
"indexable"
);
// store into it
// store into it
createStore
(
accessChain
.
base
,
lValue
);
createStore
(
accessChain
.
base
,
lValue
);
...
@@ -2273,8 +2176,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
...
@@ -2273,8 +2176,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
setPrecision
(
id
,
precision
);
setPrecision
(
id
,
precision
);
}
else
}
else
id
=
accessChain
.
base
;
// no precision, it was set when this was defined
id
=
accessChain
.
base
;
// no precision, it was set when this was defined
}
else
}
else
{
{
transferAccessChainSwizzle
(
true
);
transferAccessChainSwizzle
(
true
);
// load through the access chain
// load through the access chain
id
=
createLoad
(
collapseAccessChain
());
id
=
createLoad
(
collapseAccessChain
());
...
@@ -2287,8 +2189,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
...
@@ -2287,8 +2189,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
// Do remaining swizzling
// Do remaining swizzling
// First, static swizzling
// First, static swizzling
if
(
accessChain
.
swizzle
.
size
())
if
(
accessChain
.
swizzle
.
size
())
{
{
// static swizzle
// static swizzle
Id
swizzledType
=
getScalarTypeId
(
getTypeId
(
id
));
Id
swizzledType
=
getScalarTypeId
(
getTypeId
(
id
));
if
(
accessChain
.
swizzle
.
size
()
>
1
)
if
(
accessChain
.
swizzle
.
size
()
>
1
)
...
@@ -2298,8 +2199,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
...
@@ -2298,8 +2199,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
// dynamic single-component selection
// dynamic single-component selection
if
(
accessChain
.
component
!=
NoResult
)
if
(
accessChain
.
component
!=
NoResult
)
id
=
setPrecision
(
createVectorExtractDynamic
(
id
,
resultType
,
accessChain
.
component
),
id
=
setPrecision
(
createVectorExtractDynamic
(
id
,
resultType
,
accessChain
.
component
),
precision
);
precision
);
return
id
;
return
id
;
}
}
...
@@ -2329,12 +2229,11 @@ Id Builder::accessChainGetInferredType()
...
@@ -2329,12 +2229,11 @@ Id Builder::accessChainGetInferredType()
Id
type
=
getTypeId
(
accessChain
.
base
);
Id
type
=
getTypeId
(
accessChain
.
base
);
// do initial dereference
// do initial dereference
if
(
!
accessChain
.
isRValue
)
if
(
!
accessChain
.
isRValue
)
type
=
getContainedTypeId
(
type
);
type
=
getContainedTypeId
(
type
);
// dereference each index
// dereference each index
for
(
auto
it
=
accessChain
.
indexChain
.
cbegin
();
it
!=
accessChain
.
indexChain
.
cend
();
++
it
)
for
(
auto
it
=
accessChain
.
indexChain
.
cbegin
();
it
!=
accessChain
.
indexChain
.
cend
();
++
it
)
{
{
if
(
isStructType
(
type
))
if
(
isStructType
(
type
))
type
=
getContainedTypeId
(
type
,
getConstantScalar
(
*
it
));
type
=
getContainedTypeId
(
type
,
getConstantScalar
(
*
it
));
else
else
...
@@ -2355,29 +2254,26 @@ Id Builder::accessChainGetInferredType()
...
@@ -2355,29 +2254,26 @@ Id Builder::accessChainGetInferredType()
}
}
// comment in header
// comment in header
void
Builder
::
eliminateDeadDecorations
()
void
Builder
::
eliminateDeadDecorations
()
{
{
std
::
unordered_set
<
const
Block
*>
reachable_blocks
;
std
::
unordered_set
<
const
Block
*>
reachable_blocks
;
std
::
unordered_set
<
Id
>
unreachable_definitions
;
std
::
unordered_set
<
Id
>
unreachable_definitions
;
// Collect IDs defined in unreachable blocks. For each function, label the
// Collect IDs defined in unreachable blocks. For each function, label the
// reachable blocks first. Then for each unreachable block, collect the
// reachable blocks first. Then for each unreachable block, collect the
// result IDs of the instructions in it.
// result IDs of the instructions in it.
for
(
std
::
vector
<
Function
*>::
const_iterator
fi
=
module
.
getFunctions
().
cbegin
();
for
(
std
::
vector
<
Function
*>::
const_iterator
fi
=
module
.
getFunctions
().
cbegin
();
fi
!=
module
.
getFunctions
().
cend
();
fi
++
)
fi
!=
module
.
getFunctions
().
cend
();
fi
++
)
{
{
Function
*
f
=
*
fi
;
Function
*
f
=
*
fi
;
Block
*
entry
=
f
->
getEntryBlock
();
Block
*
entry
=
f
->
getEntryBlock
();
inReadableOrder
(
entry
,
[
&
reachable_blocks
](
const
Block
*
b
)
{
reachable_blocks
.
insert
(
b
);
});
inReadableOrder
(
entry
,
[
&
reachable_blocks
](
const
Block
*
b
)
{
reachable_blocks
.
insert
(
b
);
});
for
(
std
::
vector
<
Block
*>::
const_iterator
bi
=
f
->
getBlocks
().
cbegin
();
for
(
std
::
vector
<
Block
*>::
const_iterator
bi
=
f
->
getBlocks
().
cbegin
();
bi
!=
f
->
getBlocks
().
cend
();
bi
++
)
bi
!=
f
->
getBlocks
().
cend
();
bi
++
)
{
{
Block
*
b
=
*
bi
;
Block
*
b
=
*
bi
;
if
(
!
reachable_blocks
.
count
(
b
))
if
(
!
reachable_blocks
.
count
(
b
))
{
{
for
(
std
::
vector
<
std
::
unique_ptr
<
Instruction
>
>::
const_iterator
for
(
std
::
vector
<
std
::
unique_ptr
<
Instruction
>
>::
const_iterator
ii
=
ii
=
b
->
getInstructions
().
cbegin
();
b
->
getInstructions
().
cbegin
();
ii
!=
b
->
getInstructions
().
cend
();
ii
++
)
{
ii
!=
b
->
getInstructions
().
cend
();
ii
++
)
{
Instruction
*
i
=
ii
->
get
();
Instruction
*
i
=
ii
->
get
();
unreachable_definitions
.
insert
(
i
->
getResultId
());
unreachable_definitions
.
insert
(
i
->
getResultId
());
}
}
...
@@ -2403,8 +2299,7 @@ void Builder::dump(std::vector<unsigned int>& out) const
...
@@ -2403,8 +2299,7 @@ void Builder::dump(std::vector<unsigned int>& out) const
out
.
push_back
(
0
);
out
.
push_back
(
0
);
// Capabilities
// Capabilities
for
(
auto
it
=
capabilities
.
cbegin
();
it
!=
capabilities
.
cend
();
++
it
)
for
(
auto
it
=
capabilities
.
cbegin
();
it
!=
capabilities
.
cend
();
++
it
)
{
{
Instruction
capInst
(
0
,
0
,
OpCapability
);
Instruction
capInst
(
0
,
0
,
OpCapability
);
capInst
.
addImmediateOperand
(
*
it
);
capInst
.
addImmediateOperand
(
*
it
);
capInst
.
dump
(
out
);
capInst
.
dump
(
out
);
...
@@ -2423,15 +2318,13 @@ void Builder::dump(std::vector<unsigned int>& out) const
...
@@ -2423,15 +2318,13 @@ void Builder::dump(std::vector<unsigned int>& out) const
dumpInstructions
(
out
,
executionModes
);
dumpInstructions
(
out
,
executionModes
);
// Debug instructions
// Debug instructions
if
(
source
!=
SourceLanguageUnknown
)
if
(
source
!=
SourceLanguageUnknown
)
{
{
Instruction
sourceInst
(
0
,
0
,
OpSource
);
Instruction
sourceInst
(
0
,
0
,
OpSource
);
sourceInst
.
addImmediateOperand
(
source
);
sourceInst
.
addImmediateOperand
(
source
);
sourceInst
.
addImmediateOperand
(
sourceVersion
);
sourceInst
.
addImmediateOperand
(
sourceVersion
);
sourceInst
.
dump
(
out
);
sourceInst
.
dump
(
out
);
}
}
for
(
int
e
=
0
;
e
<
(
int
)
extensions
.
size
();
++
e
)
for
(
int
e
=
0
;
e
<
(
int
)
extensions
.
size
();
++
e
)
{
{
Instruction
extInst
(
0
,
0
,
OpSourceExtension
);
Instruction
extInst
(
0
,
0
,
OpSourceExtension
);
extInst
.
addStringOperand
(
extensions
[
e
]);
extInst
.
addStringOperand
(
extensions
[
e
]);
extInst
.
dump
(
out
);
extInst
.
dump
(
out
);
...
@@ -2462,14 +2355,10 @@ Id Builder::collapseAccessChain()
...
@@ -2462,14 +2355,10 @@ Id Builder::collapseAccessChain()
{
{
assert
(
accessChain
.
isRValue
==
false
);
assert
(
accessChain
.
isRValue
==
false
);
if
(
accessChain
.
indexChain
.
size
()
>
0
)
if
(
accessChain
.
indexChain
.
size
()
>
0
)
{
{
if
(
accessChain
.
instr
==
0
)
{
if
(
accessChain
.
instr
==
0
)
StorageClass
storageClass
=
(
StorageClass
)
module
.
getStorageClass
(
getTypeId
(
accessChain
.
base
));
{
accessChain
.
instr
=
createAccessChain
(
storageClass
,
accessChain
.
base
,
accessChain
.
indexChain
);
StorageClass
storageClass
=
(
StorageClass
)
module
.
getStorageClass
(
getTypeId
(
accessChain
.
base
));
accessChain
.
instr
=
createAccessChain
(
storageClass
,
accessChain
.
base
,
accessChain
.
indexChain
);
}
}
return
accessChain
.
instr
;
return
accessChain
.
instr
;
...
@@ -2489,8 +2378,7 @@ void Builder::simplifyAccessChainSwizzle()
...
@@ -2489,8 +2378,7 @@ void Builder::simplifyAccessChainSwizzle()
return
;
return
;
// if components are out of order, it is a swizzle
// if components are out of order, it is a swizzle
for
(
unsigned
int
i
=
0
;
i
<
accessChain
.
swizzle
.
size
();
++
i
)
for
(
unsigned
int
i
=
0
;
i
<
accessChain
.
swizzle
.
size
();
++
i
)
{
{
if
(
i
!=
accessChain
.
swizzle
[
i
])
if
(
i
!=
accessChain
.
swizzle
[
i
])
return
;
return
;
}
}
...
@@ -2526,8 +2414,7 @@ void Builder::transferAccessChainSwizzle(bool dynamic)
...
@@ -2526,8 +2414,7 @@ void Builder::transferAccessChainSwizzle(bool dynamic)
if
(
isBoolType
(
getContainedTypeId
(
accessChain
.
preSwizzleBaseType
)))
if
(
isBoolType
(
getContainedTypeId
(
accessChain
.
preSwizzleBaseType
)))
return
;
return
;
if
(
accessChain
.
swizzle
.
size
()
==
1
)
if
(
accessChain
.
swizzle
.
size
()
==
1
)
{
{
// handle static component
// handle static component
accessChain
.
indexChain
.
push_back
(
makeUintConstant
(
accessChain
.
swizzle
.
front
()));
accessChain
.
indexChain
.
push_back
(
makeUintConstant
(
accessChain
.
swizzle
.
front
()));
accessChain
.
swizzle
.
clear
();
accessChain
.
swizzle
.
clear
();
...
@@ -2535,8 +2422,7 @@ void Builder::transferAccessChainSwizzle(bool dynamic)
...
@@ -2535,8 +2422,7 @@ void Builder::transferAccessChainSwizzle(bool dynamic)
// component, so don't bother even looking at accessChain.component
// component, so don't bother even looking at accessChain.component
accessChain
.
preSwizzleBaseType
=
NoType
;
accessChain
.
preSwizzleBaseType
=
NoType
;
accessChain
.
component
=
NoResult
;
accessChain
.
component
=
NoResult
;
}
else
if
(
dynamic
&&
accessChain
.
component
!=
NoResult
)
}
else
if
(
dynamic
&&
accessChain
.
component
!=
NoResult
)
{
{
// handle dynamic component
// handle dynamic component
accessChain
.
indexChain
.
push_back
(
accessChain
.
component
);
accessChain
.
indexChain
.
push_back
(
accessChain
.
component
);
accessChain
.
preSwizzleBaseType
=
NoType
;
accessChain
.
preSwizzleBaseType
=
NoType
;
...
@@ -2554,7 +2440,7 @@ void Builder::createAndSetNoPredecessorBlock(const char* /*name*/)
...
@@ -2554,7 +2440,7 @@ void Builder::createAndSetNoPredecessorBlock(const char* /*name*/)
buildPoint
->
getParent
().
addBlock
(
block
);
buildPoint
->
getParent
().
addBlock
(
block
);
setBuildPoint
(
block
);
setBuildPoint
(
block
);
//
if (name)
//if (name)
// addName(block->getId(), name);
// addName(block->getId(), name);
}
}
...
@@ -2595,11 +2481,9 @@ void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* els
...
@@ -2595,11 +2481,9 @@ void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* els
elseBlock
->
addPredecessor
(
buildPoint
);
elseBlock
->
addPredecessor
(
buildPoint
);
}
}
void
Builder
::
dumpInstructions
(
std
::
vector
<
unsigned
int
>&
out
,
void
Builder
::
dumpInstructions
(
std
::
vector
<
unsigned
int
>&
out
,
const
std
::
vector
<
std
::
unique_ptr
<
Instruction
>
>&
instructions
)
const
const
std
::
vector
<
std
::
unique_ptr
<
Instruction
>
>&
instructions
)
const
{
{
for
(
int
i
=
0
;
i
<
(
int
)
instructions
.
size
();
++
i
)
for
(
int
i
=
0
;
i
<
(
int
)
instructions
.
size
();
++
i
)
{
{
instructions
[
i
]
->
dump
(
out
);
instructions
[
i
]
->
dump
(
out
);
}
}
}
}
...
...
SPIRV/SpvBuilder.h
View file @
738314fe
...
@@ -79,8 +79,10 @@ public:
...
@@ -79,8 +79,10 @@ public:
}
}
void
addCapability
(
spv
::
Capability
cap
)
{
capabilities
.
insert
(
cap
);
}
void
addCapability
(
spv
::
Capability
cap
)
{
capabilities
.
insert
(
cap
);
}
// To get a new <id> for anything needing a new one.
// To get a new <id> for anything needing a new one.
Id
getUniqueId
()
{
return
++
uniqueId
;
}
Id
getUniqueId
()
{
return
++
uniqueId
;
}
// To get a set of new <id>s, e.g., for a set of function parameters
// To get a set of new <id>s, e.g., for a set of function parameters
Id
getUniqueIds
(
int
numIds
)
Id
getUniqueIds
(
int
numIds
)
{
{
...
@@ -93,7 +95,7 @@ public:
...
@@ -93,7 +95,7 @@ public:
Id
makeVoidType
();
Id
makeVoidType
();
Id
makeBoolType
();
Id
makeBoolType
();
Id
makePointer
(
StorageClass
,
Id
type
);
Id
makePointer
(
StorageClass
,
Id
type
);
Id
makeIntegerType
(
int
width
,
bool
hasSign
);
// generic
Id
makeIntegerType
(
int
width
,
bool
hasSign
);
// generic
Id
makeIntType
(
int
width
)
{
return
makeIntegerType
(
width
,
true
);
}
Id
makeIntType
(
int
width
)
{
return
makeIntegerType
(
width
,
true
);
}
Id
makeUintType
(
int
width
)
{
return
makeIntegerType
(
width
,
false
);
}
Id
makeUintType
(
int
width
)
{
return
makeIntegerType
(
width
,
false
);
}
Id
makeFloatType
(
int
width
);
Id
makeFloatType
(
int
width
);
...
@@ -104,8 +106,7 @@ public:
...
@@ -104,8 +106,7 @@ public:
Id
makeArrayType
(
Id
element
,
Id
sizeId
,
int
stride
);
// 0 stride means no stride decoration
Id
makeArrayType
(
Id
element
,
Id
sizeId
,
int
stride
);
// 0 stride means no stride decoration
Id
makeRuntimeArray
(
Id
element
);
Id
makeRuntimeArray
(
Id
element
);
Id
makeFunctionType
(
Id
returnType
,
const
std
::
vector
<
Id
>&
paramTypes
);
Id
makeFunctionType
(
Id
returnType
,
const
std
::
vector
<
Id
>&
paramTypes
);
Id
makeImageType
(
Id
sampledType
,
Dim
,
bool
depth
,
bool
arrayed
,
bool
ms
,
unsigned
sampled
,
Id
makeImageType
(
Id
sampledType
,
Dim
,
bool
depth
,
bool
arrayed
,
bool
ms
,
unsigned
sampled
,
ImageFormat
format
);
ImageFormat
format
);
Id
makeSamplerType
();
Id
makeSamplerType
();
Id
makeSampledImageType
(
Id
imageType
);
Id
makeSampledImageType
(
Id
imageType
);
...
@@ -122,36 +123,27 @@ public:
...
@@ -122,36 +123,27 @@ public:
Id
getContainedTypeId
(
Id
typeId
)
const
;
Id
getContainedTypeId
(
Id
typeId
)
const
;
Id
getContainedTypeId
(
Id
typeId
,
int
)
const
;
Id
getContainedTypeId
(
Id
typeId
,
int
)
const
;
StorageClass
getTypeStorageClass
(
Id
typeId
)
const
{
return
module
.
getStorageClass
(
typeId
);
}
StorageClass
getTypeStorageClass
(
Id
typeId
)
const
{
return
module
.
getStorageClass
(
typeId
);
}
ImageFormat
getImageTypeFormat
(
Id
typeId
)
const
ImageFormat
getImageTypeFormat
(
Id
typeId
)
const
{
return
(
ImageFormat
)
module
.
getInstruction
(
typeId
)
->
getImmediateOperand
(
6
);
}
{
return
(
ImageFormat
)
module
.
getInstruction
(
typeId
)
->
getImmediateOperand
(
6
);
}
bool
isPointer
(
Id
resultId
)
const
{
return
isPointerType
(
getTypeId
(
resultId
));
}
bool
isPointer
(
Id
resultId
)
const
{
return
isPointerType
(
getTypeId
(
resultId
));
}
bool
isScalar
(
Id
resultId
)
const
{
return
isScalarType
(
getTypeId
(
resultId
));
}
bool
isScalar
(
Id
resultId
)
const
{
return
isScalarType
(
getTypeId
(
resultId
));
}
bool
isVector
(
Id
resultId
)
const
{
return
isVectorType
(
getTypeId
(
resultId
));
}
bool
isVector
(
Id
resultId
)
const
{
return
isVectorType
(
getTypeId
(
resultId
));
}
bool
isMatrix
(
Id
resultId
)
const
{
return
isMatrixType
(
getTypeId
(
resultId
));
}
bool
isMatrix
(
Id
resultId
)
const
{
return
isMatrixType
(
getTypeId
(
resultId
));
}
bool
isAggregate
(
Id
resultId
)
const
{
return
isAggregateType
(
getTypeId
(
resultId
));
}
bool
isAggregate
(
Id
resultId
)
const
{
return
isAggregateType
(
getTypeId
(
resultId
));
}
bool
isSampledImage
(
Id
resultId
)
const
{
return
isSampledImageType
(
getTypeId
(
resultId
));
}
bool
isSampledImage
(
Id
resultId
)
const
{
return
isSampledImageType
(
getTypeId
(
resultId
));
}
bool
isBoolType
(
Id
typeId
)
const
{
bool
isBoolType
(
Id
typeId
)
const
{
return
groupedTypes
[
OpTypeBool
].
size
()
>
0
&&
typeId
==
groupedTypes
[
OpTypeBool
].
back
()
->
getResultId
();
}
return
groupedTypes
[
OpTypeBool
].
size
()
>
0
&&
bool
isPointerType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypePointer
;
}
typeId
==
groupedTypes
[
OpTypeBool
].
back
()
->
getResultId
();
bool
isScalarType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeFloat
||
getTypeClass
(
typeId
)
==
OpTypeInt
||
getTypeClass
(
typeId
)
==
OpTypeBool
;
}
}
bool
isVectorType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeVector
;
}
bool
isPointerType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypePointer
;
}
bool
isMatrixType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeMatrix
;
}
bool
isScalarType
(
Id
typeId
)
const
bool
isStructType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeStruct
;
}
{
bool
isArrayType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeArray
;
}
return
getTypeClass
(
typeId
)
==
OpTypeFloat
||
getTypeClass
(
typeId
)
==
OpTypeInt
||
bool
isAggregateType
(
Id
typeId
)
const
{
return
isArrayType
(
typeId
)
||
isStructType
(
typeId
);
}
getTypeClass
(
typeId
)
==
OpTypeBool
;
bool
isImageType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeImage
;
}
}
bool
isSamplerType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeSampler
;
}
bool
isVectorType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeVector
;
}
bool
isMatrixType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeMatrix
;
}
bool
isStructType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeStruct
;
}
bool
isArrayType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeArray
;
}
bool
isAggregateType
(
Id
typeId
)
const
{
return
isArrayType
(
typeId
)
||
isStructType
(
typeId
);
}
bool
isImageType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeImage
;
}
bool
isSamplerType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeSampler
;
}
bool
isSampledImageType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeSampledImage
;
}
bool
isSampledImageType
(
Id
typeId
)
const
{
return
getTypeClass
(
typeId
)
==
OpTypeSampledImage
;
}
bool
isConstantOpCode
(
Op
opcode
)
const
;
bool
isConstantOpCode
(
Op
opcode
)
const
;
bool
isSpecConstantOpCode
(
Op
opcode
)
const
;
bool
isSpecConstantOpCode
(
Op
opcode
)
const
;
bool
isConstant
(
Id
resultId
)
const
{
return
isConstantOpCode
(
getOpCode
(
resultId
));
}
bool
isConstant
(
Id
resultId
)
const
{
return
isConstantOpCode
(
getOpCode
(
resultId
));
}
...
@@ -172,6 +164,7 @@ public:
...
@@ -172,6 +164,7 @@ public:
return
getNumTypeComponents
(
getContainedTypeId
(
typeId
));
return
getNumTypeComponents
(
getContainedTypeId
(
typeId
));
}
}
int
getNumRows
(
Id
resultId
)
const
{
return
getTypeNumRows
(
getTypeId
(
resultId
));
}
int
getNumRows
(
Id
resultId
)
const
{
return
getTypeNumRows
(
getTypeId
(
resultId
));
}
Dim
getTypeDimensionality
(
Id
typeId
)
const
Dim
getTypeDimensionality
(
Id
typeId
)
const
{
{
assert
(
isImageType
(
typeId
));
assert
(
isImageType
(
typeId
));
...
@@ -203,8 +196,7 @@ public:
...
@@ -203,8 +196,7 @@ public:
// Methods for adding information outside the CFG.
// Methods for adding information outside the CFG.
Instruction
*
addEntryPoint
(
ExecutionModel
,
Function
*
,
const
char
*
name
);
Instruction
*
addEntryPoint
(
ExecutionModel
,
Function
*
,
const
char
*
name
);
void
addExecutionMode
(
Function
*
,
ExecutionMode
mode
,
int
value1
=
-
1
,
int
value2
=
-
1
,
void
addExecutionMode
(
Function
*
,
ExecutionMode
mode
,
int
value1
=
-
1
,
int
value2
=
-
1
,
int
value3
=
-
1
);
int
value3
=
-
1
);
void
addName
(
Id
,
const
char
*
name
);
void
addName
(
Id
,
const
char
*
name
);
void
addMemberName
(
Id
,
int
member
,
const
char
*
name
);
void
addMemberName
(
Id
,
int
member
,
const
char
*
name
);
void
addLine
(
Id
target
,
Id
fileName
,
int
line
,
int
column
);
void
addLine
(
Id
target
,
Id
fileName
,
int
line
,
int
column
);
...
@@ -222,9 +214,8 @@ public:
...
@@ -222,9 +214,8 @@ public:
// Make a shader-style function, and create its entry block if entry is non-zero.
// Make a shader-style function, and create its entry block if entry is non-zero.
// Return the function, pass back the entry.
// Return the function, pass back the entry.
// The returned pointer is only valid for the lifetime of this builder.
// The returned pointer is only valid for the lifetime of this builder.
Function
*
makeFunctionEntry
(
Decoration
precision
,
Id
returnType
,
const
char
*
name
,
Function
*
makeFunctionEntry
(
Decoration
precision
,
Id
returnType
,
const
char
*
name
,
const
std
::
vector
<
Id
>&
paramTypes
,
const
std
::
vector
<
Id
>&
paramTypes
,
const
std
::
vector
<
Decoration
>&
precisions
,
Block
**
entry
=
0
);
const
std
::
vector
<
Decoration
>&
precisions
,
Block
**
entry
=
0
);
// Create a return. An 'implicit' return is one not appearing in the source
// Create a return. An 'implicit' return is one not appearing in the source
// code. In the case of an implicit return, no post-return block is inserted.
// code. In the case of an implicit return, no post-return block is inserted.
...
@@ -277,8 +268,7 @@ public:
...
@@ -277,8 +268,7 @@ public:
// Take an rvalue (source) and a set of channels to extract from it to
// Take an rvalue (source) and a set of channels to extract from it to
// make a new rvalue, which is returned.
// make a new rvalue, which is returned.
Id
createRvalueSwizzle
(
Decoration
precision
,
Id
typeId
,
Id
source
,
Id
createRvalueSwizzle
(
Decoration
precision
,
Id
typeId
,
Id
source
,
std
::
vector
<
unsigned
>&
channels
);
std
::
vector
<
unsigned
>&
channels
);
// Take a copy of an lvalue (target) and a source of components, and set the
// Take a copy of an lvalue (target) and a source of components, and set the
// source components into the lvalue where the 'channels' say to put them.
// source components into the lvalue where the 'channels' say to put them.
...
@@ -304,11 +294,10 @@ public:
...
@@ -304,11 +294,10 @@ public:
// - promoteScalar(scalar, scalar) // do nothing
// - promoteScalar(scalar, scalar) // do nothing
// Other forms are not allowed.
// Other forms are not allowed.
//
//
// Generally, the type of 'scalar' does not need to be the same type as the components in
// Generally, the type of 'scalar' does not need to be the same type as the components in 'vector'.
// 'vector'.
// The type of the created vector is a vector of components of the same type as the scalar.
// The type of the created vector is a vector of components of the same type as the scalar.
//
//
// Note: One of the arguments will change, with the result coming back that way rather than
// Note: One of the arguments will change, with the result coming back that way rather than
// through the return value.
// through the return value.
void
promoteScalar
(
Decoration
precision
,
Id
&
left
,
Id
&
right
);
void
promoteScalar
(
Decoration
precision
,
Id
&
left
,
Id
&
right
);
...
@@ -338,8 +327,7 @@ public:
...
@@ -338,8 +327,7 @@ public:
};
};
// Select the correct texture operation based on all inputs, and emit the correct instruction
// Select the correct texture operation based on all inputs, and emit the correct instruction
Id
createTextureCall
(
Decoration
precision
,
Id
resultType
,
bool
sparse
,
bool
fetch
,
bool
proj
,
Id
createTextureCall
(
Decoration
precision
,
Id
resultType
,
bool
sparse
,
bool
fetch
,
bool
proj
,
bool
gather
,
bool
noImplicit
,
const
TextureParameters
&
);
bool
gather
,
bool
noImplicit
,
const
TextureParameters
&
);
// Emit the OpTextureQuery* instruction that was passed in.
// Emit the OpTextureQuery* instruction that was passed in.
// Figure out the right return value and type, and return it.
// Figure out the right return value and type, and return it.
...
@@ -351,8 +339,7 @@ public:
...
@@ -351,8 +339,7 @@ public:
Id
createBitFieldInsertCall
(
Decoration
precision
,
Id
,
Id
,
Id
,
Id
);
Id
createBitFieldInsertCall
(
Decoration
precision
,
Id
,
Id
,
Id
,
Id
);
// Reduction comparison for composites: For equal and not-equal resulting in a scalar.
// Reduction comparison for composites: For equal and not-equal resulting in a scalar.
Id
createCompositeCompare
(
Decoration
precision
,
Id
,
Id
,
Id
createCompositeCompare
(
Decoration
precision
,
Id
,
Id
,
bool
/* true if for equal, false if for not-equal */
);
bool
/* true if for equal, false if for not-equal */
);
// OpCompositeConstruct
// OpCompositeConstruct
Id
createCompositeConstruct
(
Id
typeId
,
std
::
vector
<
Id
>&
constituents
);
Id
createCompositeConstruct
(
Id
typeId
,
std
::
vector
<
Id
>&
constituents
);
...
@@ -361,14 +348,14 @@ public:
...
@@ -361,14 +348,14 @@ public:
Id
createConstructor
(
Decoration
precision
,
const
std
::
vector
<
Id
>&
sources
,
Id
resultTypeId
);
Id
createConstructor
(
Decoration
precision
,
const
std
::
vector
<
Id
>&
sources
,
Id
resultTypeId
);
// matrix constructor
// matrix constructor
Id
createMatrixConstructor
(
Decoration
precision
,
const
std
::
vector
<
Id
>&
sources
,
Id
createMatrixConstructor
(
Decoration
precision
,
const
std
::
vector
<
Id
>&
sources
,
Id
constructee
);
Id
constructee
);
// Helper to use for building nested control flow with if-then-else.
// Helper to use for building nested control flow with if-then-else.
class
If
{
class
If
{
public
:
public
:
If
(
Id
condition
,
Builder
&
builder
);
If
(
Id
condition
,
Builder
&
builder
);
~
If
()
{}
~
If
()
{}
void
makeBeginElse
();
void
makeBeginElse
();
void
makeEndIf
();
void
makeEndIf
();
...
@@ -397,8 +384,7 @@ public:
...
@@ -397,8 +384,7 @@ public:
// Returns the right set of basic blocks to start each code segment with, so that the caller's
// Returns the right set of basic blocks to start each code segment with, so that the caller's
// recursion stack can hold the memory for it.
// recursion stack can hold the memory for it.
//
//
void
makeSwitch
(
Id
condition
,
int
numSegments
,
std
::
vector
<
int
>&
caseValues
,
void
makeSwitch
(
Id
condition
,
int
numSegments
,
std
::
vector
<
int
>&
caseValues
,
std
::
vector
<
int
>&
valueToSegment
,
int
defaultSegment
,
std
::
vector
<
int
>&
valueToSegment
,
int
defaultSegment
,
std
::
vector
<
Block
*>&
segmentBB
);
// return argument
std
::
vector
<
Block
*>&
segmentBB
);
// return argument
// Add a branch to the innermost switch's merge block.
// Add a branch to the innermost switch's merge block.
...
@@ -464,16 +450,13 @@ public:
...
@@ -464,16 +450,13 @@ public:
//
//
struct
AccessChain
{
struct
AccessChain
{
Id
base
;
// for l-values, pointer to the base object, for r-values, the base object
Id
base
;
// for l-values, pointer to the base object, for r-values, the base object
std
::
vector
<
Id
>
indexChain
;
std
::
vector
<
Id
>
indexChain
;
Id
instr
;
// cache the instruction that generates this access chain
Id
instr
;
// cache the instruction that generates this access chain
std
::
vector
<
unsigned
>
std
::
vector
<
unsigned
>
swizzle
;
// each std::vector element selects the next GLSL component number
swizzle
;
// each std::vector element selects the next GLSL component number
Id
component
;
// a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present
Id
component
;
// a dynamic component index, can coexist with a swizzle, done after the
Id
preSwizzleBaseType
;
// dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present
// swizzle, NoResult if not present
bool
isRValue
;
// true if 'base' is an r-value, otherwise, base is an l-value
Id
preSwizzleBaseType
;
// dereferenced type, before swizzle or component is applied; NoType
// unless a swizzle or component is present
bool
isRValue
;
// true if 'base' is an r-value, otherwise, base is an l-value
};
};
//
//
...
@@ -484,6 +467,7 @@ public:
...
@@ -484,6 +467,7 @@ public:
// for external save and restore
// for external save and restore
AccessChain
getAccessChain
()
{
return
accessChain
;
}
AccessChain
getAccessChain
()
{
return
accessChain
;
}
void
setAccessChain
(
AccessChain
newChain
)
{
accessChain
=
newChain
;
}
void
setAccessChain
(
AccessChain
newChain
)
{
accessChain
=
newChain
;
}
// clear accessChain
// clear accessChain
void
clearAccessChain
();
void
clearAccessChain
();
...
@@ -502,7 +486,11 @@ public:
...
@@ -502,7 +486,11 @@ public:
}
}
// push offset onto the end of the chain
// push offset onto the end of the chain
void
accessChainPush
(
Id
offset
)
{
accessChain
.
indexChain
.
push_back
(
offset
);
}
void
accessChainPush
(
Id
offset
)
{
accessChain
.
indexChain
.
push_back
(
offset
);
}
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
void
accessChainPushSwizzle
(
std
::
vector
<
unsigned
>&
swizzle
,
Id
preSwizzleBaseType
);
void
accessChainPushSwizzle
(
std
::
vector
<
unsigned
>&
swizzle
,
Id
preSwizzleBaseType
);
...
@@ -554,8 +542,7 @@ public:
...
@@ -554,8 +542,7 @@ public:
void
simplifyAccessChainSwizzle
();
void
simplifyAccessChainSwizzle
();
void
createAndSetNoPredecessorBlock
(
const
char
*
);
void
createAndSetNoPredecessorBlock
(
const
char
*
);
void
createSelectionMerge
(
Block
*
mergeBlock
,
unsigned
int
control
);
void
createSelectionMerge
(
Block
*
mergeBlock
,
unsigned
int
control
);
void
dumpInstructions
(
std
::
vector
<
unsigned
int
>&
,
void
dumpInstructions
(
std
::
vector
<
unsigned
int
>&
,
const
std
::
vector
<
std
::
unique_ptr
<
Instruction
>
>&
)
const
;
const
std
::
vector
<
std
::
unique_ptr
<
Instruction
>
>&
)
const
;
SourceLanguage
source
;
SourceLanguage
source
;
int
sourceVersion
;
int
sourceVersion
;
...
@@ -582,7 +569,7 @@ public:
...
@@ -582,7 +569,7 @@ public:
std
::
vector
<
std
::
unique_ptr
<
Instruction
>
>
externals
;
std
::
vector
<
std
::
unique_ptr
<
Instruction
>
>
externals
;
std
::
vector
<
std
::
unique_ptr
<
Function
>
>
functions
;
std
::
vector
<
std
::
unique_ptr
<
Function
>
>
functions
;
// not output, internally used for quick & dirty canonical (unique) creation
// not output, internally used for quick & dirty canonical (unique) creation
std
::
vector
<
Instruction
*>
groupedConstants
[
OpConstant
];
// all types appear before OpConstant
std
::
vector
<
Instruction
*>
groupedConstants
[
OpConstant
];
// all types appear before OpConstant
std
::
vector
<
Instruction
*>
groupedTypes
[
OpConstant
];
std
::
vector
<
Instruction
*>
groupedTypes
[
OpConstant
];
...
@@ -598,4 +585,4 @@ public:
...
@@ -598,4 +585,4 @@ public:
};
// end spv namespace
};
// end spv namespace
#endif
// SpvBuilder_H
#endif // SpvBuilder_H
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment