Skip to content

Commit

Permalink
Add glBindUniformLocationCHROMIUM
Browse files Browse the repository at this point in the history
TEST=unit tests
BUG=132844

Review URL: https://chromiumcodereview.appspot.com/10635011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@144070 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
gman@chromium.org committed Jun 26, 2012
1 parent 2c3eaaf commit 2be6abf
Show file tree
Hide file tree
Showing 33 changed files with 1,045 additions and 796 deletions.
131 changes: 131 additions & 0 deletions gpu/GLES2/extensions/CHROMIUM/CHROMIUM_bind_uniform_location.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
Name

CHROMIUM_bind_uniform_location

Name Strings

GL_CHROMIUM_bind_uniform_location

Version

Last Modifed Date: June 20, 2012

Dependencies

OpenGL ES 2.0 is required.

Overview

This extension is simlar to glBindAttribLocation but instead
lets you choose a location for a uniform. This allows you
to not have to query the locations of uniforms.

This allows the client program to know the locations of uniforms
without having to wait for shaders to compile or GLSL programs to
link to query the locations and therefore have no blocking calls
when initializing programs.

Issues

If a uniform is an array you can only call glBindUniformLocation
for the location of the first element. Other elements' locations
must be queried if you need them. Often this is not an issue
because you can set all the elements with a single gl call from
the first location.

Good Example:

--shader--
uniform float u_someArray[4];

--C--
GLint location = 123;
glBindUniformLocation(program, location, "u_someArray");
glLinkProgram(program);
glUseProgram(program);

// set all 4 floats in u_someArray
float values[] = { 0.1f, 0.2f, 0.3f, 0.4f, };
glUniform1fv(location, 4, values);

Bad example 1:

GLint location = 123;
glBindUniformLocation(program, location, "u_someArray");
glLinkProgram(program);
glUseProgram(program);

// set floats in u_someArray one at a time
glUniform1f(location, 0.1f);
glUniform1f(location + 1, 0.2f); // ERROR! math not allowed on locations

Bad example 2:

GLint location0 = 123;
GLint location1 = 124;
glBindUniformLocation(program, location0, "u_someArray[0]");
glBindUniformLocation(program, location1, "u_someArray[1]"); // ERROR!
// not allowed to assign locations to array elements

If you need to set individual elements of a uniform array you must query the
location of the each element you wish to set.

New Tokens

None

New Procedures and Functions

void BindUniformLocationCHROMIUM (GLuint program, GLint location,
const GLhchar* name);

specifes that the uniform variable named <name> in program <program>
should be bound to uniform location <location> when the program is next
linked. If <name> was bound previously, its assigned binding is replaced
with <location>. <name> must be a null terminated string. The error
INVALID_VALUE is generated if <location> is equal or greater than

(MAX_VERTEX_UNIFORM_VECTORS + MAX_FRAGMENT_UNIFORM_VECTORS) * 4

or less than 0. BindUniformLocation has no effect until the program is
linked. In particular, it doesn't modify the bindings of active uniforms
variables in a program that has already been linked.

The error INVALID_OPERATION is generated if name starts with the reserved
"gl_" prefix. The error INVALID_VALUE is generated if name ends with
an array element expression other than "[0]".

When a program is linked, any active uniforms without a binding specified
through BindUniformLocation will be automatically be bound to locations by
the GL. Such bindings can be queried using the command
GetUniformLocation.

BindUniformLocation may be issued before any shader objects are attached
to a program object. Hence it is allowed to bind any name (except a name
starting with "gl_") to an index, including a name that is never used as a
uniform in any shader object. Assigned bindings for uniform variables
that do not exist or are not active are ignored.

It is possible for an application to bind more than one uniform name to
the same location. This is referred to as aliasing. This will only work
if only one of the aliased uniforms is active in the executable program,
or if no path through the shader consumes more than one uniform of a set
of uniforms aliased to the same location. A link error can occur if the
linker determines that every path through the shader consumes multiple
aliased uniforms, but implementations are not required to generate an
error in this case. The compiler and linker are allowed to assume that no
aliasing is done, and may employ optimizations that work only in the
absence of aliasing.

Errors

None.

New State

None.

Revision History

7/20/2012 Documented the extension

This file was deleted.

19 changes: 8 additions & 11 deletions gpu/command_buffer/build_gles2_cmd_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1701,11 +1701,11 @@
'gl_test_func': 'glGetQueryObjectuiv',
'pepper_interface': 'Query',
},
'GetUniformLocationsCHROMIUM': {
'gen_cmd': False,
'extension': True,
'chromium': True,
'client_test': False,
'BindUniformLocationCHROMIUM': {
'type': 'GLchar',
'bucket': True,
'needs_size': True,
'gl_test_func': 'DoBindUniformLocationCHROMIUM',
},
}

Expand Down Expand Up @@ -3837,9 +3837,7 @@ def WriteServiceUnitTest(self, func, file):
# the location of the second element of the 2nd uniform.
# defined in GLES2DecoderBase::SetupShaderForUniform
gl_arg_strings.append("3")
arg_strings.append(
"GLES2Util::SwizzleLocation("
"GLES2Util::MakeFakeLocation(1, 1))")
arg_strings.append("ProgramManager::MakeFakeLocation(1, 1)")
elif count == 1:
# the number of elements that gl will be called with.
gl_arg_strings.append("3")
Expand Down Expand Up @@ -4695,14 +4693,13 @@ def __init__(self, name):

def WriteGetCode(self, file):
"""Writes the code to get an argument from a command structure."""
code = """ %s %s = GLES2Util::UnswizzleLocation(
static_cast<%s>(c.%s));
code = """ %s %s = static_cast<%s>(c.%s);
"""
file.Write(code % (self.type, self.name, self.type, self.name))

def GetValidArg(self, func, offset, index):
"""Gets a valid value for this argument."""
return "GLES2Util::SwizzleLocation(%d)" % (offset + 1)
return "%d" % (offset + 1)


class DataSizeArgument(Argument):
Expand Down
8 changes: 3 additions & 5 deletions gpu/command_buffer/client/gles2_c_lib_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -651,11 +651,9 @@ void GLES2ProduceTextureCHROMIUM(GLenum target, const GLbyte* mailbox) {
void GLES2ConsumeTextureCHROMIUM(GLenum target, const GLbyte* mailbox) {
gles2::GetGLContext()->ConsumeTextureCHROMIUM(target, mailbox);
}
void GLES2GetUniformLocationsCHROMIUM(
GLuint program, const GLUniformDefinitionCHROMIUM* uniforms, GLsizei count,
GLsizei max_locations, GLint* locations) {
gles2::GetGLContext()->GetUniformLocationsCHROMIUM(
program, uniforms, count, max_locations, locations);
void GLES2BindUniformLocationCHROMIUM(
GLuint program, GLint location, const char* name) {
gles2::GetGLContext()->BindUniformLocationCHROMIUM(program, location, name);
}

#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_C_LIB_AUTOGEN_H_
Expand Down
30 changes: 30 additions & 0 deletions gpu/command_buffer/client/gles2_cmd_helper_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -1798,5 +1798,35 @@
}
}

void BindUniformLocationCHROMIUM(
GLuint program, GLint location, uint32 name_shm_id,
uint32 name_shm_offset, uint32 data_size) {
gles2::BindUniformLocationCHROMIUM* c =
GetCmdSpace<gles2::BindUniformLocationCHROMIUM>();
if (c) {
c->Init(program, location, name_shm_id, name_shm_offset, data_size);
}
}

void BindUniformLocationCHROMIUMImmediate(
GLuint program, GLint location, const char* name) {
const uint32 data_size = strlen(name);
gles2::BindUniformLocationCHROMIUMImmediate* c =
GetImmediateCmdSpace<gles2::BindUniformLocationCHROMIUMImmediate>(
data_size);
if (c) {
c->Init(program, location, name, data_size);
}
}

void BindUniformLocationCHROMIUMBucket(
GLuint program, GLint location, uint32 name_bucket_id) {
gles2::BindUniformLocationCHROMIUMBucket* c =
GetCmdSpace<gles2::BindUniformLocationCHROMIUMBucket>();
if (c) {
c->Init(program, location, name_bucket_id);
}
}

#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_

Loading

0 comments on commit 2be6abf

Please sign in to comment.