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
9dd5dbd8
Commit
9dd5dbd8
authored
Jul 12, 2017
by
Commit Bot
Committed by
Gerrit Code Review
Jul 12, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge "Link atomic counters to buffers"
parents
1636e1b9
eaef1e5e
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
356 additions
and
84 deletions
+356
-84
ShaderVars.cpp
src/compiler/translator/ShaderVars.cpp
+3
-2
MemoryProgramCache.cpp
src/libANGLE/MemoryProgramCache.cpp
+56
-20
Program.cpp
src/libANGLE/Program.cpp
+67
-6
Program.h
src/libANGLE/Program.h
+14
-3
Uniform.cpp
src/libANGLE/Uniform.cpp
+26
-19
Uniform.h
src/libANGLE/Uniform.h
+27
-11
UniformLinker.cpp
src/libANGLE/UniformLinker.cpp
+76
-16
UniformLinker.h
src/libANGLE/UniformLinker.h
+13
-2
queryutils.cpp
src/libANGLE/queryutils.cpp
+4
-4
validationES.cpp
src/libANGLE/validationES.cpp
+1
-1
AtomicCounterBufferTest.cpp
src/tests/gl_tests/AtomicCounterBufferTest.cpp
+69
-0
No files found.
src/compiler/translator/ShaderVars.cpp
View file @
9dd5dbd8
...
...
@@ -210,7 +210,9 @@ bool Uniform::operator==(const Uniform &other) const
bool
Uniform
::
isSameUniformAtLinkTime
(
const
Uniform
&
other
)
const
{
if
(
binding
!=
other
.
binding
)
// Enforce a consistent match.
// https://cvs.khronos.org/bugzilla/show_bug.cgi?id=16261
if
(
binding
!=
-
1
&&
other
.
binding
!=
-
1
&&
binding
!=
other
.
binding
)
{
return
false
;
}
...
...
@@ -218,7 +220,6 @@ bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const
{
return
false
;
}
// TODO(jie.a.chen@intel.com): Add a test case to cover this.
if
(
offset
!=
other
.
offset
)
{
return
false
;
...
...
src/libANGLE/MemoryProgramCache.cpp
View file @
9dd5dbd8
...
...
@@ -49,6 +49,37 @@ void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var)
var
->
structName
=
stream
->
readString
();
}
void
WriteShaderVariableBuffer
(
BinaryOutputStream
*
stream
,
const
ShaderVariableBuffer
&
var
)
{
stream
->
writeInt
(
var
.
binding
);
stream
->
writeInt
(
var
.
dataSize
);
stream
->
writeInt
(
var
.
vertexStaticUse
);
stream
->
writeInt
(
var
.
fragmentStaticUse
);
stream
->
writeInt
(
var
.
computeStaticUse
);
stream
->
writeInt
(
var
.
memberIndexes
.
size
());
for
(
unsigned
int
memberCounterIndex
:
var
.
memberIndexes
)
{
stream
->
writeInt
(
memberCounterIndex
);
}
}
void
LoadShaderVariableBuffer
(
BinaryInputStream
*
stream
,
ShaderVariableBuffer
*
var
)
{
var
->
binding
=
stream
->
readInt
<
int
>
();
var
->
dataSize
=
stream
->
readInt
<
unsigned
int
>
();
var
->
vertexStaticUse
=
stream
->
readBool
();
var
->
fragmentStaticUse
=
stream
->
readBool
();
var
->
computeStaticUse
=
stream
->
readBool
();
unsigned
int
numMembers
=
stream
->
readInt
<
unsigned
int
>
();
for
(
unsigned
int
blockMemberIndex
=
0
;
blockMemberIndex
<
numMembers
;
blockMemberIndex
++
)
{
var
->
memberIndexes
.
push_back
(
stream
->
readInt
<
unsigned
int
>
());
}
}
class
HashStream
final
:
angle
::
NonCopyable
{
public
:
...
...
@@ -158,7 +189,7 @@ LinkResult MemoryProgramCache::Deserialize(const Context *context,
LinkedUniform
uniform
;
LoadShaderVar
(
&
stream
,
&
uniform
);
uniform
.
b
lockIndex
=
stream
.
readInt
<
int
>
();
uniform
.
b
ufferIndex
=
stream
.
readInt
<
int
>
();
uniform
.
blockInfo
.
offset
=
stream
.
readInt
<
int
>
();
uniform
.
blockInfo
.
arrayStride
=
stream
.
readInt
<
int
>
();
uniform
.
blockInfo
.
matrixStride
=
stream
.
readInt
<
int
>
();
...
...
@@ -191,21 +222,22 @@ LinkResult MemoryProgramCache::Deserialize(const Context *context,
stream
.
readString
(
&
uniformBlock
.
name
);
stream
.
readBool
(
&
uniformBlock
.
isArray
);
stream
.
readInt
(
&
uniformBlock
.
arrayElement
);
stream
.
readInt
(
&
uniformBlock
.
binding
);
stream
.
readInt
(
&
uniformBlock
.
dataSize
);
stream
.
readBool
(
&
uniformBlock
.
vertexStaticUse
);
stream
.
readBool
(
&
uniformBlock
.
fragmentStaticUse
);
unsigned
int
numMembers
=
stream
.
readInt
<
unsigned
int
>
();
for
(
unsigned
int
blockMemberIndex
=
0
;
blockMemberIndex
<
numMembers
;
blockMemberIndex
++
)
{
uniformBlock
.
memberUniformIndexes
.
push_back
(
stream
.
readInt
<
unsigned
int
>
());
}
LoadShaderVariableBuffer
(
&
stream
,
&
uniformBlock
);
state
->
mUniformBlocks
.
push_back
(
uniformBlock
);
state
->
mActiveUniformBlockBindings
.
set
(
uniformBlockIndex
,
uniformBlock
.
binding
!=
0
);
}
unsigned
int
atomicCounterBufferCount
=
stream
.
readInt
<
unsigned
int
>
();
ASSERT
(
state
->
mAtomicCounterBuffers
.
empty
());
for
(
unsigned
int
bufferIndex
=
0
;
bufferIndex
<
atomicCounterBufferCount
;
++
bufferIndex
)
{
AtomicCounterBuffer
atomicCounterBuffer
;
LoadShaderVariableBuffer
(
&
stream
,
&
atomicCounterBuffer
);
state
->
mAtomicCounterBuffers
.
push_back
(
atomicCounterBuffer
);
}
unsigned
int
transformFeedbackVaryingCount
=
stream
.
readInt
<
unsigned
int
>
();
...
...
@@ -286,6 +318,10 @@ LinkResult MemoryProgramCache::Deserialize(const Context *context,
state
->
mImageBindings
.
emplace_back
(
ImageBinding
(
boundImageUnit
,
elementCount
));
}
unsigned
int
atomicCounterRangeLow
=
stream
.
readInt
<
unsigned
int
>
();
unsigned
int
atomicCounterRangeHigh
=
stream
.
readInt
<
unsigned
int
>
();
state
->
mAtomicCounterUniformRange
=
RangeUI
(
atomicCounterRangeLow
,
atomicCounterRangeHigh
);
return
program
->
getImplementation
()
->
load
(
context
,
infoLog
,
&
stream
);
}
...
...
@@ -335,7 +371,7 @@ void MemoryProgramCache::Serialize(const Context *context,
// FIXME: referenced
stream
.
writeInt
(
uniform
.
b
lock
Index
);
stream
.
writeInt
(
uniform
.
b
uffer
Index
);
stream
.
writeInt
(
uniform
.
blockInfo
.
offset
);
stream
.
writeInt
(
uniform
.
blockInfo
.
arrayStride
);
stream
.
writeInt
(
uniform
.
blockInfo
.
matrixStride
);
...
...
@@ -358,17 +394,14 @@ void MemoryProgramCache::Serialize(const Context *context,
stream
.
writeString
(
uniformBlock
.
name
);
stream
.
writeInt
(
uniformBlock
.
isArray
);
stream
.
writeInt
(
uniformBlock
.
arrayElement
);
stream
.
writeInt
(
uniformBlock
.
binding
);
stream
.
writeInt
(
uniformBlock
.
dataSize
);
stream
.
writeInt
(
uniformBlock
.
vertexStaticUse
);
stream
.
writeInt
(
uniformBlock
.
fragmentStaticUse
);
WriteShaderVariableBuffer
(
&
stream
,
uniformBlock
);
}
stream
.
writeInt
(
uniformBlock
.
memberUniformIndexes
.
size
());
for
(
unsigned
int
memberUniformIndex
:
uniformBlock
.
memberUniformIndexes
)
{
stream
.
writeInt
(
memberUniformIndex
);
}
stream
.
writeInt
(
state
.
mAtomicCounterBuffers
.
size
());
for
(
const
auto
&
atomicCounterBuffer
:
state
.
mAtomicCounterBuffers
)
{
WriteShaderVariableBuffer
(
&
stream
,
atomicCounterBuffer
);
}
// Warn the app layer if saving a binary with unsupported transform feedback.
...
...
@@ -437,6 +470,9 @@ void MemoryProgramCache::Serialize(const Context *context,
stream
.
writeInt
(
imageBinding
.
elementCount
);
}
stream
.
writeInt
(
state
.
getAtomicCounterUniformRange
().
low
());
stream
.
writeInt
(
state
.
getAtomicCounterUniformRange
().
high
());
program
->
getImplementation
()
->
save
(
context
,
&
stream
);
ASSERT
(
binaryOut
);
...
...
src/libANGLE/Program.cpp
View file @
9dd5dbd8
...
...
@@ -296,6 +296,8 @@ ProgramState::ProgramState()
mAttachedComputeShader
(
nullptr
),
mTransformFeedbackBufferMode
(
GL_INTERLEAVED_ATTRIBS
),
mSamplerUniformRange
(
0
,
0
),
mImageUniformRange
(
0
,
0
),
mAtomicCounterUniformRange
(
0
,
0
),
mBinaryRetrieveableHint
(
false
)
{
mComputeShaderLocalSize
.
fill
(
1
);
...
...
@@ -757,10 +759,11 @@ Error Program::link(const gl::Context *context)
gatherTransformFeedbackVaryings
(
mergedVaryings
);
}
setUniformValuesFromBindingQualifiers
();
gatherAtomicCounterBuffers
();
gatherInterfaceBlockInfo
(
context
);
setUniformValuesFromBindingQualifiers
();
// Save to the program cache.
if
(
cache
&&
(
mState
.
mLinkedTransformFeedbackVaryings
.
empty
()
||
!
context
->
getWorkarounds
().
disableProgramCachingForTransformFeedback
))
...
...
@@ -781,12 +784,14 @@ void Program::unlink()
mState
.
mUniformLocations
.
clear
();
mState
.
mUniformBlocks
.
clear
();
mState
.
mActiveUniformBlockBindings
.
reset
();
mState
.
mAtomicCounterBuffers
.
clear
();
mState
.
mOutputVariables
.
clear
();
mState
.
mOutputLocations
.
clear
();
mState
.
mOutputVariableTypes
.
clear
();
mState
.
mActiveOutputVariables
.
reset
();
mState
.
mComputeShaderLocalSize
.
fill
(
1
);
mState
.
mSamplerBindings
.
clear
();
mState
.
mImageBindings
.
clear
();
mValidated
=
false
;
...
...
@@ -1219,7 +1224,8 @@ GLint Program::getActiveUniformi(GLuint index, GLenum pname) const
case
GL_UNIFORM_TYPE
:
return
static_cast
<
GLint
>
(
uniform
.
type
);
case
GL_UNIFORM_SIZE
:
return
static_cast
<
GLint
>
(
uniform
.
elementCount
());
case
GL_UNIFORM_NAME_LENGTH
:
return
static_cast
<
GLint
>
(
uniform
.
name
.
size
()
+
1
+
(
uniform
.
isArray
()
?
3
:
0
));
case
GL_UNIFORM_BLOCK_INDEX
:
return
uniform
.
blockIndex
;
case
GL_UNIFORM_BLOCK_INDEX
:
return
uniform
.
bufferIndex
;
case
GL_UNIFORM_OFFSET
:
return
uniform
.
blockInfo
.
offset
;
case
GL_UNIFORM_ARRAY_STRIDE
:
return
uniform
.
blockInfo
.
arrayStride
;
case
GL_UNIFORM_MATRIX_STRIDE
:
return
uniform
.
blockInfo
.
matrixStride
;
...
...
@@ -1763,6 +1769,11 @@ bool Program::linkUniforms(const Context *context,
linkSamplerAndImageBindings
();
if
(
!
linkAtomicCounterBuffers
())
{
return
false
;
}
return
true
;
}
...
...
@@ -1771,6 +1782,16 @@ void Program::linkSamplerAndImageBindings()
unsigned
int
high
=
static_cast
<
unsigned
int
>
(
mState
.
mUniforms
.
size
());
unsigned
int
low
=
high
;
for
(
auto
counterIter
=
mState
.
mUniforms
.
rbegin
();
counterIter
!=
mState
.
mUniforms
.
rend
()
&&
counterIter
->
isAtomicCounter
();
++
counterIter
)
{
--
low
;
}
mState
.
mAtomicCounterUniformRange
=
RangeUI
(
low
,
high
);
high
=
low
;
for
(
auto
imageIter
=
mState
.
mUniforms
.
rbegin
();
imageIter
!=
mState
.
mUniforms
.
rend
()
&&
imageIter
->
isImage
();
++
imageIter
)
{
...
...
@@ -1815,6 +1836,39 @@ void Program::linkSamplerAndImageBindings()
}
}
bool
Program
::
linkAtomicCounterBuffers
()
{
for
(
unsigned
int
index
:
mState
.
mAtomicCounterUniformRange
)
{
auto
&
uniform
=
mState
.
mUniforms
[
index
];
bool
found
=
false
;
for
(
unsigned
int
bufferIndex
=
0
;
bufferIndex
<
mState
.
mAtomicCounterBuffers
.
size
();
++
bufferIndex
)
{
auto
&
buffer
=
mState
.
mAtomicCounterBuffers
[
bufferIndex
];
if
(
buffer
.
binding
==
uniform
.
binding
)
{
buffer
.
memberIndexes
.
push_back
(
index
);
uniform
.
bufferIndex
=
bufferIndex
;
found
=
true
;
break
;
}
}
if
(
!
found
)
{
AtomicCounterBuffer
atomicCounterBuffer
;
atomicCounterBuffer
.
binding
=
uniform
.
binding
;
atomicCounterBuffer
.
memberIndexes
.
push_back
(
index
);
mState
.
mAtomicCounterBuffers
.
push_back
(
atomicCounterBuffer
);
uniform
.
bufferIndex
=
static_cast
<
int
>
(
mState
.
mAtomicCounterBuffers
.
size
()
-
1
);
}
}
// TODO(jie.a.chen@intel.com): Count each atomic counter buffer to validate against
// gl_Max[Vertex|Fragment|Compute|Combined]AtomicCounterBuffers.
return
true
;
}
bool
Program
::
linkValidateInterfaceBlockFields
(
InfoLog
&
infoLog
,
const
std
::
string
&
uniformName
,
const
sh
::
InterfaceBlockField
&
vertexUniform
,
...
...
@@ -2530,6 +2584,13 @@ void Program::setUniformValuesFromBindingQualifiers()
}
}
void
Program
::
gatherAtomicCounterBuffers
()
{
// TODO(jie.a.chen@intel.com): Get the actual OFFSET and ARRAY_STRIDE from the backend for each
// counter.
// TODO(jie.a.chen@intel.com): Get the actual BUFFER_DATA_SIZE from backend for each buffer.
}
void
Program
::
gatherInterfaceBlockInfo
(
const
Context
*
context
)
{
ASSERT
(
mState
.
mUniformBlocks
.
empty
());
...
...
@@ -2635,7 +2696,7 @@ void Program::defineUniformBlockMembers(const std::vector<VarT> &fields,
}
LinkedUniform
newUniform
(
field
.
type
,
field
.
precision
,
fullName
,
field
.
arraySize
,
-
1
,
-
1
,
blockIndex
,
memberInfo
);
-
1
,
blockIndex
,
memberInfo
);
// Since block uniforms have no location, we don't need to store them in the uniform
// locations list.
...
...
@@ -2677,7 +2738,7 @@ void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenu
}
UniformBlock
block
(
interfaceBlock
.
name
,
true
,
arrayElement
,
blockBinding
+
arrayElement
);
block
.
member
Uniform
Indexes
=
blockUniformIndexes
;
block
.
memberIndexes
=
blockUniformIndexes
;
switch
(
shaderType
)
{
...
...
@@ -2714,7 +2775,7 @@ void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenu
return
;
}
UniformBlock
block
(
interfaceBlock
.
name
,
false
,
0
,
blockBinding
);
block
.
member
Uniform
Indexes
=
blockUniformIndexes
;
block
.
memberIndexes
=
blockUniformIndexes
;
switch
(
shaderType
)
{
...
...
src/libANGLE/Program.h
View file @
9dd5dbd8
...
...
@@ -246,11 +246,16 @@ class ProgramState final : angle::NonCopyable
const
sh
::
WorkGroupSize
&
getComputeShaderLocalSize
()
const
{
return
mComputeShaderLocalSize
;
}
const
RangeUI
&
getSamplerUniformRange
()
const
{
return
mSamplerUniformRange
;
}
const
RangeUI
&
getImageUniformRange
()
const
{
return
mImageUniformRange
;
}
const
RangeUI
&
getAtomicCounterUniformRange
()
const
{
return
mAtomicCounterUniformRange
;
}
const
std
::
vector
<
TransformFeedbackVarying
>
&
getLinkedTransformFeedbackVaryings
()
const
{
return
mLinkedTransformFeedbackVaryings
;
}
const
std
::
vector
<
AtomicCounterBuffer
>
&
getAtomicCounterBuffers
()
const
{
return
mAtomicCounterBuffers
;
}
GLint
getUniformLocation
(
const
std
::
string
&
name
)
const
;
GLuint
getUniformIndexFromName
(
const
std
::
string
&
name
)
const
;
...
...
@@ -283,15 +288,19 @@ class ProgramState final : angle::NonCopyable
angle
::
BitSet
<
MAX_VERTEX_ATTRIBS
>
mActiveAttribLocationsMask
;
// Uniforms are sorted in order:
// 1. Non-
sampler
uniforms
// 1. Non-
opaque
uniforms
// 2. Sampler uniforms
// 3. Uniform block uniforms
// This makes sampler validation easier, since we don't need a separate list.
// 3. Image uniforms
// 4. Atomic counter uniforms
// 5. Uniform block uniforms
// This makes opaque uniform validation easier, since we don't need a separate list.
std
::
vector
<
LinkedUniform
>
mUniforms
;
std
::
vector
<
VariableLocation
>
mUniformLocations
;
std
::
vector
<
UniformBlock
>
mUniformBlocks
;
std
::
vector
<
AtomicCounterBuffer
>
mAtomicCounterBuffers
;
RangeUI
mSamplerUniformRange
;
RangeUI
mImageUniformRange
;
RangeUI
mAtomicCounterUniformRange
;
// An array of the samplers that are used by the program
std
::
vector
<
gl
::
SamplerBinding
>
mSamplerBindings
;
...
...
@@ -540,6 +549,7 @@ class Program final : angle::NonCopyable, public LabeledObject
InfoLog
&
infoLog
,
const
Bindings
&
uniformLocationBindings
);
void
linkSamplerAndImageBindings
();
bool
linkAtomicCounterBuffers
();
bool
areMatchingInterfaceBlocks
(
InfoLog
&
infoLog
,
const
sh
::
InterfaceBlock
&
vertexInterfaceBlock
,
...
...
@@ -565,6 +575,7 @@ class Program final : angle::NonCopyable, public LabeledObject
void
setUniformValuesFromBindingQualifiers
();
void
gatherAtomicCounterBuffers
();
void
gatherInterfaceBlockInfo
(
const
Context
*
context
);
template
<
typename
VarT
>
void
defineUniformBlockMembers
(
const
std
::
vector
<
VarT
>
&
fields
,
...
...
src/libANGLE/Uniform.cpp
View file @
9dd5dbd8
...
...
@@ -14,7 +14,7 @@ namespace gl
{
LinkedUniform
::
LinkedUniform
()
:
b
lock
Index
(
-
1
),
blockInfo
(
sh
::
BlockMemberInfo
::
getDefaultBlockInfo
())
:
b
uffer
Index
(
-
1
),
blockInfo
(
sh
::
BlockMemberInfo
::
getDefaultBlockInfo
())
{
}
...
...
@@ -23,26 +23,28 @@ LinkedUniform::LinkedUniform(GLenum typeIn,
const
std
::
string
&
nameIn
,
unsigned
int
arraySizeIn
,
const
int
bindingIn
,
const
int
offsetIn
,
const
int
locationIn
,
const
int
b
lock
IndexIn
,
const
int
b
uffer
IndexIn
,
const
sh
::
BlockMemberInfo
&
blockInfoIn
)
:
b
lockIndex
(
block
IndexIn
),
blockInfo
(
blockInfoIn
)
:
b
ufferIndex
(
buffer
IndexIn
),
blockInfo
(
blockInfoIn
)
{
type
=
typeIn
;
precision
=
precisionIn
;
name
=
nameIn
;
arraySize
=
arraySizeIn
;
binding
=
bindingIn
;
offset
=
offsetIn
;
location
=
locationIn
;
}
LinkedUniform
::
LinkedUniform
(
const
sh
::
Uniform
&
uniform
)
:
sh
::
Uniform
(
uniform
),
b
lock
Index
(
-
1
),
blockInfo
(
sh
::
BlockMemberInfo
::
getDefaultBlockInfo
())
:
sh
::
Uniform
(
uniform
),
b
uffer
Index
(
-
1
),
blockInfo
(
sh
::
BlockMemberInfo
::
getDefaultBlockInfo
())
{
}
LinkedUniform
::
LinkedUniform
(
const
LinkedUniform
&
uniform
)
:
sh
::
Uniform
(
uniform
),
b
lockIndex
(
uniform
.
block
Index
),
blockInfo
(
uniform
.
blockInfo
)
:
sh
::
Uniform
(
uniform
),
b
ufferIndex
(
uniform
.
buffer
Index
),
blockInfo
(
uniform
.
blockInfo
)
{
// This function is not intended to be called during runtime.
ASSERT
(
uniform
.
mLazyData
.
empty
());
...
...
@@ -54,7 +56,7 @@ LinkedUniform &LinkedUniform::operator=(const LinkedUniform &uniform)
ASSERT
(
uniform
.
mLazyData
.
empty
());
sh
::
Uniform
::
operator
=
(
uniform
);
b
lockIndex
=
uniform
.
block
Index
;
b
ufferIndex
=
uniform
.
buffer
Index
;
blockInfo
=
uniform
.
blockInfo
;
return
*
this
;
...
...
@@ -66,7 +68,7 @@ LinkedUniform::~LinkedUniform()
bool
LinkedUniform
::
isInDefaultBlock
()
const
{
return
b
lock
Index
==
-
1
;
return
b
uffer
Index
==
-
1
;
}
size_t
LinkedUniform
::
dataSize
()
const
...
...
@@ -108,6 +110,11 @@ bool LinkedUniform::isImage() const
return
IsImageType
(
type
);
}
bool
LinkedUniform
::
isAtomicCounter
()
const
{
return
IsAtomicCounterType
(
type
);
}
bool
LinkedUniform
::
isField
()
const
{
return
name
.
find
(
'.'
)
!=
std
::
string
::
npos
;
...
...
@@ -134,10 +141,8 @@ const uint8_t *LinkedUniform::getDataPtrToElement(size_t elementIndex) const
return
const_cast
<
LinkedUniform
*>
(
this
)
->
getDataPtrToElement
(
elementIndex
);
}
UniformBlock
::
UniformBlock
()
:
isArray
(
false
),
arrayElement
(
0
),
binding
(
0
),
ShaderVariableBuffer
::
ShaderVariableBuffer
()
:
binding
(
0
),
dataSize
(
0
),
vertexStaticUse
(
false
),
fragmentStaticUse
(
false
),
...
...
@@ -145,19 +150,21 @@ UniformBlock::UniformBlock()
{
}
ShaderVariableBuffer
::~
ShaderVariableBuffer
()
{
}
UniformBlock
::
UniformBlock
()
:
isArray
(
false
),
arrayElement
(
0
)
{
}
UniformBlock
::
UniformBlock
(
const
std
::
string
&
nameIn
,
bool
isArrayIn
,
unsigned
int
arrayElementIn
,
int
bindingIn
)
:
name
(
nameIn
),
isArray
(
isArrayIn
),
arrayElement
(
arrayElementIn
),
binding
(
bindingIn
),
dataSize
(
0
),
vertexStaticUse
(
false
),
fragmentStaticUse
(
false
),
computeStaticUse
(
false
)
:
name
(
nameIn
),
isArray
(
isArrayIn
),
arrayElement
(
arrayElementIn
)
{
binding
=
bindingIn
;
}
std
::
string
UniformBlock
::
nameWithArrayIndex
()
const
...
...
src/libANGLE/Uniform.h
View file @
9dd5dbd8
...
...
@@ -28,8 +28,9 @@ struct LinkedUniform : public sh::Uniform
const
std
::
string
&
name
,
unsigned
int
arraySize
,
const
int
binding
,
const
int
offset
,
const
int
location
,
const
int
b
lock
Index
,
const
int
b
uffer
Index
,
const
sh
::
BlockMemberInfo
&
blockInfo
);
LinkedUniform
(
const
sh
::
Uniform
&
uniform
);
LinkedUniform
(
const
LinkedUniform
&
uniform
);
...
...
@@ -41,6 +42,7 @@ struct LinkedUniform : public sh::Uniform
const
uint8_t
*
data
()
const
;
bool
isSampler
()
const
;
bool
isImage
()
const
;
bool
isAtomicCounter
()
const
;
bool
isInDefaultBlock
()
const
;
bool
isField
()
const
;
size_t
getElementSize
()
const
;
...
...
@@ -48,15 +50,37 @@ struct LinkedUniform : public sh::Uniform
uint8_t
*
getDataPtrToElement
(
size_t
elementIndex
);
const
uint8_t
*
getDataPtrToElement
(
size_t
elementIndex
)
const
;
int
blockIndex
;
// Identifies the containing buffer backed resource -- interface block or atomic counter buffer.
int
bufferIndex
;
sh
::
BlockMemberInfo
blockInfo
;
private
:
mutable
angle
::
MemoryBuffer
mLazyData
;
};
// Parent struct for atomic counter, uniform block, and shader storage block buffer, which all
// contain a group of shader variables, and have a GL buffer backed.
struct
ShaderVariableBuffer
{
ShaderVariableBuffer
();
virtual
~
ShaderVariableBuffer
();
ShaderVariableBuffer
(
const
ShaderVariableBuffer
&
other
)
=
default
;
ShaderVariableBuffer
&
operator
=
(
const
ShaderVariableBuffer
&
other
)
=
default
;
int
numActiveVariables
()
const
{
return
static_cast
<
int
>
(
memberIndexes
.
size
());
}
int
binding
;
unsigned
int
dataSize
;
std
::
vector
<
unsigned
int
>
memberIndexes
;
bool
vertexStaticUse
;
bool
fragmentStaticUse
;
bool
computeStaticUse
;
};
using
AtomicCounterBuffer
=
ShaderVariableBuffer
;
// Helper struct representing a single shader uniform block
struct
UniformBlock
struct
UniformBlock
:
public
ShaderVariableBuffer
{
UniformBlock
();
UniformBlock
(
const
std
::
string
&
nameIn
,
...
...
@@ -71,14 +95,6 @@ struct UniformBlock
std
::
string
name
;
bool
isArray
;
unsigned
int
arrayElement
;
int
binding
;
unsigned
int
dataSize
;
bool
vertexStaticUse
;
bool
fragmentStaticUse
;
bool
computeStaticUse
;
std
::
vector
<
unsigned
int
>
memberUniformIndexes
;
};
}
...
...
src/libANGLE/UniformLinker.cpp
View file @
9dd5dbd8
This diff is collapsed.
Click to expand it.
src/libANGLE/UniformLinker.h
View file @
9dd5dbd8
...
...
@@ -32,7 +32,9 @@ class UniformLinker
private
:
struct
ShaderUniformCount
{
ShaderUniformCount
()
:
vectorCount
(
0
),
samplerCount
(
0
),
imageCount
(
0
)
{}
ShaderUniformCount
()
:
vectorCount
(
0
),
samplerCount
(
0
),
imageCount
(
0
),
atomicCounterCount
(
0
)
{
}
ShaderUniformCount
(
const
ShaderUniformCount
&
other
)
=
default
;
ShaderUniformCount
&
operator
=
(
const
ShaderUniformCount
&
other
)
=
default
;
...
...
@@ -41,12 +43,14 @@ class UniformLinker
vectorCount
+=
other
.
vectorCount
;
samplerCount
+=
other
.
samplerCount
;
imageCount
+=
other
.
imageCount
;
atomicCounterCount
+=
other
.
atomicCounterCount
;
return
*
this
;
}
unsigned
int
vectorCount
;
unsigned
int
samplerCount
;
unsigned
int
imageCount
;
unsigned
int
atomicCounterCount
;
};
bool
validateVertexAndFragmentUniforms
(
const
Context
*
context
,
InfoLog
&
infoLog
)
const
;
...
...
@@ -61,18 +65,23 @@ class UniformLinker
GLuint
maxUniformComponents
,
GLuint
maxTextureImageUnits
,
GLuint
maxImageUnits
,
GLuint
maxAtomicCounters
,
const
std
::
string
&
componentsErrorMessage
,
const
std
::
string
&
samplerErrorMessage
,
const
std
::
string
&
imageErrorMessage
,
const
std
::
string
&
atomicCounterErrorMessage
,
std
::
vector
<
LinkedUniform
>
&
samplerUniforms
,
std
::
vector
<
LinkedUniform
>
&
imageUniforms
,
std
::
vector
<
LinkedUniform
>
&
atomicCounterUniforms
,
InfoLog
&
infoLog
);
bool
flattenUniformsAndCheckCaps
(
const
Context
*
context
,
InfoLog
&
infoLog
);
bool
checkMaxCombinedAtomicCounters
(
const
Caps
&
caps
,
InfoLog
&
infoLog
);
ShaderUniformCount
flattenUniform
(
const
sh
::
Uniform
&
uniform
,
std
::
vector
<
LinkedUniform
>
*
samplerUniforms
,
std
::
vector
<
LinkedUniform
>
*
imageUniforms
);
std
::
vector
<
LinkedUniform
>
*
imageUniforms
,
std
::
vector
<
LinkedUniform
>
*
atomicCounterUniforms
);
// markStaticUse is given as a separate parameter because it is tracked here at struct
// granularity.
...
...
@@ -80,8 +89,10 @@ class UniformLinker
const
std
::
string
&
fullName
,
std
::
vector
<
LinkedUniform
>
*
samplerUniforms
,
std
::
vector
<
LinkedUniform
>
*
imageUniforms
,
std
::
vector
<
LinkedUniform
>
*
atomicCounterUniforms
,
bool
markStaticUse
,
int
binding
,
int
offset
,
int
*
location
);
bool
indexUniforms
(
InfoLog
&
infoLog
,
const
Program
::
Bindings
&
uniformLocationBindings
);
...
...
src/libANGLE/queryutils.cpp
View file @
9dd5dbd8
...
...
@@ -816,14 +816,14 @@ void QueryActiveUniformBlockiv(const Program *program,
*
params
=
ConvertToGLint
(
uniformBlock
.
nameWithArrayIndex
().
size
()
+
1
);
break
;
case
GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS
:
*
params
=
ConvertToGLint
(
uniformBlock
.
member
Uniform
Indexes
.
size
());
*
params
=
ConvertToGLint
(
uniformBlock
.
memberIndexes
.
size
());
break
;
case
GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES
:
for
(
size_t
blockMemberIndex
=
0
;
blockMemberIndex
<
uniformBlock
.
memberUniformIndexes
.
size
();
blockMemberIndex
++
)
for
(
size_t
blockMemberIndex
=
0
;
blockMemberIndex
<
uniformBlock
.
memberIndexes
.
size
();
blockMemberIndex
++
)
{
params
[
blockMemberIndex
]
=
ConvertToGLint
(
uniformBlock
.
member
Uniform
Indexes
[
blockMemberIndex
]);
ConvertToGLint
(
uniformBlock
.
memberIndexes
[
blockMemberIndex
]);
}
break
;
case
GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER
:
...
...
src/libANGLE/validationES.cpp
View file @
9dd5dbd8
...
...
@@ -518,7 +518,7 @@ bool ValidateGetActiveUniformBlockivBase(Context *context,
{
const
UniformBlock
&
uniformBlock
=
programObject
->
getUniformBlockByIndex
(
uniformBlockIndex
);
*
length
=
static_cast
<
GLsizei
>
(
uniformBlock
.
member
Uniform
Indexes
.
size
());
*
length
=
static_cast
<
GLsizei
>
(
uniformBlock
.
memberIndexes
.
size
());
}
else
{
...
...
src/tests/gl_tests/AtomicCounterBufferTest.cpp
View file @
9dd5dbd8
...
...
@@ -45,10 +45,79 @@ TEST_P(AtomicCounterBufferTest, AtomicCounterBufferBindings)
}
}
class
AtomicCounterBufferTest31
:
public
AtomicCounterBufferTest
{
};
// Linking should fail if counters in vertex shader exceed gl_MaxVertexAtomicCounters.
TEST_P
(
AtomicCounterBufferTest31
,
ExceedMaxVertexAtomicCounters
)
{
const
std
::
string
&
vertexShaderSource
=
"#version 310 es
\n
"
"layout(binding = 2) uniform atomic_uint foo[gl_MaxVertexAtomicCounters + 1];
\n
"
"void main()
\n
"
"{
\n
"
" atomicCounterIncrement(foo[0]);
\n
"
"}
\n
"
;
const
std
::
string
&
fragmentShaderSource
=
"#version 310 es
\n
"
"void main()
\n
"
"{
\n
"
"}
\n
"
;
GLuint
program
=
CompileProgram
(
vertexShaderSource
,
fragmentShaderSource
);
EXPECT_EQ
(
0u
,
program
);
}
// Counters matching across shader stages should fail if offsets aren't all specified.
// GLSL ES Spec 3.10.4, section 9.2.1.
TEST_P
(
AtomicCounterBufferTest31
,
OffsetNotAllSpecified
)
{
const
std
::
string
&
vertexShaderSource
=
"#version 310 es
\n
"
"layout(binding = 2, offset = 4) uniform atomic_uint foo;
\n
"
"void main()
\n
"
"{
\n
"
" atomicCounterIncrement(foo);
\n
"
"}
\n
"
;
const
std
::
string
&
fragmentShaderSource
=
"#version 310 es
\n
"
"layout(binding = 2) uniform atomic_uint foo;
\n
"
"void main()
\n
"
"{
\n
"
"}
\n
"
;
GLuint
program
=
CompileProgram
(
vertexShaderSource
,
fragmentShaderSource
);
EXPECT_EQ
(
0u
,
program
);
}
// Counters matching across shader stages should fail if offsets aren't all specified with same
// value.
TEST_P
(
AtomicCounterBufferTest31
,
OffsetNotAllSpecifiedWithSameValue
)
{
const
std
::
string
&
vertexShaderSource
=
"#version 310 es
\n
"
"layout(binding = 2, offset = 4) uniform atomic_uint foo;
\n
"
"void main()
\n
"
"{
\n
"
" atomicCounterIncrement(foo);
\n
"
"}
\n
"
;
const
std
::
string
&
fragmentShaderSource
=
"#version 310 es
\n
"
"layout(binding = 2, offset = 8) uniform atomic_uint foo;
\n
"
"void main()
\n
"
"{
\n
"
"}
\n
"
;
GLuint
program
=
CompileProgram
(
vertexShaderSource
,
fragmentShaderSource
);
EXPECT_EQ
(
0u
,
program
);
}
ANGLE_INSTANTIATE_TEST
(
AtomicCounterBufferTest
,
ES3_OPENGL
(),
ES3_OPENGLES
(),
ES31_OPENGL
(),
ES31_OPENGLES
());
ANGLE_INSTANTIATE_TEST
(
AtomicCounterBufferTest31
,
ES31_OPENGL
(),
ES31_OPENGLES
());
}
// namespace
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