Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
angle
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
angle
Commits
28167c62
Commit
28167c62
authored
Aug 30, 2013
by
Jamie Madill
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for struct varyings, and more robust varying link validation.
TRAC #23749 Signed-off-by: Geoff Lang Signed-off-by: Nicolas Capens
parent
94599669
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
85 additions
and
43 deletions
+85
-43
angleutils.h
src/common/angleutils.h
+1
-0
OutputHLSL.cpp
src/compiler/OutputHLSL.cpp
+5
-3
ShaderVariable.h
src/compiler/ShaderVariable.h
+1
-0
ProgramBinary.cpp
src/libGLESv2/ProgramBinary.cpp
+70
-39
ProgramBinary.h
src/libGLESv2/ProgramBinary.h
+2
-1
Shader.cpp
src/libGLESv2/Shader.cpp
+6
-0
No files found.
src/common/angleutils.h
View file @
28167c62
...
...
@@ -67,5 +67,6 @@ void SafeDeleteArray(T*& resource)
#define GL_BGRA4_ANGLEX 0x6ABC
#define GL_BGR5_A1_ANGLEX 0x6ABD
#define GL_INT_64_ANGLEX 0x6ABE
#define GL_STRUCT_ANGLEX 0x6ABF
#endif // COMMON_ANGLEUTILS_H_
src/compiler/OutputHLSL.cpp
View file @
28167c62
...
...
@@ -3569,7 +3569,7 @@ void OutputHLSL::declareInterfaceBlockField(const TType &type, const TString &na
}
else
{
InterfaceBlockField
structField
(
GL_
NONE
,
GL_NONE
,
name
.
c_str
(),
(
unsigned
int
)
type
.
getArraySize
(),
false
);
InterfaceBlockField
structField
(
GL_
STRUCT_ANGLEX
,
GL_NONE
,
name
.
c_str
(),
(
unsigned
int
)
type
.
getArraySize
(),
false
);
const
TFieldList
&
fields
=
structure
->
fields
();
...
...
@@ -3603,7 +3603,7 @@ Uniform OutputHLSL::declareUniformToList(const TType &type, const TString &name,
}
else
{
Uniform
structUniform
(
GL_
NONE
,
GL_NONE
,
name
.
c_str
(),
(
unsigned
int
)
type
.
getArraySize
(),
(
unsigned
int
)
registerIndex
);
Uniform
structUniform
(
GL_
STRUCT_ANGLEX
,
GL_NONE
,
name
.
c_str
(),
(
unsigned
int
)
type
.
getArraySize
(),
(
unsigned
int
)
registerIndex
);
int
fieldRegister
=
registerIndex
;
const
TFieldList
&
fields
=
structure
->
fields
();
...
...
@@ -3658,9 +3658,11 @@ void OutputHLSL::declareVaryingToList(const TType &type, TQualifier baseTypeQual
}
else
{
Varying
structVarying
(
GL_
NONE
,
GL_NONE
,
name
.
c_str
(),
(
unsigned
int
)
type
.
getArraySize
(),
interpolation
);
Varying
structVarying
(
GL_
STRUCT_ANGLEX
,
GL_NONE
,
name
.
c_str
(),
(
unsigned
int
)
type
.
getArraySize
(),
interpolation
);
const
TFieldList
&
fields
=
structure
->
fields
();
structVarying
.
structName
=
structure
->
name
().
c_str
();
for
(
size_t
fieldIndex
=
0
;
fieldIndex
<
fields
.
size
();
fieldIndex
++
)
{
const
TField
&
field
=
*
fields
[
fieldIndex
];
...
...
src/compiler/ShaderVariable.h
View file @
28167c62
...
...
@@ -70,6 +70,7 @@ struct Varying : public ShaderVariable
std
::
vector
<
Varying
>
fields
;
unsigned
int
registerIndex
;
// Assigned during link
unsigned
int
elementIndex
;
// First register element for varyings, assigned during link
std
::
string
structName
;
Varying
(
GLenum
typeIn
,
GLenum
precisionIn
,
const
char
*
nameIn
,
unsigned
int
arraySizeIn
,
InterpolationType
interpolationIn
);
...
...
src/libGLESv2/ProgramBinary.cpp
View file @
28167c62
...
...
@@ -938,19 +938,21 @@ int ProgramBinary::packVaryings(InfoLog &infoLog, const sh::ShaderVariable *pack
{
sh
::
Varying
*
varying
=
&
fragmentShader
->
mVaryings
[
varyingIndex
];
GLenum
transposedType
=
TransposeMatrixType
(
varying
->
type
);
int
n
=
VariableRowCount
(
transposedType
)
*
varying
->
elementCount
();
int
m
=
VariableColumnCount
(
transposedType
);
// matrices within varying structs are not transposed
int
registers
=
(
varying
->
isStruct
()
?
sh
::
HLSLVariableRegisterCount
(
*
varying
)
:
gl
::
VariableRowCount
(
transposedType
))
*
varying
->
elementCount
();
int
elements
=
(
varying
->
isStruct
()
?
4
:
VariableColumnCount
(
transposedType
));
bool
success
=
false
;
if
(
m
==
2
||
m
==
3
||
m
==
4
)
if
(
elements
==
2
||
elements
==
3
||
elements
==
4
)
{
for
(
int
r
=
0
;
r
<=
maxVaryingVectors
-
n
&&
!
success
;
r
++
)
for
(
int
r
=
0
;
r
<=
maxVaryingVectors
-
registers
&&
!
success
;
r
++
)
{
bool
available
=
true
;
for
(
int
y
=
0
;
y
<
n
&&
available
;
y
++
)
for
(
int
y
=
0
;
y
<
registers
&&
available
;
y
++
)
{
for
(
int
x
=
0
;
x
<
m
&&
available
;
x
++
)
for
(
int
x
=
0
;
x
<
elements
&&
available
;
x
++
)
{
if
(
packing
[
r
+
y
][
x
])
{
...
...
@@ -964,9 +966,9 @@ int ProgramBinary::packVaryings(InfoLog &infoLog, const sh::ShaderVariable *pack
varying
->
registerIndex
=
r
;
varying
->
elementIndex
=
0
;
for
(
int
y
=
0
;
y
<
n
;
y
++
)
for
(
int
y
=
0
;
y
<
registers
;
y
++
)
{
for
(
int
x
=
0
;
x
<
m
;
x
++
)
for
(
int
x
=
0
;
x
<
elements
;
x
++
)
{
packing
[
r
+
y
][
x
]
=
&*
varying
;
}
...
...
@@ -976,13 +978,13 @@ int ProgramBinary::packVaryings(InfoLog &infoLog, const sh::ShaderVariable *pack
}
}
if
(
!
success
&&
m
==
2
)
if
(
!
success
&&
elements
==
2
)
{
for
(
int
r
=
maxVaryingVectors
-
n
;
r
>=
0
&&
!
success
;
r
--
)
for
(
int
r
=
maxVaryingVectors
-
registers
;
r
>=
0
&&
!
success
;
r
--
)
{
bool
available
=
true
;
for
(
int
y
=
0
;
y
<
n
&&
available
;
y
++
)
for
(
int
y
=
0
;
y
<
registers
&&
available
;
y
++
)
{
for
(
int
x
=
2
;
x
<
4
&&
available
;
x
++
)
{
...
...
@@ -998,7 +1000,7 @@ int ProgramBinary::packVaryings(InfoLog &infoLog, const sh::ShaderVariable *pack
varying
->
registerIndex
=
r
;
varying
->
elementIndex
=
2
;
for
(
int
y
=
0
;
y
<
n
;
y
++
)
for
(
int
y
=
0
;
y
<
registers
;
y
++
)
{
for
(
int
x
=
2
;
x
<
4
;
x
++
)
{
...
...
@@ -1011,7 +1013,7 @@ int ProgramBinary::packVaryings(InfoLog &infoLog, const sh::ShaderVariable *pack
}
}
}
else
if
(
m
==
1
)
else
if
(
elements
==
1
)
{
int
space
[
4
]
=
{
0
};
...
...
@@ -1027,13 +1029,13 @@ int ProgramBinary::packVaryings(InfoLog &infoLog, const sh::ShaderVariable *pack
for
(
int
x
=
0
;
x
<
4
;
x
++
)
{
if
(
space
[
x
]
>=
n
&&
space
[
x
]
<
space
[
column
])
if
(
space
[
x
]
>=
registers
&&
space
[
x
]
<
space
[
column
])
{
column
=
x
;
}
}
if
(
space
[
column
]
>=
n
)
if
(
space
[
column
]
>=
registers
)
{
for
(
int
r
=
0
;
r
<
maxVaryingVectors
;
r
++
)
{
...
...
@@ -1041,7 +1043,7 @@ int ProgramBinary::packVaryings(InfoLog &infoLog, const sh::ShaderVariable *pack
{
varying
->
registerIndex
=
r
;
for
(
int
y
=
r
;
y
<
r
+
n
;
y
++
)
for
(
int
y
=
r
;
y
<
r
+
registers
;
y
++
)
{
packing
[
y
][
column
]
=
&*
varying
;
}
...
...
@@ -1154,10 +1156,8 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const sh::Shad
sh
::
Varying
*
output
=
&
vertexShader
->
mVaryings
[
vertVaryingIndex
];
if
(
output
->
name
==
input
->
name
)
{
if
(
output
->
type
!=
input
->
type
||
output
->
arraySize
!=
input
->
arraySize
||
output
->
interpolation
!=
input
->
interpolation
)
if
(
!
linkValidateVariables
(
infoLog
,
output
->
name
,
*
input
,
*
output
)
)
{
infoLog
.
append
(
"Type of vertex varying %s does not match that of the fragment varying"
,
output
->
name
.
c_str
());
return
false
;
}
...
...
@@ -1308,7 +1308,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const sh::Shad
{
for
(
unsigned
int
elementIndex
=
0
;
elementIndex
<
varying
->
elementCount
();
elementIndex
++
)
{
int
variableRows
=
VariableRowCount
(
TransposeMatrixType
(
varying
->
type
));
int
variableRows
=
(
varying
->
isStruct
()
?
1
:
VariableRowCount
(
TransposeMatrixType
(
varying
->
type
)
));
for
(
int
row
=
0
;
row
<
variableRows
;
row
++
)
{
...
...
@@ -1508,7 +1508,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const sh::Shad
for
(
unsigned
int
elementIndex
=
0
;
elementIndex
<
varying
->
elementCount
();
elementIndex
++
)
{
GLenum
transposedType
=
TransposeMatrixType
(
varying
->
type
);
int
variableRows
=
VariableRowCount
(
transposedType
);
int
variableRows
=
(
varying
->
isStruct
()
?
1
:
VariableRowCount
(
transposedType
)
);
for
(
int
row
=
0
;
row
<
variableRows
;
row
++
)
{
std
::
string
n
=
str
(
varying
->
registerIndex
+
elementIndex
*
variableRows
+
row
);
...
...
@@ -1524,13 +1524,20 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const sh::Shad
pixelHLSL
+=
arrayString
(
row
);
}
switch
(
VariableColumnCount
(
transposedType
))
if
(
varying
->
isStruct
())
{
pixelHLSL
+=
" = input.v"
+
n
+
";
\n
"
;
break
;
}
else
{
case
1
:
pixelHLSL
+=
" = input.v"
+
n
+
".x;
\n
"
;
break
;
case
2
:
pixelHLSL
+=
" = input.v"
+
n
+
".xy;
\n
"
;
break
;
case
3
:
pixelHLSL
+=
" = input.v"
+
n
+
".xyz;
\n
"
;
break
;
case
4
:
pixelHLSL
+=
" = input.v"
+
n
+
";
\n
"
;
break
;
default
:
UNREACHABLE
();
switch
(
VariableColumnCount
(
transposedType
))
{
case
1
:
pixelHLSL
+=
" = input.v"
+
n
+
".x;
\n
"
;
break
;
case
2
:
pixelHLSL
+=
" = input.v"
+
n
+
".xy;
\n
"
;
break
;
case
3
:
pixelHLSL
+=
" = input.v"
+
n
+
".xyz;
\n
"
;
break
;
case
4
:
pixelHLSL
+=
" = input.v"
+
n
+
";
\n
"
;
break
;
default
:
UNREACHABLE
();
}
}
}
}
...
...
@@ -1589,7 +1596,7 @@ std::string ProgramBinary::generateVaryingHLSL(FragmentShader *fragmentShader, c
for
(
unsigned
int
elementIndex
=
0
;
elementIndex
<
varying
->
elementCount
();
elementIndex
++
)
{
GLenum
transposedType
=
TransposeMatrixType
(
varying
->
type
);
int
variableRows
=
VariableRowCount
(
transposedType
);
int
variableRows
=
(
varying
->
isStruct
()
?
1
:
VariableRowCount
(
transposedType
)
);
for
(
int
row
=
0
;
row
<
variableRows
;
row
++
)
{
switch
(
varying
->
interpolation
)
...
...
@@ -1601,7 +1608,10 @@ std::string ProgramBinary::generateVaryingHLSL(FragmentShader *fragmentShader, c
}
std
::
string
n
=
str
(
varying
->
registerIndex
+
elementIndex
*
variableRows
+
row
);
std
::
string
typeString
=
gl_d3d
::
TypeString
(
UniformComponentType
(
transposedType
))
+
str
(
VariableColumnCount
(
transposedType
));
// matrices within structs are not transposed, hence we do not use the special struct prefix "rm"
std
::
string
typeString
=
varying
->
isStruct
()
?
"_"
+
varying
->
structName
:
gl_d3d
::
TypeString
(
UniformComponentType
(
transposedType
))
+
str
(
VariableColumnCount
(
transposedType
));
varyingHLSL
+=
typeString
+
" v"
+
n
+
" : "
+
varyingSemantic
+
n
+
";
\n
"
;
}
...
...
@@ -2153,7 +2163,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
return
true
;
}
bool
ProgramBinary
::
linkValidateVariablesBase
(
InfoLog
&
infoLog
,
const
std
::
string
&
variableName
,
const
sh
::
ShaderVariable
&
vertexVariable
,
const
sh
::
ShaderVariable
&
fragmentVariable
)
bool
ProgramBinary
::
linkValidateVariablesBase
(
InfoLog
&
infoLog
,
const
std
::
string
&
variableName
,
const
sh
::
ShaderVariable
&
vertexVariable
,
const
sh
::
ShaderVariable
&
fragmentVariable
,
bool
validatePrecision
)
{
if
(
vertexVariable
.
type
!=
fragmentVariable
.
type
)
{
...
...
@@ -2165,7 +2175,7 @@ bool ProgramBinary::linkValidateVariablesBase(InfoLog &infoLog, const std::strin
infoLog
.
append
(
"Array sizes for %s differ between vertex and fragment shaders"
,
variableName
.
c_str
());
return
false
;
}
if
(
vertexVariable
.
precision
!=
fragmentVariable
.
precision
)
if
(
v
alidatePrecision
&&
v
ertexVariable
.
precision
!=
fragmentVariable
.
precision
)
{
infoLog
.
append
(
"Precisions for %s differ between vertex and fragment shaders"
,
variableName
.
c_str
());
return
false
;
...
...
@@ -2190,12 +2200,12 @@ bool ProgramBinary::linkValidateFields(InfoLog &infoLog, const std::string &varN
if
(
vertexMember
.
name
!=
fragmentMember
.
name
)
{
infoLog
.
append
(
"Name mismatch for field
%d
of %s: (in vertex: '%s', in fragment: '%s')"
,
memberIndex
,
varName
.
c_str
(),
vertex
Var
.
name
.
c_str
(),
fragmentVa
r
.
name
.
c_str
());
infoLog
.
append
(
"Name mismatch for field
'%d'
of %s: (in vertex: '%s', in fragment: '%s')"
,
memberIndex
,
varName
.
c_str
(),
vertex
Member
.
name
.
c_str
(),
fragmentMembe
r
.
name
.
c_str
());
return
false
;
}
const
std
::
string
memberName
=
varName
+
"."
+
vertexVar
.
name
;
const
std
::
string
memberName
=
varName
.
substr
(
0
,
varName
.
length
()
-
1
)
+
"."
+
vertexVar
.
name
+
"'"
;
if
(
!
linkValidateVariables
(
infoLog
,
memberName
,
vertexMember
,
fragmentMember
))
{
return
false
;
...
...
@@ -2207,7 +2217,7 @@ bool ProgramBinary::linkValidateFields(InfoLog &infoLog, const std::string &varN
bool
ProgramBinary
::
linkValidateVariables
(
InfoLog
&
infoLog
,
const
std
::
string
&
uniformName
,
const
sh
::
Uniform
&
vertexUniform
,
const
sh
::
Uniform
&
fragmentUniform
)
{
if
(
!
linkValidateVariablesBase
(
infoLog
,
uniformName
,
vertexUniform
,
fragmentUniform
))
if
(
!
linkValidateVariablesBase
(
infoLog
,
uniformName
,
vertexUniform
,
fragmentUniform
,
true
))
{
return
false
;
}
...
...
@@ -2220,9 +2230,30 @@ bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &u
return
true
;
}
bool
ProgramBinary
::
linkValidateVariables
(
InfoLog
&
infoLog
,
const
std
::
string
&
varyingName
,
const
sh
::
Varying
&
vertexVarying
,
const
sh
::
Varying
&
fragmentVarying
)
{
if
(
!
linkValidateVariablesBase
(
infoLog
,
varyingName
,
vertexVarying
,
fragmentVarying
,
false
))
{
return
false
;
}
if
(
vertexVarying
.
interpolation
!=
fragmentVarying
.
interpolation
)
{
infoLog
.
append
(
"Interpolation types for %s differ between vertex and fragment shaders"
,
varyingName
.
c_str
());
return
false
;
}
if
(
!
linkValidateFields
<
sh
::
Varying
>
(
infoLog
,
varyingName
,
vertexVarying
,
fragmentVarying
))
{
return
false
;
}
return
true
;
}
bool
ProgramBinary
::
linkValidateVariables
(
InfoLog
&
infoLog
,
const
std
::
string
&
uniformName
,
const
sh
::
InterfaceBlockField
&
vertexUniform
,
const
sh
::
InterfaceBlockField
&
fragmentUniform
)
{
if
(
!
linkValidateVariablesBase
(
infoLog
,
uniformName
,
vertexUniform
,
fragmentUniform
))
if
(
!
linkValidateVariablesBase
(
infoLog
,
uniformName
,
vertexUniform
,
fragmentUniform
,
true
))
{
return
false
;
}
...
...
@@ -2260,7 +2291,7 @@ bool ProgramBinary::linkUniforms(InfoLog &infoLog, const std::vector<sh::Uniform
if
(
entry
!=
linkedUniforms
.
end
())
{
const
sh
::
Uniform
&
vertexUniform
=
*
entry
->
second
;
const
std
::
string
&
uniformName
=
"uniform
"
+
vertexUniform
.
name
;
const
std
::
string
&
uniformName
=
"uniform
'"
+
vertexUniform
.
name
+
"'"
;
if
(
!
linkValidateVariables
(
infoLog
,
uniformName
,
vertexUniform
,
fragmentUniform
))
{
return
false
;
...
...
@@ -2519,12 +2550,12 @@ bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::Inter
if
(
vertexMember
.
name
!=
fragmentMember
.
name
)
{
infoLog
.
append
(
"Name mismatch for field %d of interface block
%s
: (in vertex: '%s', in fragment: '%s')"
,
infoLog
.
append
(
"Name mismatch for field %d of interface block
'%s'
: (in vertex: '%s', in fragment: '%s')"
,
blockMemberIndex
,
blockName
,
vertexMember
.
name
.
c_str
(),
fragmentMember
.
name
.
c_str
());
return
false
;
}
std
::
string
uniformName
=
"interface block
"
+
vertexInterfaceBlock
.
name
+
" member "
+
vertexMember
.
name
;
std
::
string
uniformName
=
"interface block
'"
+
vertexInterfaceBlock
.
name
+
"' member '"
+
vertexMember
.
name
+
"'"
;
if
(
!
linkValidateVariables
(
infoLog
,
uniformName
,
vertexMember
,
fragmentMember
))
{
return
false
;
...
...
src/libGLESv2/ProgramBinary.h
View file @
28167c62
...
...
@@ -159,9 +159,10 @@ class ProgramBinary : public RefCountObject
template
<
class
ShaderVarType
>
bool
linkValidateFields
(
InfoLog
&
infoLog
,
const
std
::
string
&
varName
,
const
ShaderVarType
&
vertexVar
,
const
ShaderVarType
&
fragmentVar
);
bool
linkValidateVariablesBase
(
InfoLog
&
infoLog
,
const
std
::
string
&
variableName
,
const
sh
::
ShaderVariable
&
vertexVariable
,
const
sh
::
ShaderVariable
&
fragmentVariable
);
bool
linkValidateVariablesBase
(
InfoLog
&
infoLog
,
const
std
::
string
&
variableName
,
const
sh
::
ShaderVariable
&
vertexVariable
,
const
sh
::
ShaderVariable
&
fragmentVariable
,
bool
validatePrecision
);
bool
linkValidateVariables
(
InfoLog
&
infoLog
,
const
std
::
string
&
uniformName
,
const
sh
::
Uniform
&
vertexUniform
,
const
sh
::
Uniform
&
fragmentUniform
);
bool
linkValidateVariables
(
InfoLog
&
infoLog
,
const
std
::
string
&
varyingName
,
const
sh
::
Varying
&
vertexVarying
,
const
sh
::
Varying
&
fragmentVarying
);
bool
linkValidateVariables
(
InfoLog
&
infoLog
,
const
std
::
string
&
uniformName
,
const
sh
::
InterfaceBlockField
&
vertexUniform
,
const
sh
::
InterfaceBlockField
&
fragmentUniform
);
bool
linkUniforms
(
InfoLog
&
infoLog
,
const
std
::
vector
<
sh
::
Uniform
>
&
vertexUniforms
,
const
std
::
vector
<
sh
::
Uniform
>
&
fragmentUniforms
);
bool
defineUniform
(
GLenum
shader
,
const
sh
::
Uniform
&
constant
,
InfoLog
&
infoLog
);
...
...
src/libGLESv2/Shader.cpp
View file @
28167c62
...
...
@@ -417,6 +417,12 @@ bool Shader::compareVarying(const sh::ShaderVariable &x, const sh::ShaderVariabl
return
x
.
arraySize
>
y
.
arraySize
;
}
// Special case for handling structs: we sort these to the end of the list
if
(
x
.
type
==
GL_STRUCT_ANGLEX
)
{
return
false
;
}
unsigned
int
xPriority
=
GL_INVALID_INDEX
;
unsigned
int
yPriority
=
GL_INVALID_INDEX
;
...
...
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