0% found this document useful (0 votes)
109 views27 pages

Mali & Opengl Es 3.0: Dave Shreiner Jon Kirkham

This document summarizes a presentation on new features in OpenGL ES 3.0, including instanced rendering, uniform buffers, transform feedback, and occlusion queries. It discusses how these features can improve performance and optimization over earlier versions by reducing draw calls, efficiently storing uniform data, capturing vertex shader outputs, and skipping hidden pixels. Diagrams and code samples are provided to illustrate how to implement instanced rendering, initialize uniform buffers, and configure transform feedback in OpenGL ES 3.0.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
109 views27 pages

Mali & Opengl Es 3.0: Dave Shreiner Jon Kirkham

This document summarizes a presentation on new features in OpenGL ES 3.0, including instanced rendering, uniform buffers, transform feedback, and occlusion queries. It discusses how these features can improve performance and optimization over earlier versions by reducing draw calls, efficiently storing uniform data, capturing vertex shader outputs, and skipping hidden pixels. Diagrams and code samples are provided to illustrate how to implement instanced rendering, initialize uniform buffers, and configure transform feedback in OpenGL ES 3.0.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

Mali & OpenGL ES 3.

Dave Shreiner
Jon Kirkham
ARM

Game Developers’ Conference


27 March 2013

1
Agenda
 Some foundational work
 Instanced geometry rendering
 Transform feedback
 Occlusion Queries

2
What’s New in OpenGL ES 3.0
 Updated shading  Occlusion queries
language – GLSL ES 3.00  that work efficiently with
 Updated vertex shading tiled renderers
using transform feedback  Instanced rendering
mode  New texture formats and
 Lots of new object types features
 shader uniform buffers  texture swizzles
 vertex array objects  (sized) integer formats
 sampler objects  ETC2 texture
 sync objects compression
 pixel buffer objects  Primitive restart
(PBOs)  ... and a whole lot more
3
A Quick Review …
 OpenGL ES 3.0 is a Geometric Data

shader-based API
Vertex Shader

 The pipeline has two


shading stages: Rasterizer

Stage Operation
Fragment Shader
Transformation of 3D world
Vertex Shader data to 2D screen
coordinates.

Shading (coloring) of potential


Fragment Shader
pixels on the screen

4
Preparing Geometric Data for OpenGL ES
 All data sent to OpenGL ES must be (x, y, z)
passed through a buffer (x, y, z)

Host Memory
(x, y, z)
Usage (x, y, z)
Buffer Type Description
Characteristics (x, y, z)
CPU-based memory like Evil and (x, y, z)
client-side arrays
you get from malloc() bandwidth unfriendly (x, y, z)

glBufferData()
GPU-based memory that (x, y, z)
vertex-buffer Fast and
the graphics driver
objects (VBOs) GPU friendly
allocates on your behalf

(x, y, z)

 OpenGL ES 3.0 supports both varieties, (x, y, z)

GPU Memory
(x, y, z)
but only use VBOs (x, y, z)
(x, y, z)
 We’ll see more uses for buffers in a bit (x, y, z)
(x, y, z)
(x, y, z)

5
Rendering in OpenGL ES 3.0
 In ES 2.0, you could render in two ways:
Rendering Command Description
glDrawArrays Pass vertex data to vertex shader sequentially
Pass vertex data to vertex shader indexed by
glDrawElements
element list

 Rendering the same model multiple times was inconvenient


 In ES 3.0, we can instance rendering
 one draw call replaces entire loop from above
Rendering Command Description
Repeatedly pass vertex data to vertex shader
glDrawArraysInstanced
sequentially
Repeatedly pass vertex data to vertex shader
glDrawElementsInstanced
indexed by element list

6
Converting to Instanced Rendering
 Less code, more performance (application code)

GLfloat xform[NumInstances][3] = {
{ x0, y0, z0 },
{ x1, y1, z1 },

};

for ( int i = 0; i < NumInstances; ++i ) {


glUniform3fv( xform, 1, xform[i] );
glDrawArrays( GL_TRIANGLES, 0, NumTris );
}

glUniform3fv( xform, NumInstances, xform );


glDrawArraysInstanced( GL_TRIANGLES, 0, NumTris, NumInstances );

7
Converting to Instanced Rendering
(shader code)
in vec4 position;

uniform vec4 xform;

void main()
{
gl_Position = position + xform;
}

in vec4 position;

uniform vec4 xform[];

void main()
{
gl_Position = position + xform[gl_InstanceID];
}

8
Instance Rendering Demo

9
Optimally Storing Data Using Uniform Buffers
 Uniforms are like constant global variables for a shader
 their value stays the same for all primitives in a draw call

 Loading large numbers of uniform variables is tedious


 there is a struct packaging mechanism, but it’s not widely used

 Uniform Buffer Objects let you load many uniforms easily


(shader code)

uniform ObjectData {
uniform vec4 position[NumObjects]; vec4 position[NumObjects];
uniform vec4 velocity[NumObjects]; vec4 velocity[NumObjects];
uniform float drag[NumObjects]; float drag[NumObjects];
};
void main() { … }
void main() { … }

10
Initializing Uniforms: A Comparison
struct { (application code)
GLfloat position[NumObjects][4];
GLfloat velocity[NumObjects][4];
GLfloat drag[NumObjects];
} data;
GLuint positionLoc = glGetUniformLocation( program, “position” );
GLuint velocityLoc = glGetUniformLocation( program, “velocity” );
GLuint dragLoc = glGetUniformLocation( program, “drag” );

if ( positionLoc < 0 || velocityLoc < 0 || dragLoc < 0 ) {


throw UniformLocationError();
}

glUniform4fv( positionLoc, NumObjects, data.position );


glUniform4fv( velocityLoc, NumObjects, data.velocity );
glUniform4fv( dragLoc, NumObjects, data.drag );

glGenBuffer( 1, &uniformBuffer );
glBufferData( GL_UNIFORM_BUFFER, sizeof(data), data, GL_STATIC_DRAW );
GLuint uniformIndex = glGetUniformBlockIndex( program, “ObjectData” );
glUniformBlockBinding( program, uniformIndex, n );
glBindBufferBase( GL_UNIFORM_BUFFER, 0, uniformBuffer );

11
Instanced Tessellation Demo

12
Transform Feedback
 Recall that every vertex is processed Geometric Data

by a vertex shader
Transform
Vertex Shader feedback
 For complex vertex shaders executing buffer

the shader could take a long time


 could result in this being a Rasterizer

performance bottleneck

 Transform feedback allows the results


Fragment Shader

of vertex shading to be captured in a


buffer, and rendered later
 very useful if the object doesn’t
change between frames

13
Data Flow in Shaders

uniform

Vertices in Vertex Shader out Magic in Fragment Shader out Fragments

During transform feedback, the


outputs of the vertex shader
are written to a buffer,
which can then become a new
data buffer for vertex shading

14
Configuring Transform Feedback
1. Compile and link transform feedback shader program
2. Determine the outputs of your transform feedback buffer
const GLchar* varyings = { “location”, “velocity” };
glTransformFeedbackVaryings( program, 2, varyings,
GL_SEPARATE_ATTRIBS );

 the order of varying names specify their output index


3. Associate transform feedback buffer with output streams
GLuint index = 0; // for “location”
GLintptr offset = 0; // “location” starts at the beginning of the buffer
GLsizeptr size = 4 * NumVertices * sizeof(GLfloat);
glBindBufferRange( GL_TRANSFORM_FEEDBACK_BUFFER, index, xfbID, offset, size);

index = 1; // for “veclocity”


offset = size; // data starts immediately after previous entries
glBindBufferRange( GL_TRANSFORM_FEEDBACK_BUFFER, index, xfbID, offset, size);

15
Generating Data with Transform Feedback

glEnable( GL_RASTERIZER_DISCARD
glEnable( GL_RASTERIZER_DISCARD ); );
glUseProgram( xfbProgram );
glBeginTransformFeedback( GL_POINTS );
glDrawArrays( GL_POINTS, 0, NumVertices ); Specify that we’re not
going to engage the
glEndTransformFeedback(); rasterizer to generate
any fragments
glDisable( GL_RASTERIZER_DISCARD );

16
Generating Data with Transform Feedback

glEnable( GL_RASTERIZER_DISCARD );
glUseProgram( xfbProgram
glUseProgram( xfbProgram );
);
glBeginTransformFeedback( GL_POINTS );
Switch to our
glDrawArrays( GL_POINTS, 0, NumVertices ); transform feedback
shader program
glEndTransformFeedback(); (this is the one with
our xfb varyings in it)
glDisable( GL_RASTERIZER_DISCARD );

17
Generating Data with Transform Feedback

glEnable( GL_RASTERIZER_DISCARD );
glUseProgram( xfbProgram );
glBeginTransformFeedback( GL_POINTS );
glBeginTranformFeedback( GL_POINTS ); Switch into
transform feedback
glDrawArrays( GL_POINTS, 0, NumVertices ); mode, requesting that
points are generated
glEndTransformFeedback();
glDisable( GL_RASTERIZER_DISCARD );

18
Generating Data with Transform Feedback

glEnable( GL_RASTERIZER_DISCARD );
glUseProgram( xfbProgram );
Send our input
glBeginTransformFeedback( GL_POINTS ); data through our
transform feedback
glDrawArrays( GL_POINTS,
glDrawArrays( GL_POINTS, 0,
0, NumVertices
NumVertices );
); shader, which will
output into our
glEndTransformFeedback(); vertex buffer

glDisable( GL_RASTERIZER_DISCARD );

19
Generating Data with Transform Feedback

glEnable( GL_RASTERIZER_DISCARD );
glUseProgram( xfbProgram );
glBeginTransformFeedback( GL_POINTS ); Return to normal
rendering
glDrawArrays( GL_POINTS, 0, NumVertices ); (i.e., vertex shader
output isn’t sent
glEndTransformFeedback(); to an xfb buffer)
glEndTransformFeedback();
glDisable( GL_RASTERIZER_DISCARD );

20
Generating Data with Transform Feedback

glEnable( GL_RASTERIZER_DISCARD );
glUseProgram( xfbProgram );
glBeginTransformFeedback( GL_POINTS );
glDrawArrays( GL_POINTS, 0, NumVertices ); Disable the
rasterizer sending
glEndTransformFeedback(); fragments to the
bit-bucket.
glDisable(
glDisable(GL_RASTERIZER_DISCARD
GL_RASTERIZER_DISCARD););

21
Transform Feedback Demo

22
Occlusion Queries
 OpenGL shades before determining visibility
 the fragment shader is executed before depth testing

 For complex fragment shading, this can be wasteful


 lots of work for naught

 Occlusion Queries help determine if the fragments from a


rendered object will pass the depth test

 Fundamental Idea: render a simply shaded, low-resolution


version of your object to determine if any of it is visible
 constant color, object-aligned bounding-boxes are a nice choice

23
Using Occlusion Queries
 Queries need to be allocated
GLuint queries[NumQueries];
glGenQueries( NumQueries, queries );

 Render in query mode


glBeginQuery( GL_ANY_SAMPLES_PASSED_CONSERVATIVE, queries[i] );
glDrawArrays( … );
glEndQuery( GL_ANY_SAMPLES_PASSED_CONSERVATIVE );

24
Using Occlusion Queries (cont’d.)
 Check if query computation is completed
GLboolean ready;
GLboolean visible;

do {
glGetQueryObjectiv( GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
GL_QUERY_RESULT_AVAILABLE, &ready );
} while ( !ready );

glGetQueryObjective( GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
GL_QUERY_RESULT, visible );

if ( visible ) {
// render
};

25
Occlusion Query Demo

26
END

27

You might also like