<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>RasterGrid Blog &#187; texture buffer</title>
	<atom:link href="http://rastergrid.com/blog/tag/texture-buffer/feed/" rel="self" type="application/rss+xml" />
	<link>http://rastergrid.com/blog</link>
	<description>A technical blog from Daniel Rákos (aka aqnuep)</description>
	<lastBuildDate>Fri, 04 Nov 2011 18:10:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>An introduction to OpenGL 4.2</title>
		<link>http://rastergrid.com/blog/2011/08/an-introduction-to-opengl-4-2/</link>
		<comments>http://rastergrid.com/blog/2011/08/an-introduction-to-opengl-4-2/#comments</comments>
		<pubDate>Sun, 28 Aug 2011 14:25:25 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[atomic counter]]></category>
		<category><![CDATA[fragment shader]]></category>
		<category><![CDATA[geometry instancing]]></category>
		<category><![CDATA[GLSL]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[image load store]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[texture buffer]]></category>
		<category><![CDATA[transform feedback]]></category>
		<category><![CDATA[uniform buffer]]></category>
		<category><![CDATA[vertex shader]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=611</guid>
		<description><![CDATA[After the release of the OpenGL 4.1 specification the Khronos Group slowed down the pace a little bit but they didn&#8217;t left OpenGL developers without a new specification version for too long as a few weeks ago they&#8217;ve released OpenGL 4.2. The new version of the specification brings several API improvements as well as exposes]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frastergrid.com%252Fblog%252F2011%252F08%252Fan-introduction-to-opengl-4-2%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FpAMBuE%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22An%20introduction%20to%20OpenGL%204.2%22%20%7D);"></div>
<p>After the release of the OpenGL 4.1 specification the Khronos Group slowed down the pace a little bit but they didn&#8217;t left OpenGL developers without a new specification version for too long as a few weeks ago they&#8217;ve released OpenGL 4.2. The new version of the specification brings several API improvements as well as exposes some important pieces of hardware functionality that makes OpenGL 4.x class hardware a great step forward in GPU history. This article aims to present the newly introduced features in the latest version of the OpenGL specification and, as a few months ago I wrote an article about <a title="Suggestion for OpenGL 4.2 and beyond" href="http://rastergrid.com/blog/2010/11/suggestions-for-opengl-4-2-and-beyond/">Suggestions for OpenGL 4.2 and beyond</a>, I will write a few words about how does the new specification reflect my forecast.</p>
<p><span id="more-611"></span></p>
<h2>New features in OpenGL 4.2</h2>
<p>OpenGL 4.2 finally filled the holes in the capability matrix of Shader Model 5.0 hardware with some long waited extensions from which some of the functionalities were actually already accessible through cross-vendor and vendor specific extensions. Also, the new version of the specification brings some important API improvement extensions and GLSL constructs that continue the transition to a more easy to use state and shader management.</p>
<h3><a title="GL_ARB_texture_compression_bptc" href="http://www.opengl.org/registry/specs/ARB/texture_compression_bptc.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_compression_bptc.txt?referer=');">ARB_texture_compression_bptc</a></h3>
<p>This extension adds the new block compression texture formats called BC7 and BC6H in Direct3D terminology. The extension is actually available for quite some time, since the release of OpenGL 4.0 but now it became core. The formats provide high quality block compression for fixed point RGBA and sRGB textures as well as two floating point texture compression formats for signed and unsigned data.</p>
<p>Traditional block compression methods (as S3TC or RGTC) use the gradients in a block of pixels which works fine for smooth images but does provide poor results in case of sharp edges. BPTC solves the issue by dividing blocks into multiple partitions which are compressed using independent gradients thus providing better overall quality.</p>
<p>When comparing compression efficiency, BPTC has a compression ratio of 3:1 compared to 6:1, 4:1 and 2:1 that are the compression ratios of the S3TC DXT1, S3TC DXT5 and RGTC formats respectively.</p>
<h3><a title="GL_ARB_compressed_texture_pixel_storage" href="http://www.opengl.org/registry/specs/ARB/compressed_texture_pixel_storage.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/compressed_texture_pixel_storage.txt?referer=');">ARB_compressed_texture_pixel_storage</a></h3>
<p>This is an interesting extension that solves a problem that I didn&#8217;t even know is such a big issue. The extension is designed primarily to support compressed image formats with fixed-size blocks as that of BPTC as an example. The application can use this extension to configure pixel store parameters so that subtexture operations can provide consistent results in all cases.</p>
<h3><a title="GL_ARB_texture_storage" href="http://www.opengl.org/registry/specs/ARB/texture_storage.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_storage.txt?referer=');">ARB_texture_storage</a></h3>
<p>This is again an interesting extension that provides API improvement over how texture storage is allocated in classic OpenGL. As we all know, OpenGL was always too ad hoc on resource management, from the point of view of when actual resources are allocated for a particular API primitive. This is especially a problem in case of textures where we potentially talk about large amount of data. In classic OpenGL the driver could not know from the beginning for example whether the application will need mipmaps for the texture or how many levels are required. This could easily result in bad allocation patterns and/or large reallocations. This extension introduces the concept of immutable texture images where all the levels are allocated up-front for a texture object.</p>
<h3><a title="GL_ARB_transform_feedback_instanced" href="http://www.opengl.org/registry/specs/ARB/transform_feedback_instanced.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/transform_feedback_instanced.txt?referer=');">ARB_transform_feedback_instanced</a></h3>
<p>This extension extends the so called &#8220;AutoDraw&#8221; feature by providing instanced &#8220;AutoDraw&#8221;. This means that geometry captured using transform feedback can be rendered multiple time using geometry instancing. This is actually a feature that even D3D11 does not provide and being such, I didn&#8217;t even think that hardware supports it, even though I think the list usage patterns of the extensions is most probably pretty narrow.</p>
<h3><a title="GL_ARB_base_instance" href="http://www.opengl.org/registry/specs/ARB/base_instance.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/base_instance.txt?referer=');">ARB_base_instance</a></h3>
<p>This extension is actually the feature I called <strong>ARB_instanced_arrays2</strong> in my <a title="Suggestions for OpenGL 4.2 and beyond." href="http://rastergrid.com/blog/2010/11/suggestions-for-opengl-4-2-and-beyond/" target="_blank">suggestion list</a>. The extension provides three new draw commands, one is kind of illy named as <strong>DrawElementsInstancedBaseVertexBaseInstance</strong>, even though this command can be called the &#8220;basic&#8221; indexed draw commands that specifies all parameters. Also, the parameter list of the indirect indexed draw command is extended with the base instance parameter. Fortunately, however, the ARB chosen to add new commands rather than a <strong>SetBaseInstance</strong>-style state specifier command to introduce the new concept. Funnily this feature was missing for a long time as, as far as I know, it is supported by all GPUs capable of doing instanced drawing, and is available in D3D as well.</p>
<h3><a title="GL_ARB_shader_image_load_store" href="http://www.opengl.org/registry/specs/ARB/shader_image_load_store.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/shader_image_load_store.txt?referer=');">ARB_shader_image_load_store</a></h3>
<p>This is where things get start really interesting. This new extension is the ARBified version of the extension <a title="GL_EXT_shader_image_load_store" href="http://www.opengl.org/registry/specs/EXT/shader_image_load_store.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/EXT/shader_image_load_store.txt?referer=');">EXT_shader_image_load_store</a> which fortunately didn&#8217;t make it into core in its current form.</p>
<p>The extension provides GLSL built-in functions allowing shaders to load from, store to, and perform atomic read-modify-write operations to a single level of a texture called an image from any shader stage. Also, the extension indirectly enables the same set of operations for buffer objects by using buffer textures. This enables developers to implement more sophisticated algorithms using shaders that require more complex data structures than just plain arrays.</p>
<p>This, together with atomic counters that we will talk about later, enables the possibility to implement append/consume buffers and rendering techniques like AMD&#8217;s Order-Independent Transparency (OIT) algorithm as <a title="OIT and Indirect Illumination  Using DX11 Linked Lists" href="http://www.slideshare.net/hgruen/oit-and-indirect-illumination-using-dx11-linked-lists" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.slideshare.net/hgruen/oit-and-indirect-illumination-using-dx11-linked-lists?referer=');">presented at GDC10</a>.</p>
<p>As the introduction of the new write operations to fragment shaders besides the traditional framebuffer writes makes the execution of the shader have side effects and thus sensitive to whether early-Z is used or not by the hardware, so the extension also provides a mechanism to force or disable early-Z in the fragment shader.</p>
<p>A similar issue is in case of vertex shaders as the post-transform cache may be no longer valid in case of certain usage patterns of load/store images so, based on how smart the shader compiler is, the post-transform cache could be easily disabled in case a vertex shader uses load/store images resulting in downgraded performance, so care must be taken when using read/write images in vertex shaders as OpenGL does not have any mechanism to help these issues (but I actually have a proposal that I&#8217;ll talk about in a future article).</p>
<p>The API of this extension is greatly improved compared to the EXT version, especially when dealing with various texture image formats. The extension also provides a future-proof DSA-style API. Further, the ARB version of the extension supports loads from any texture format and corrected some specification bugs of the EXT version.</p>
<p>From hardware implementation point of view, it must be noted that in case a shader contains atomic operations applied to a particular read/write image the driver uses a different hardware path, as required by atomic read-modify-writes so that care must be taken to use atomic operations only when necessary. Also note that this decision is made statically at compile time by the driver so even a single atomic operation in an unlikely taken branch will result it degraded performance. This is another reason why to use atomic counters to implement append/consume buffers instead of using read/write image atomics.</p>
<h3><a title="GL_ARB_shader_atomic_counters" href="http://www.opengl.org/registry/specs/ARB/shader_atomic_counters.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/shader_atomic_counters.txt?referer=');">ARB_shader_atomic_counters</a></h3>
<p>This the other long waited feature that I also suggested and was still missing from OpenGL but was available in D3D11. The specification was actually ongoing for a long time now (about a year) and it even appeared for a while in AMD&#8217;s OpenGL drivers sometimes as EXT, sometimes as ARB extension. The extension provides API to access a number of hardware atomic counters that provide efficient counter operations on a GPU global scale. Atomic counters come handy in many cases like append/consume buffers or indirect draw buffer construction.</p>
<p>The extension provides access to these atomic counters from GLSL and also makes it possible to back them up with buffer objects so after OpenGL draw calls the value of the counters is preserved in these buffers for later use.</p>
<p>The OpenGL implementation is superior compared to D3D&#8217;s as it provides access to atomic counters from all shader stages, with caveats of course as, it was mentioned in the previous section, the side effects made possible with read/write images and atomic counters require special care in case of fragment and vertex shaders as they may result in invalid rendering and/or lower performance.</p>
<p>On hardware vendor implementations, it must be noted that atomic counters are much, much more faster than read/write image atomics, at least on AMD hardware which has dedicated hardware for atomic counters. On NVIDIA hardware, though, it seems that there is no different hardware path for atomic counters as their performance is roughly the same as in case of read/write image atomics.</p>
<p>The dedicated hardware implementation of atomic counters, however, comes with a trade-off as the number of atomic counters is severely limited on AMD hardware, but one can still use read/write image atomics if ran out of atomic counters.</p>
<h3><a title="GL_ARB_conservative_depth" href="http://www.opengl.org/registry/specs/ARB/conservative_depth.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/conservative_depth.txt?referer=');">ARB_conservative_depth</a></h3>
<p>This is another extension I&#8217;ve suggested and that fills another functionality hole compared to D3D11. The extension is actually an ARBified version of <a title="GL_AMD_conservative_depth" href="http://www.opengl.org/registry/specs/AMD/conservative_depth.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/AMD/conservative_depth.txt?referer=');">AMD_conservative_depth</a> that extends the application developer&#8217;s control over eary depth and stencil tests. <a title="GL_ARB_shader_image_load_store" href="http://www.opengl.org/registry/specs/ARB/shader_image_load_store.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/shader_image_load_store.txt?referer=');">ARB_shader_image_load_store</a>  already provides a way to force or disable eary-Z and this extension provides further modes that provide a hint to the driver about how depth is modified in a fragment shader that outputs depth. This passes enough information to the GL implementation to activate some early depth test optimizations safely while still preserving the ability to account the final depth value in the depth test.</p>
<p>The extension exposes the new capability in the form of fragment shader input layout qualifiers called &#8220;depth_any&#8221;, &#8220;depth_greater&#8221;, &#8220;depth_less&#8221; and &#8220;depth_unchanged&#8221;. The interesting ones are the one that assume a greater or less depth value as output and provide the ability to early reject groups of fragments using Hi-Z and early-Z even when depth is modified. This technique can greatly improve the rendering performance of volumetric particles, decals and billboards.</p>
<p>As far as I can tell, though, the extension provides performance benefits only the AMD hardware currently as NVIDIA hardware does not have such functionality thus using the extension would still force NVIDIA GPUs to disable early-Z in case the fragment shader outputs a depth value, but future hardware may change this.</p>
<h3><a title="GL_ARB_shading_language_420pack" href="http://www.opengl.org/registry/specs/ARB/shading_language_420pack.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/shading_language_420pack.txt?referer=');">ARB_shading_language_420pack</a></h3>
<p>This is a strangely named extension that provides a lot of improvements to GLSL. These are mostly API improvements only, but have a great value when looking at source code maintainability and resource management.</p>
<p>I think the most useful addition of the extension is the &#8220;binding&#8221; layout qualifier that I referred to as ARB_explicit_sampler_location and ARB_explicit_uniform_block_index in my <a title="Suggestions for OpenGL 4.2 and beyond." href="http://rastergrid.com/blog/2010/11/suggestions-for-opengl-4-2-and-beyond/" target="_blank">suggestion list</a>. This enables shader writers to explicitly bind a uniform block binding index to a uniform block as well as explicitly bind sampler, texture and image binding points to a sampler or image variable.</p>
<p>Besides that, the extension adds other minor improvements, like implicit conversion of return values of functions, UTF-8 character set support, C-style initializer list support and scalar swizzle operators.</p>
<h3><a title="GL_ARB_internalformat_query" href="http://www.opengl.org/registry/specs/ARB/internalformat_query.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/internalformat_query.txt?referer=');">ARB_internalformat_query</a></h3>
<p>This is another kind of strangely named extension that was meant to provide the possibility to query information about the internal format of textures, however, it actually failed it as it provides only the ability to query the maximum number of samples available for different texture formats.</p>
<p>The extension was ambitious as it planned to provide internal format information like the ability to query the actual internal format used, whether the format is renderable, accessible in a particular shader stage, whether it can be used as read/write image, and even to provide performance hint about using a particular texture internal format. Unfortunately all these were left for a future extension.</p>
<h3><a title="GL_ARB_map_buffer_alignment" href="http://www.opengl.org/registry/specs/ARB/map_buffer_alignment.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/map_buffer_alignment.txt?referer=');">ARB_map_buffer_alignment</a></h3>
<p>This is the last new extension introduced in OpenGL 4.2 that trivially adds the requirement to the pointer returned by buffer mapping commands that they provide a minimum of 64 byte alignment to support processing of the data directly with special CPU instructions like SSE or AVX. This can provide further performance increase when client is modifying buffer data.</p>
<h2>Conclusion</h2>
<p>OpenGL 4.2 again proven that OpenGL is not dead, but in fact plans to be again the ultimate choice of 3D API by pushing the exposed hardware capabilities over the line set by D3D11. When thinking about the list of expected extensions I presented in my earlier article, <a title="Suggestions for OpenGL 4.2 and beyond" href="http://rastergrid.com/blog/2010/11/suggestions-for-opengl-4-2-and-beyond/" target="_blank">Suggestions for OpenGL 4.2 and beyond</a> we can see that OpenGL 4.2 fulfilled all my expectations and even my wish list was partly fulfilled, but here&#8217;s the list for a better overview:</p>
<p><strong>My expectations for OpenGL 4.2:</strong></p>
<pre style="background-color: #ccffcc;"><strong>GL_EXT_shader_image_load_store</strong>
<span>- added in the form of GL_ARB_shader_image_load_store</span></pre>
<pre style="background-color: #ccffcc;"><strong>GL_ARB_shader_atomic_counters</strong>
<span>- added as is</span></pre>
<pre style="background-color: #ccffcc;"><strong>GL_ARB_instanced_arrays2</strong>
<span>- added in the form of GL_ARB_base_instance</span></pre>
<pre style="background-color: #ccffcc;"><strong>GL_ARB_explicit_sampler_location</strong>
<span>- added in the form of GL_ARB_shading_language_420pack</span></pre>
<pre style="background-color: #ccffcc;"><strong>GL_ARB_explicit_uniform_block_index</strong>
<span>- added in the form of GL_ARB_shading_language_420pack</span></pre>
<p><strong>My personal wish-list for OpenGL 4.2:</strong></p>
<pre style="background-color: #ffcccc;"><strong>GL_ARB_draw_indirect2</strong>
<span>- still missing, though partly available though <a title="GL_AMD_multi_draw_indirect" href="http://www.opengl.org/registry/specs/AMD/multi_draw_indirect.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/AMD/multi_draw_indirect.txt?referer=');">GL_AMD_multi_draw_indirect</a></span></pre>
<pre style="background-color: #ffcccc;"><strong>GL_ARB_direct_state_access</strong>
<span>- still missing, however, there is hope that it will be included in the next release where the ARB plans to rewrite the whole structure of the core specification</span></pre>
<pre style="background-color: #ccffcc;"><strong>GL_NV_texture_barrier</strong>
<span>- not in core but it is implicitly subsumed by GL_ARB_shader_image_load_store, they say</span></pre>
<pre style="background-color: #ccffcc;"><strong>GL_AMD_conservative_depth</strong>
<span>- added in the form of GL_ARB_conservative_depth, despite lack of NVIDIA support</span></pre>
<pre style="background-color: #ffcccc;"><strong>GL_ARB_texture_gather_lod</strong>
<span>- still missing, because of lack of supporting hardware</span></pre>
<pre style="background-color: #ffcccc;"><strong>GL_NV_copy_image</strong>
<span>- still missing, even though it could be a good API improvement</span></pre>
<pre style="background-color: #ffcccc;"><strong>GL_EXT_texture_filter_anisotropic</strong>
<span>- still missing, as I was informed, because of patent issues</span></pre>
<pre style="background-color: #ffcccc;"><strong>GL_ARB_shader_stencil_export</strong>
<span>- still missing, most probably because of lack of NVIDIA hardware support</span></pre>
<pre style="background-color: #ffcccc;"><strong>GL_AMD_depth_clamp_separate</strong>
<span>- still missing, most probably because of lack of NVIDIA hardware support</span></pre>
<pre style="background-color: #ffcccc;"><strong>GL_AMD_transform_feedback3_lines_triangles</strong>
<span>- still missing, most probably because of lack of NVIDIA hardware support</span></pre>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2011/08/an-introduction-to-opengl-4-2/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Suggestions for OpenGL 4.2 and beyond</title>
		<link>http://rastergrid.com/blog/2010/11/suggestions-for-opengl-4-2-and-beyond/</link>
		<comments>http://rastergrid.com/blog/2010/11/suggestions-for-opengl-4-2-and-beyond/#comments</comments>
		<pubDate>Sun, 14 Nov 2010 17:15:23 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[callback]]></category>
		<category><![CDATA[fragment shader]]></category>
		<category><![CDATA[geometry instancing]]></category>
		<category><![CDATA[GLSL]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[texture buffer]]></category>
		<category><![CDATA[transform feedback]]></category>
		<category><![CDATA[uniform buffer]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=504</guid>
		<description><![CDATA[The Khronos Group did a great job in the last few years to once again prove that OpenGL is still in game and that it can become the ultimate graphics API of choice, if it is not that already. However, we must note that it is not quite yet true that OpenGL 4.1 is a]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frastergrid.com%252Fblog%252F2010%252F11%252Fsuggestions-for-opengl-4-2-and-beyond%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FdymyU0%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Suggestions%20for%20OpenGL%204.2%20and%20beyond%22%20%7D);"></div>
<p>The Khronos Group did a great job in the last few years to once again prove that OpenGL is still in game and that it can become the ultimate graphics API of choice, if it is not that already. However, we must note that it is not quite yet true that OpenGL 4.1 is a superset of its competitor, DirectX 11. We still have some holes that still have to be filled and I think the ARB should not stop just there as there is much more potential in the current hardware architectures than that is currently exposed by any graphics API so establishing the future of OpenGL should start by going one step further than DX11. In this article I would like to present my vision of items of importance that should be included in the next revision of the specification and how I see the future of OpenGL.</p>
<p><span id="more-504"></span>Since the original OpenGL Longs Peak announcement, graphics developers were really excited to get their hands on the completely revised OpenGL 3 specification. Still, due to severe backward compatibility and portability issues the original plan seemed to be failed and developers expressed their great sense of disappointment about the ARB&#8217;s decision to choose rather a more evolutionary move away from the legacy API instead of the radical rewrite, the Khronos Group has proved that the decision was not necessarily bad for OpenGL and in fact we got now a pretty powerful API, even though the coexistence of the legacy and the new design greatly increased the complexity of the specification.</p>
<p>What we have now is an API that can really compete with DirectX 11 but I strongly believe that this is not the end of the story yet as we still have a lot of things to do in ahead of us. I mean this both from point of view of exposing more hardware capabilities as well as streamlining the API language itself to increase the productivity of the developers who use it. My plan is to target both of these issues in this article, also trying to focus on hardware functionalities that are not even exposed by other graphics APIs yet.</p>
<h2>Exposing more hardware capabilities</h2>
<p>In this chapter of the article I will talk about some familiar and some not so familiar hardware features and corresponding OpenGL extensions that should be included in the next revision of the specification in order to be able to confidently say that OpenGL is a strict superset of the competing graphics APIs. The extensions listed here are not in any particular priority order, they are just listed in a way that ease the discussion about their functionality.</p>
<h3><a title="GL_EXT_shader_image_load_store" href="http://www.opengl.org/registry/specs/EXT/shader_image_load_store.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/EXT/shader_image_load_store.txt?referer=');">GL_EXT_shader_image_load_store</a></h3>
<p>This extension provides GLSL built-in functions allowing shaders to load from, store to, and perform atomic read-modify-write operations to a single level of a texture from any shader stage. Also, the extension also indirectly enables the same operations for buffer objects by using texture buffers. This enables developers to implement more sophisticated algorithms using shaders that require more complex data structures than just plain arrays.</p>
<p>An example use case can be the implementation of Order-Independent Transparency (OIT) using fragment linked lists as presented by <a title="OIT And Indirect Illumination Using Dx11 Linked Lists" href="http://www.slideshare.net/hgruen/oit-and-indirect-illumination-using-dx11-linked-lists" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.slideshare.net/hgruen/oit-and-indirect-illumination-using-dx11-linked-lists?referer=');">AMD at GDC10</a>. Of course, there are a lot of other techniques that could benefit from hardware accelerated random access images (called UAV textures/buffers in DX11 terminology) including algorithms related to global illumination, ray tracing, and my personal favorite: scene management.</p>
<p>As the introduction of new write operations to fragment shaders besides the traditional framebuffer writes makes the execution of the shaders sensitive to whether early-Z is used or not by the hardware, the extension also introduces a new fragment shader input layout qualifier called &#8220;early_fragment_tests&#8221; to force OpenGL to use early depth and stencil test. Otherwise the specification language is valid stating that the depth and stencil tests are performed after fragment shader execution.</p>
<p>Finally, the extension enables some form of control over the order of image loads, stores, and atomics relative to other pipeline operations accessing the same memory region both using the OpenGL API and from within shaders.</p>
<p>The API itself provides a DSA-style binding mechanism that enables binding to so called &#8220;image units&#8221; that are separate from that of texture image units. In the same style, the specification language and GLSL refers to the introduced read-write textures with the term &#8220;image&#8221;.</p>
<p>In my opinion this is one of the most important extensions that should be made core with OpenGL 4.2 and I&#8217;m pretty sure this will actually happen.</p>
<h3><a title="GL_NV_texture_barrier" href="http://www.opengl.org/registry/specs/NV/texture_barrier.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/NV/texture_barrier.txt?referer=');">GL_NV_texture_barrier</a></h3>
<p>This extension relaxes the restrictions of OpenGL on rendering to a currently bound texture and provides a mechanism to avoid read-after-write problems. More precisely, the extension allows rendering to a currently bound texture in the following cases:</p>
<ul>
<li>If the reads and writes are from/to disjoint sets of texels (after accounting for texture filtering rules) so it should work unless the drawn areas overlap, or</li>
<li>If there is only a single read and write of each texel, and the read is in the fragment shader invocation that writes the same texel (e.g. using texelFetch2D).</li>
</ul>
<p>Some of these situations were already supported implicitly like rendering to a texture level and fetching from another texture level. But the extension goes further and provides an API function to put an explicit barrier between draw calls to ensure proper rendering.</p>
<p>The extension can be used to accomplish a limited form of programmable blending and can eliminate the need of any image or buffer data copy in case we can live with the restrictions mentioned above.</p>
<p>One may ask why we need this extension if we have the <a title="GL_EXT_shader_image_load_store" href="http://www.opengl.org/registry/specs/EXT/shader_image_load_store.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/EXT/shader_image_load_store.txt?referer=');">GL_EXT_shader_image_load_store</a> extension as this one is just a subset of the functionality provided by that. The answer is simple: performance. While read-write textures can mimic the same functionality they usually use different hardware paths that are slower than regular read-only texture accesses. So it would be a definite benefit to having also this extension in core OpenGL.</p>
<h3>GL_ARB_shader_atomic_counters</h3>
<p>This extension does not have public specifications yet, however it can be found in the extension lists of the latest Catalyst driver releases sometimes with EXT, sometimes with ARB prefix. The extension itself provides API to access a number of hardware atomic counters that provide efficient counter operations on a GPU global scale.</p>
<p>Atomic counters come handy when one has to read or write individual elements of a buffer or texture. As an example, this extension is needed to be able to efficiently implement the OIT algorithm mentioned earlier as, when constructing the fragment linked list, we need to have unique offsets to the linked list buffer. This unique offset can be, of course, acquired by using atomic read-modify-write operations but those perform much slower than hardware atomic counters.</p>
<p>Besides the mentioned example, atomic counters are useful in many algorithms from many domains, one important use case is to perform feedback operations similar to that provided by transform feedback. Such feedback operations can be used to perform various scene management or culling mechanisms.</p>
<p>The extension provides access to these atomic counters from GLSL and also makes it possible to back them up with buffer objects so after OpenGL draw calls the value of the counters is conserved in these buffers for subsequent use.</p>
<h3><a title="GL_AMD_conservative_depth" href="http://www.opengl.org/registry/specs/AMD/conservative_depth.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/AMD/conservative_depth.txt?referer=');">GL_AMD_conservative_depth</a></h3>
<p>Early depth test is a common optimization for hardware accelerated graphics that can skip the evaluation of fragment shaders for fragments that end up being discarded because they don&#8217;t pass the depth test. The problem is that in case the fragment shader modifies the depth value of the fragment then the early depth test is disabled. One can force early depth test with the functionality introduced by the extension <a title="GL_EXT_shader_image_load_store" href="http://www.opengl.org/registry/specs/EXT/shader_image_load_store.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/EXT/shader_image_load_store.txt?referer=');">GL_EXT_shader_image_load_store</a> but that can lead to some rendering artifacts as the modified depth value output by the fragment shader is not taken into account.</p>
<p>This extension allows the application to pass enough information to the GL implementation to activate some early depth test optimizations safely while still preserving the ability to account the final depth value in the depth test. In order to solve this, the extension introduces four new fragment shader input layout qualifiers called &#8220;depth_unchanged, &#8220;depth_any&#8221;, &#8220;depth_greater&#8221; and &#8220;depth_less&#8221;. The most interesting ones are the latest two that provide the ability to do early-Z and hierarchical-Z tests from one direction to discard some groups of fragments and still allow the fragment shader to safely modify the depth value.</p>
<p>This technique comes very handy in case of rendering volumetric particles, decals or billboards. Without this extension one have to sacrifice the possibility to do early rejection of fragments in order to be able to create the volumetric primitives mentioned.</p>
<p>As far as I know this feature is also present in DirectX 11 so it should be a must for OpenGL 4.x also. As the extension is an AMD one, I don&#8217;t know whether NVIDIA GPUs do support anything like this in hardware but even if not, they can simply ignore the new layout qualifiers and do late depth test instead. Of course, it would result in lower performance but if only functionality is concerned it should be just okay.</p>
<h3>GL_ARB_instanced_arrays2</h3>
<p>OpenGL provides two means to perform geometry instancing via the extensions <a title="GL_ARB_draw_instanced" href="http://www.opengl.org/registry/specs/ARB/draw_instanced.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/draw_instanced.txt?referer=');">GL_ARB_draw_instanced</a> and <a title="GL_ARB_instanced_arrays" href="http://www.opengl.org/registry/specs/ARB/instanced_arrays.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/instanced_arrays.txt?referer=');">GL_ARB_instanced_arrays</a>. While this (yet non-existent) extension would extend both, it is more relevant in case of the extension mentioned later so I named it accordingly.</p>
<p>The extension should trivially add the possibility to specify a &#8220;first instance&#8221; parameter for the instanced draw commands. Whether this is accomplished by introducing new variants of the glDrawElement* and glDrawArrays* draw commands or having a separate command for specifying the new parameter is up to the ARB. The extension should also interact with <a title="GL_ARB_draw_indirect" href="http://www.opengl.org/registry/specs/ARB/draw_indirect.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/draw_indirect.txt?referer=');">GL_ARB_draw_indirect</a> which already mentions the lack of the parameter in GL and reserved already a field in the indirect draw command structure for specifying the &#8220;first instance&#8221; parameter.</p>
<p>This extension itself would be much more a bug fix rather than a completely new feature as this functionality should have been already exposed at the first time instancing was introduced to OpenGL.</p>
<h3>GL_ARB_draw_indirect2</h3>
<p>This is one of the extensions I would be the most happy to see in the next release of the OpenGL specification. It would be a functional addition to the <a title="GL_ARB_draw_indirect" href="http://www.opengl.org/registry/specs/ARB/draw_indirect.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/draw_indirect.txt?referer=');">GL_ARB_draw_indirect</a> extension that currently only allows the execution of a single instanced draw command that sources its parameter from a buffer object.</p>
<p>The new extension would add a new buffer binding point called e.g. GL_DRAW_INDIRECT_PRIMITIVE_COUNT that would specify the source of the &#8220;primcount&#8221; parameter to the following newly introduced draw commands:</p>
<pre>    void <strong>MultiDrawArraysIndirect</strong>( enum <em>mode</em>, sizei stride,
                                  const void *<em>indirect</em>,
                                  const void *<em>primcount</em> );
    void <strong>MultiDrawElementsIndirect</strong>( enum <em>mode</em>, enum <em>type</em>, sizei stride,
                                    const void *<em>indirect</em>,
                                    const void *<em>primcount</em> );</pre>
<p>This would not just allow for executing multiple indirect draw commands at once, without further CPU action, but also would source the &#8220;primcount&#8221; parameter from a buffer object thus if the draw commands are generated using transform feedback, read-write buffers or OpenCL (e.g. based on some GPU based scene management algorithm) then the application does not have to use asynchronous queries or other means that may introduce sync points in the rendering to be able to feed the &#8220;primcount&#8221; parameter.</p>
<p>Some people said that this is quite a futuristic feature to expect and most probably such functionality will be available only on newer generation of GPUs and maybe with OpenGL 5. I was not that pessimistic so I decided to raise my question to the relevant ARB members of NVIDIA and AMD. While I did not receive any answer from NVIDIA, I did received some good news from AMD as they said that this functionality can be implemented for Shader Model 5.0 level hardware.</p>
<p>What this extension would give developers is a way to efficiently implement GPU based scene management where the GPU bakes together all the rendering commands for the current frame using atomic counters and buffer writes, and the CPU just have to issue a few or maybe just a single MultiDraw*Indirect command to render the whole scene. But of course, the feature can increase draw command throughput also in case of CPU based scene management.</p>
<p>So my message to the Khronos Group is please, start working on such an extension as this would not just make developers happy, but you can also strengthen OpenGL&#8217;s position in the industry by putting something into the specification that even DirectX 11 cannot do.</p>
<h3><a title="GL_AMD_transform_feedback3_lines_triangles" href="http://www.opengl.org/registry/specs/AMD/transform_feedback3_lines_triangles.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/AMD/transform_feedback3_lines_triangles.txt?referer=');">GL_AMD_transform_feedback3_lines_triangles</a></h3>
<p>OpenGL 4.0 introduced the extension <a title="GL_ARB_transform_feedback3" href="http://www.opengl.org/registry/specs/ARB/transform_feedback3.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/transform_feedback3.txt?referer=');">GL_ARB_transform_feedback3</a> that further extended the transform feedback capabilities provided by earlier extensions to allow ouput to separate vertex streams. However there is one caveat: separate vertex streams are only supported for point primitives.</p>
<p>This new AMD extension does nothing more than just simply removes that restrictions for separate output streams allowing the same set of primitive types to be used with multiple transform feedback streams as with a single stream as long as the primitive types are the same for all output streams.</p>
<p>Limiting the possible output primitive types for transform feedback into multiple streams should not be a problem unless you want also to rasterize some triangles at the same time you output. Without relaxing this restriction can do this only by issuing two separate draw commands that incurs a performance hit.</p>
<p>I don&#8217;t know if the restriction is present in the ARB extension because NVIDIA does not support this in hardware but if this is not the case then I think this extension should be included in the next release of the specification. Otherwise, please NVIDIA include this feature in your next GPU generation.</p>
<h3><a title="GL_NV_copy_image" href="http://www.opengl.org/registry/specs/NV/copy_image.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/NV/copy_image.txt?referer=');">GL_NV_copy_image</a></h3>
<p>OpenGL 3.1 already introduced a method to provide GPU accelerated copy of buffer data. This NVIDIA extension provides a similar functionality that can be used to execute efficient image data transfer between image objects (i.e. textures and renderbuffers).</p>
<p>While there are already methods to perform image data copies between textures e.g. using the <a title="GL_EXT_framebuffer_blit" href="http://www.opengl.org/registry/specs/EXT/framebuffer_blit.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/EXT/framebuffer_blit.txt?referer=');">GL_EXT_framebuffer_blit</a> extension promoted to core with OpenGL 3.0 these require expensive framebuffer object operations and they also lack direct support for transferring 3D image data.</p>
<p>This extension simply introduces a single command that allows such image data copies for every type of textures (including cube maps, 3D textures and array textures) without the need to bind the image objects or otherwise configure the rendering.</p>
<h3><a title="GL_AMD_depth_clamp_separate" href="http://www.opengl.org/registry/specs/AMD/depth_clamp_separate.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/AMD/depth_clamp_separate.txt?referer=');">GL_AMD_depth_clamp_separate</a></h3>
<p>The extension <a title="GL_ARB_depth_clamp" href="http://www.opengl.org/registry/specs/ARB/depth_clamp.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/depth_clamp.txt?referer=');">GL_ARB_depth_clamp</a> promoted to core with OpenGL 3.2 introduced the ability to control the clamping of the depth value for both the near and far clip planes. This eliminates artifacts like seeing inside an object happening when the object&#8217;s geometry is clipped by the near clip plane.</p>
<p>This new extension provides a mean for the application to enable depth clamp separately for the near and the far clip plane. This increases the flexibility of depth clamping and can save some fill-rate in certain situations.</p>
<h3><a title="GL_EXT_texture_filter_anisotropic" href="http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt?referer=');">GL_EXT_texture_filter_anisotropic</a></h3>
<p>I don&#8217;t think that I have to talk too much about this extension as it should be familiar to all of you. It simply enables the possibility to use anisotropic filtering on a per-texture basis. I really wonder how this extension didn&#8217;t make its way into core as it is supported by hardware since more than a decade.</p>
<p>I know that the extension itself is supported by all relevant graphics driver vendors but really, why we can&#8217;t just simply include it in the core specification?</p>
<h3>GL_ARB_texture_gather_lod</h3>
<p>This is another yet non-existent extension that would extend <a title="GL_ARB_texture_gather" href="http://www.opengl.org/registry/specs/ARB/texture_gather.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_gather.txt?referer=');">GL_ARB_texture_gather</a> by adding GLSL built-in functions called textureGatherLod that would allow gathered fetches with explicit LOD. I&#8217;m not sure if these functions are missing from the specification because of lack of hardware support or just because the ARB thought they might not be of any use. Anyway, if the hardware supports it then OpenGL should expose it to developers as there are certain situations when one has to use explicit LOD and could benefit from the increased fetching performance enabled by gathered fetches.</p>
<h3><a title="GL_ARB_shader_stencil_export" href="http://www.opengl.org/registry/specs/ARB/shader_stencil_export.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/shader_stencil_export.txt?referer=');">GL_ARB_shader_stencil_export</a></h3>
<p>This extension was published at the time the OpenGL 4.1 specification came out and provides the ability for the fragment shader to output the stencil reference value that was otherwise configurable only using API calls. This enables a great level of flexibility to existing and future stencil buffer based algorithms making it possible also to directly write independent values to the stencil buffer on a per-fragment basis.</p>
<p>The predecessor of the extension is <a title="GL_AMD_shader_stencil_export" href="http://www.opengl.org/registry/specs/AMD/shader_stencil_export.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/AMD/shader_stencil_export.txt?referer=');">GL_AMD_shader_stencil_export</a> and as such it indicates that maybe it is only supported in hardware on AMD GPUs. However, if this is not the case and NVIDIA could support this also then I think it worths to promote this feature also to core OpenGL.</p>
<h2>Streamlining the API</h2>
<p>After discussing the long list of functional features that would be nice to be included into the next release of OpenGL let&#8217;s focus on the API improvement extensions and ideas that are necessary to improve the usability of the API itself. Actually this part could go way longer than I&#8217;ll discuss because as we get more and more features to OpenGL, developers struggle with the increased complexity of the API. I&#8217;ll try to focus on the most crucial issues.</p>
<h3><a title="GL_EXT_direct_state_access" href="http://www.opengl.org/registry/specs/EXT/direct_state_access.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/EXT/direct_state_access.txt?referer=');">GL_EXT_direct_state_access</a></h3>
<p>This is the extension what all OpenGL developers are waiting for a long time now. Direct state access eliminates the OpenGL API&#8217;s stupid &#8220;bind-to-modify&#8221; nature.</p>
<p>For a very long time the only vendor supporting the extension was NVIDIA. Fortunately, since Catalyst 10.7 AMD also exposes the extension to developers. Still, I have one problem: this extension is very poorly designed.</p>
<p>The main problem with the extension is that the functions were designed in a way that a naive implementation could be done by simply using &#8220;bind-to-modify&#8221; under the hood. That&#8217;s what resulted in crazy API functions like MultiTexParameter* and friends. Also, enabling DSA for all of the deprecated functionalities would result in an explosion of the API specification and as a consequence it would result in bloated specification language. Finally, I would also like to object somewhat the lack of creativity of the contributors regarding to the awkward naming conventions present in the current DSA extension.</p>
<p>In my opinion the Khronos Group has to address the issue by creating a new ARB version of the DSA extension that focuses strictly on core functionalities, throwing away DSA support for deprecated features (if somebody needs to use deprecated features they can still use the EXT version) and provide a naming convention that fits much better into the current API language.</p>
<p>Anyway, I completely agree with the other developers out there and scream for DSA. I think the Khronos Group has to eliminate the problem of the &#8220;bind-to-modify&#8221; semantics as soon as possible otherwise, even though the core specification exposes more and more hardware features, developers will not be attracted to use OpenGL.</p>
<h3>GL_ARB_explicit_sampler_location</h3>
<p>The ARB moved in the right direction when they introduced the <a title="GL_ARB_explicit_attrib_location" href="http://www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt?referer=');">GL_ARB_explicit_attrib_location</a> extension by eliminating the need to use dummy API calls to bind vertex attributes and output buffers to shader variables but they should not stop here. One of the most important addition could be adding a similar language syntax to GLSL that would allow us to bind sampler uniforms to texture image units. Obviously, the same goes for read-write images if <a title="GL_EXT_shader_image_load_store" href="http://www.opengl.org/registry/specs/EXT/shader_image_load_store.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/EXT/shader_image_load_store.txt?referer=');">GL_EXT_shader_image_load_store</a> is included.</p>
<h3>GL_ARB_explicit_uniform_block_index</h3>
<p>Similar to the previous request, uniform block indices should be as well explicitly specifiable in the shaders themselves. This extension would add exactly such functionality. The implementation is also straightforward: just a simple uniform block layout qualifier has to be added.</p>
<h3>Other API clarifications</h3>
<p>Besides the major issues the current specification language also has some bugs and unclear parts that should be addressed as well:</p>
<ul>
<li>Program pipeline objects are created by binding the object name which is not in align with the rest of the API language.</li>
<li>No language is about whether program pipeline objects are shared among contexts or not which suggests that they aren&#8217;t which is not in align with the fact that program and shader objects are shared.</li>
</ul>
<p>Most probably there are a lot more issues with the specification language but for now just these came into my mind. Maybe some of you can extend the list with tons of other specification mistakes.</p>
<h2>OpenGL 4.2 and beyond</h2>
<p>While my feature requests cover most of the needed functionality that should be included in the next revision of the OpenGL specification, there are a lot of other things that could be very useful for developers but are very unlikely to get their way into the specification any soon. I will talk about these features in this section of the article as these raise much more questions than just to be able to simply include it in OpenGL 4.2.</p>
<h3>Affinity contexts</h3>
<p>We have multi-GPU designs like SLI and CrossFire for a long time now. Fortunately, we have also vendor specific extensions to create affinity contexts that are associated with a single GPU of a multi-GPU configuration. We have <a title="WGL_AMD_gpu_association" href="http://www.opengl.org/registry/specs/AMD/wgl_gpu_association.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/AMD/wgl_gpu_association.txt?referer=');">WGL_AMD_gpu_association</a> and <a title="WGL_NV_gpu_affinity" href="http://www.opengl.org/registry/specs/NV/gpu_affinity.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/NV/gpu_affinity.txt?referer=');">WGL_NV_gpu_affinity</a> for Windows and <a title="GLX_AMD_gpu_association" href="http://www.opengl.org/registry/specs/AMD/glx_gpu_association.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/AMD/glx_gpu_association.txt?referer=');">GLX_AMD_gpu_association</a> on GLX based platforms. I have just two problems with this:</p>
<ul>
<li>First, these are vendor specific extensions.</li>
<li>Second, NVIDIA exposes its affinity context support only on Windows and just for their professional cards, leaving consumer hardware owners without affinity context support.</li>
</ul>
<p>I would be pleased to see in the future extensions like <span style="text-decoration: underline;">WGL_ARB_gpu_affinity_context</span> and <span style="text-decoration: underline;">GLX_ARB_gpu_affinity_context</span> that will be supported by both NVIDIA and AMD, and that are supported on both professional and consumer hardware.</p>
<h3>Command buffers</h3>
<p>I would like to see something similar in OpenGL that what we have in OpenCL. Having several separate command buffers for a single OpenGL context can have its performance benefits as some of the implicit sync points that are otherwise present in OpenGL draw commands could be eliminated. Another solution would be to use simply multiple GL contexts but it is much more complicated and context switches are quite heavy-weight operations. This would be something like how framebuffer objects replaced pbuffers.</p>
<p>Also this could go that far as we can encapsulate state manipulation data into command buffers in a similar way how display lists allowed this in many cases just in a more efficient and hardware centric manner.</p>
<h3>Immutable state objects</h3>
<p>Another thing strongly related to the previous idea would be immutable state objects. If state management data could not be efficiently stored in such a command buffer we could use instead immutable state objects that would be very similar in nature to display lists that are hiding the underlying representation of the commands.</p>
<p>Display lists are deprecated and I don&#8217;t think it was a wrong decision. It made the API language complex and you&#8217;ve never knew which command compiles into display lists and how. I remember the time I was making an OpenGL app on my GeForce2 and used DrawElements calls inside display lists that referenced buffer object data. Funnily it was working on NVIDIA hardware, even though the specification says otherwise, and I was wondering why I my app crashes on ATI cards.</p>
<p>Anyway, display lists are gone, but we need some complex state objects that could fill those holes that were left after them.</p>
<h3>More callbacks</h3>
<p>I was very happy to see the appearance of an extension that introduced the callback concept into OpenGL (<a title="GL_AMD_debug_output" href="http://www.opengl.org/registry/specs/AMD/debug_output.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/AMD/debug_output.txt?referer=');">GL_AMD_debug_output</a>). Since that, the functionality was promoted to an ARB extension meaning that the ARB has accepted the fact that we need callbacks.</p>
<p>What I would like to see in the future is more OpenGL callbacks. One of the most trivial things I can think of are asynchronous queries. It would so much easier if we would be able to receive a callback from OpenGL when the results of our asynchronous queries are available, rather than having to manually poll it for result in various phases of the rendering.</p>
<p>Actually, I could imagine callbacks for every rendering command issued that will be called by the driver as soon as the actual rendering is complete on the GPU side.</p>
<h3>Programmable blending</h3>
<p>This is one another thing that developers are screaming for. Fortunately now we have indirect methods to solve most of the issues of programmable blending via the extensions <a title="GL_EXT_shader_image_load_store" href="http://www.opengl.org/registry/specs/EXT/shader_image_load_store.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/EXT/shader_image_load_store.txt?referer=');">GL_EXT_shader_image_load_store</a> and <a title="GL_NV_texture_barrier" href="http://www.opengl.org/registry/specs/NV/texture_barrier.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/NV/texture_barrier.txt?referer=');">GL_NV_texture_barrier</a>, however a more general solution would be welcomed.</p>
<p>I don&#8217;t know whether this would be actually possible on current hardware but if not, then this is a message to hardware vendors to solve the issue in the near future.</p>
<h2>Summary</h2>
<p>We&#8217;ve seen that even though OpenGL is on track and the Khronos Group is keeping up the pace with its competitors, still there are lots of room for improvement regarding to the OpenGL specification from both functional point of view as well as from API design point of view.</p>
<p>I would like to end the article with a summary of what I expect to be part of the OpenGL 4.2 specification and my personal wish-list beyond those in some kind of priority order.</p>
<p><strong>My expectations for OpenGL 4.2:</strong></p>
<ul>
<li>GL_EXT_shader_image_load_store</li>
<li>GL_ARB_shader_atomic_counters</li>
<li>GL_ARB_instanced_arrays2</li>
<li>GL_ARB_explicit_sampler_location</li>
<li>GL_ARB_explicit_uniform_block_index</li>
</ul>
<p><strong>My personal wish-list for OpenGL 4.2:</strong></p>
<ul>
<li>GL_ARB_draw_indirect2</li>
<li>GL_ARB_direct_state_access</li>
<li>GL_NV_texture_barrier</li>
<li>GL_AMD_conservative_depth</li>
<li>GL_ARB_texture_gather_lod</li>
<li>GL_NV_copy_image</li>
<li>GL_EXT_texture_filter_anisotropic</li>
<li>GL_ARB_shader_stencil_export</li>
<li>GL_AMD_depth_clamp_separate</li>
<li>GL_AMD_transform_feedback3_lines_triangles</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/11/suggestions-for-opengl-4-2-and-beyond/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Texture and buffer access performance</title>
		<link>http://rastergrid.com/blog/2010/11/texture-and-buffer-access-performance/</link>
		<comments>http://rastergrid.com/blog/2010/11/texture-and-buffer-access-performance/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 20:44:57 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Multiprocessing]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[OpenCL]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[texture buffer]]></category>
		<category><![CDATA[uniform buffer]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=475</guid>
		<description><![CDATA[Currently there are several ways to feed data to the GPU no matter of what API we use and what type of application we develop. In case of OpenGL we have uniform buffers, texture buffers, texture images, etc. The same is true for OpenCL and other compute APIs that even provide more fine-grained memory management]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frastergrid.com%252Fblog%252F2010%252F11%252Ftexture-and-buffer-access-performance%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Texture%20and%20buffer%20access%20performance%22%20%7D);"></div>
<p>Currently there are several ways to feed data to the GPU no matter of what API we use and what type of application we develop. In case of OpenGL we have uniform buffers, texture buffers, texture images, etc. The same is true for OpenCL and other compute APIs that even provide more fine-grained memory management taking advantage of the local data store (LDS) available on today&#8217;s hardware. In this article I&#8217;ll present the memory access performance characteristics of AMD&#8217;s Evergreen-class GPUs focusing on what this all means from OpenGL point of view. While most of the data is about the HD5870, the general principles and relative performance characteristics are valid for other GPUs, including ones from other vendors.</p>
<p><span id="more-475"></span></p>
<h2>Introduction</h2>
<p>Traditional CPU based applications don&#8217;t have to worry too much about where they put their data as they have a simple set of possibilities: registers and global memory (accessed through a series of linear caches called L1, L2 and on newer architectures also L3). While this and its details can be already quite cumbersome to utilize efficiently, GPU based algorithms need even more investigation as their architecture is based on a more complex multi-level memory design.</p>
<p>Typical questions an OpenGL graphics developer could ask nowadays are:</p>
<ul>
<li>Where should I put my per-object data?</li>
<li>From where should I source animation data?</li>
<li>Should I use uniform buffers, texture buffers or vertex buffers for my per-instance data?</li>
<li>What does it mean from performance point of view if I use read-write buffers or textures?</li>
</ul>
<p>Of course, the list could continue and answering the individual questions is not easy and often requires performance measurements to prove our suspicions. Instead of trying to answer all these questions it is easier to take a look at the actual hardware performance characteristics and solve the individual issues based on that.</p>
<p>I&#8217;ve already touched the topic in the past with the article <a title="Uniform Buffers VS Texture Buffers" href="http://rastergrid.com/blog/2010/01/uniform-buffers-vs-texture-buffers/">Uniform Buffers VS Texture Buffers</a> where I&#8217;ve presented the key differences between the two data access method and a few examples when to use one or the other. In this article I&#8217;ll go further and try to provide more accurate data about how various memory access methods perform in practice.</p>
<p>Earlier there were little to no detailed information about the actual performance of API level memory access methods but fortunately the increasing popularity of OpenCL made vendors to provide more technical details about the architecture and performance of their products to enable software developers to fully leverage the power of today&#8217;s GPUs. While these documents focus on OpenCL or other compute APIs, most of the data applies indirectly to OpenGL as well.</p>
<h2>The Evergreen architecture</h2>
<p>In order to be able to provide some actual performance data, I&#8217;ve selected as reference AMD&#8217;s Evergreen architecture and the Radeon HD5870 as the target hardware. Note that most of the presented details roughly apply to all other modern GPUs, including NVIDIA&#8217;s Fermi architecture. Each time there is a clear difference between the two, I&#8217;ll try to point it out. However, I cannot be 100% sure what are these differences as <a title="ATI Stream SDK OpenCL Programming Guide" href="http://developer.amd.com/gpu/ATIStreamSDK/assets/ATI_Stream_SDK_OpenCL_Programming_Guide.pdf" target="_blank" onclick="pageTracker._trackPageview('/outgoing/developer.amd.com/gpu/ATIStreamSDK/assets/ATI_Stream_SDK_OpenCL_Programming_Guide.pdf?referer=');">ATI&#8217;s OpenCL programming guide</a> is somewhat more talkative about actual performance details than that of <a title="NVIDIA OpenCL Programming Guide" href="http://developer.download.nvidia.com/compute/cuda/3_1/toolkit/docs/NVIDIA_OpenCL_ProgrammingGuide.pdf" target="_blank" onclick="pageTracker._trackPageview('/outgoing/developer.download.nvidia.com/compute/cuda/3_1/toolkit/docs/NVIDIA_OpenCL_ProgrammingGuide.pdf?referer=');">NVIDIA&#8217;s OpenCL programming guide</a>.</p>
<div class="wp-caption aligncenter" style="width: 510px"><img class=" " title="OpenCL Platform Model" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/11/opencl_platform_model.png" alt="OpenCL Platform Model" width="500" height="273" /><p class="wp-caption-text">OpenCL Platform Model</p></div>
<p>From OpenCL platform model&#8217;s point of view the Radeon HD5870 is structured in the following way:</p>
<ul>
<li>Total of 20 compute units.</li>
<li>Each compute unit consists of 16 stream cores.</li>
<li>Each stream core consists of 5 processing elements (4 traditional, 1 transcendental).</li>
</ul>
<p>This sums up to a total of 1600 processing elements on the Radeon HD5870.</p>
<p>The basic OpenCL architecture applies in the same way to NVIDIA GPUs, however, there is are differences between AMD&#8217;s and NVIDIA&#8217;s GPU architecture. AMD uses a special super-scalar architecture since their HD2000 series that allows them to execute 5 separate instructions in each core.</p>
<div class="wp-caption aligncenter" style="width: 439px"><img class="   " title="ATI super-scalar architecture" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/11/ati_superscalar.gif" alt="ATI super-scalar architecture" width="429" height="237" /><p class="wp-caption-text">ATI super-scalar architecture consisting of one transcendental unit (left), four traditional units and a dedicated branch execution unit (right).</p></div>
<p>What this already reveals us from OpenGL point of view is that AMD&#8217;s architecture groups together 16 stream cores so fragment shaders are most probably running on 4&#215;4 tiles of fragments in sync. As an example, it is important to note this in case we use heavy dynamic branching in shaders as we should be aware of that in case the branch selection is not coherent for the specified fragment neighborhood, performance can drop due to the fact that hardware masks out those processing elements that did not select the appropriate branch.</p>
<p>Also, it is important to note that usually one out of four or five processing elements (depending on hardware generation and vendor) are capable of executing transcendental instructions such as logarithm, exponential or trigonometric functions.</p>
<h2>Memory capacity and performance</h2>
<p>AMD is very clear about the memory capacity and performance details in their OpenCL programming guide. The figure below showcases these hardware characteristics of the Radeon HD5870:</p>
<table style="width: 100%;" border="0">
<tbody>
<tr>
<td style="text-align: center;"><strong>OpenCL Memory Type</strong></td>
<td style="text-align: center;"><strong>Hardware Resource</strong></td>
<td style="text-align: center;"><strong>Size/CU</strong></td>
<td style="text-align: center;"><strong>Size/GPU</strong></td>
<td style="text-align: center;"><strong>Peak Read Bandwidth / Stream Core</strong></td>
</tr>
<tr>
<td>Private</td>
<td>GPRs</td>
<td style="text-align: center;">256KB</td>
<td style="text-align: center;">5MB</td>
<td style="text-align: center;">48 bytes/cycle</td>
</tr>
<tr>
<td>Local</td>
<td>LDS</td>
<td style="text-align: center;">32KB</td>
<td style="text-align: center;">640KB</td>
<td style="text-align: center;">8 bytes/cycle</td>
</tr>
<tr>
<td rowspan="3">Constant</td>
<td>Direct-addressed constant</td>
<td style="text-align: center;">-</td>
<td style="text-align: center;">48KB</td>
<td style="text-align: center;">16 bytes/cycle</td>
</tr>
<tr>
<td>Same-indexed constant</td>
<td style="text-align: center;">-</td>
<td style="text-align: center;">-</td>
<td style="text-align: center;">4 bytes/cycle</td>
</tr>
<tr>
<td>Varying-indexed constant</td>
<td style="text-align: center;">-</td>
<td style="text-align: center;">-</td>
<td style="text-align: center;">~0.6 bytes/cycle</td>
</tr>
<tr>
<td rowspan="2">Images</td>
<td>L1 Cache</td>
<td style="text-align: center;">8KB</td>
<td style="text-align: center;">160KB</td>
<td style="text-align: center;">4 bytes/cycle</td>
</tr>
<tr>
<td>L2 Cache</td>
<td style="text-align: center;">-</td>
<td style="text-align: center;">512KB</td>
<td style="text-align: center;">~1.6 bytes/cycle</td>
</tr>
<tr>
<td>Global</td>
<td>Global Memory</td>
<td style="text-align: center;">-</td>
<td style="text-align: center;">1GB</td>
<td style="text-align: center;">~0.6 bytes/cycle</td>
</tr>
</tbody>
</table>
<p><strong>GPRs</strong> &#8211; General Purpose Registers<br />
<strong>LDS</strong> &#8211; Local Data Store<br />
<strong>Direct-addressed constant</strong> &#8211; a constant accessed using a constant address.<br />
<strong>Same-indexed constant</strong> &#8211; a varying-indexed constant where each processing element accesses the same index.<br />
<strong>Varying-indexed constant</strong> &#8211; a varying-indexed constant where the processing elements access different indices.</p>
<p>Of course, consider this data for fetches that are properly aligned. In case of unaligned data access the actual throughput can be much lower. In order to be able to reach the peak bandwidth we have to align our data usually to multiples of 4, 8 or 16 bytes (depending on actual hardware).</p>
<p>As it can be seen, constant storage can also fall into three different access performance categories so do buffers and images. While actual numbers differ on various platforms, the guidelines apply to most of modern GPUs: use a particular addressing method wisely and take in consideration access locality in order to get optimum performance.</p>
<p>These numbers are no different in case of OpenGL terminology either, just replace the word &#8220;constant&#8221; with uniform buffers and think about images and global data as texture images or buffer objects. The only exception is that there is no direct alternative for local memory in OpenGL.</p>
<p>An additional thing to consider since Shader Model 5.0 hardware is read-write images and buffers. AMD refers to the two memory access method as FastPath and CompletePath. This means that in case of read-only textures or buffers the GPU uses the FastPath that is able to take full advantage of the L2 cache while read-write textures and buffers usually use the so called CompletePath that sacrifices the advantages of the L2 cache to enable the use of atomic operations on global memory objects. This, of course, has a quite huge performance effect reducing the throughput of the GPU about five times on the Radeon HD5870:</p>
<table style="width: 100%;" border="0">
<tbody>
<tr>
<td><strong>Kernel</strong></td>
<td style="text-align: center;"><strong>Effective Bandwidth</strong></td>
<td style="text-align: center;"><strong>Ratio to Peak Bandwidth</strong></td>
</tr>
<tr>
<td>copy 32-bit 1D FastPath</td>
<td style="text-align: center;">96 GB/s</td>
<td style="text-align: center;">63%</td>
</tr>
<tr>
<td style="text-align: left;">copy 32-bit 1D CompletePath</td>
<td style="text-align: center;">18 GB/s</td>
<td style="text-align: center;">12%</td>
</tr>
</tbody>
</table>
<h2>Summary</h2>
<p>Well, now we&#8217;ve seen that how various OpenCL memory types perform in reality, let&#8217;s see how all these information translate to the OpenGL world. Here are my <strong>top-10 recommendations</strong> about when and how to use the various data acquiring possibilities present in modern OpenGL:</p>
<ol>
<li>Align your data to multiples of 16 bytes and fetch them accordingly.</li>
<li>Use direct-addressing of data in uniform buffers and try to avoid indexing into uniform buffers.</li>
<li>If you must use indexing into uniform buffers, make sure that the indices are coherent across processing elements working in sync.</li>
<li>If you heavily use indexed data consider using texture buffers instead of uniform buffers to take advantage of the L1 and L2 cache.</li>
<li>Texture and buffer caches are linear so consider this when planning you access patterns.</li>
<li>Bind textures and buffers for read-write mode only when it is really necessary, use regular texture binding otherwise to ensure optimum performance.</li>
<li>A single atomic buffer operation forces the shader to use the slow path so use atomic operations wisely.</li>
<li>Do not use atomic buffer operations to implement atomic counters, use built-in hardware atomic counters instead as they are much faster.</li>
<li>Consider using dynamic branching to avoid costly memory operations as often as possible.</li>
<li>Try to make your branch selection coherent across processing elements working in sync (e.g. 4&#215;4 fragment tile in case of a fragment shader).</li>
</ol>
<div class="wp-caption aligncenter" style="width: 505px"><img class="  " title="Memory Access Performance" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/11/mem_perf.png" alt="Memory Access Performance" width="495" height="233" /><p class="wp-caption-text">Relative performance characteristics of memory access methods (higher is better).</p></div>
<p><em>Note: This article may contain inaccurate data and some advices may not apply to other hardware platforms. I&#8217;ve made this article with the hope that it may prove useful for some developers out there. For accurate details or more information, please contact your hardware vendor.</em></p>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/11/texture-and-buffer-access-performance/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Instance Cloud Reduction reloaded</title>
		<link>http://rastergrid.com/blog/2010/06/instance-cloud-reduction-reloaded/</link>
		<comments>http://rastergrid.com/blog/2010/06/instance-cloud-reduction-reloaded/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 19:36:38 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Samples]]></category>
		<category><![CDATA[attribute divisor]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[culling]]></category>
		<category><![CDATA[geometry instancing]]></category>
		<category><![CDATA[geometry shader]]></category>
		<category><![CDATA[GLEW]]></category>
		<category><![CDATA[GLM]]></category>
		<category><![CDATA[GLSL]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[instanced array]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[SFML]]></category>
		<category><![CDATA[texture buffer]]></category>
		<category><![CDATA[transform feedback]]></category>
		<category><![CDATA[uniform buffer]]></category>
		<category><![CDATA[vertex buffer]]></category>
		<category><![CDATA[vertex shader]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=251</guid>
		<description><![CDATA[A few months ago I&#8217;ve presented an object culling mechanism that I&#8217;ve named Instance Cloud Reduction (ICR) in the article Instance culling using geometry shaders. The technique targets the first generation of OpenGL 3 capable cards and takes advantage of geometry shaders&#8217; capability to reduce the emitted geometry amount in order to get to a]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frastergrid.com%252Fblog%252F2010%252F06%252Finstance-cloud-reduction-reloaded%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2Fc2unzx%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Instance%20Cloud%20Reduction%20reloaded%22%20%7D);"></div>
<div class="wp-caption alignleft" style="width: 160px"><img src="http://rastergrid.com/blog/wp-content/uploads/2010/02/Nature-2010-02-08-20-20-36-24-150x150.png" alt="" width="150" height="150" /><p class="wp-caption-text">OpenGL 3.3 - Nature</p></div>
<p>A few months ago I&#8217;ve presented an object culling mechanism that I&#8217;ve named Instance Cloud Reduction (ICR) in the article <a title="Instance culling using geometry shaders" href="http://rastergrid.com/blog/2010/02/instance-culling-using-geometry-shaders/">Instance culling using geometry shaders</a>. The technique targets the first generation of OpenGL 3 capable cards and takes advantage of geometry shaders&#8217; capability to reduce the emitted geometry amount in order to get to a fully GPU accelerated algorithm that performs view frustum culling on instanced geometry without the need of OpenCL or any other GPU compute API. After the culling step the reduced set of instance data is fed to the drawing pass in the form of a texture buffers. In this article I will present an improved version of the algorithm that exploits the use of instanced arrays introduced lately in OpenGL 3.3 to further optimize it.</p>
<p><span id="more-251"></span>Lets recap the basics of the algorithm before I present the improved technique. The geometry shaders have a very nice feature that they cannot just emit a modified version of the input geometry but can also alter the number of emitted primitives compared to the number of received ones. This is a both-way ability what means that we cannot just increase but also decrease the number of primitives. That is what the technique takes advantage.</p>
<p>In the first pass we feed a simple vertex shader &#8211; geometry shader pair with the instance data of the geometries as they&#8217;ve been the data of point primitives. The vertex shader then checks whether the actual instance is inside the view frustum or not and sends the result to the geometry shader. If the result is yes then the geometry shader outputs the instance data otherwise discards it. The primitives emitted by the geometry shaders are captured then using transform feedback into a buffer object. Also a query object is needed in order to be able to get the amount of instances that passed the view frustum culling. In the drawing pass we use the result of the query to decide how many instances we have to draw and the captured feedback buffer is used as instance data.</p>
<div class="wp-caption aligncenter" style="width: 660px"><img src="http://rastergrid.com/blog/wp-content/uploads/2010/02/icr_combined.png" alt="" width="650" height="347" /><p class="wp-caption-text">Instance Cloud Reduction - Combined view of Pass 1 + Pass 2</p></div>
<p>This is a very brief description of the culling mechanism so for a complete specification please read the <a title="Instance culling using geometry shaders" href="http://rastergrid.com/blog/2010/02/instance-culling-using-geometry-shaders/">original article</a>.</p>
<h3>Motivation</h3>
<p>While Instance Cloud Reduction is a quite robust technique that can severely simplify and speed up the rendering of high amount of instanced geometry its performance is also limited due to some hardware and API restrictions. The most important ones are the following:</p>
<ul>
<li>Needs an extra rendering pass to perform the culling.</li>
<li>Requires the usage of asynchronous queries to determine the number of visible instances.</li>
<li>Uses texture fetching in the vertex shader of the actual drawing pass.</li>
</ul>
<p>The first mentioned drawback means that more draw commands are required that use the output of the first pass as input. This and the second disadvantage may cause stalls due to the fact that the CPU has to wait for the data to be ready before issuing the second pass thus the GPU is not used effectively.</p>
<p>What this improvement tries to solve is the third problem. Texture fetching itself is quite fast in the latest generation of hardware, however it causes some slowdowns anyway due to the latency introduced by texture fetches even though GPUs use some latency hiding techniques.</p>
<p>Instanced arrays provide us a way to replace texture fetching with vertex fetching that is usually done by different hardware element that works synchronously with the execution of vertex shaders. I&#8217;ve expected quite a reasonable speedup by taking advantage of instanced arrays, however we will see that actual results were far from my initial expectations.</p>
<h3>Implementation</h3>
<p>Traditional vertex fetching happens in a way that one element is fetched from each enabled input attribute buffer and the vertex shader is issued with these values. One element in a vertex attribute buffer can mean up to four floating point or integer values and for each execution of the vertex shader one set of these elements is used. There is an internal counter that is increased after each fetch and the next vertex attribute fetch will use this counter as an index into the buffer object.</p>
<p>While this mechanism is satisfactory for the most attributes of a vertex, it is not practical for instance data as such data belongs to an instance rather than a vertex. In order to source instance data from vertex attributes in case of traditional vertex fetching, high amount of redundant storage is required in order to get the same information for all the vertices belonging to a particular instance. This is not just waste of memory but also waste of bandwidth and it also defeats the goal of Instance Cloud Reduction.</p>
<p>Compared to traditional vertex fetching, instanced arrays provide a way to increase the internal counter used as the index into the vertex attribute buffer in a different way, in particular one can set the frequency of increase using a vertex attribute divisor that specifies after how many instances the counter shall be increased. This is a per-attribute property and by setting it to one we end up with exactly what we need: one vertex fetch per instance.</p>
<p>This means that actually we need just a very minor change compared to the original technique, more precisely we replace our texture buffer with a vertex attribute buffer that has a divisor of one and use it as the source of instance data in the vertex shader of the drawing pass.</p>
<h3>Execution results</h3>
<p>As we are not talking about a new technique but just an optimized implementation of the same method, the best way to evaluate it is by comparing the performance of the new version with the original one.</p>
<p>As I&#8217;ve mentioned earlier, I expected a reasonable performance increase by replacing texture fetches with vertex fetches, in practice the difference was not so significant. However, the performance difference between the two implementation can heavily depend on the underlying hardware implementation so various cards from various vendors and GPU generations can show more diverging behavior. In fact even driver versions may have an effect on the results.</p>
<div class="wp-caption aligncenter" style="width: 620px"><img class="  " src="http://rastergrid.com/blog/wp-content/uploads/2010/06/comparison.png" alt="" width="610" height="139" /><p class="wp-caption-text">Performance comparison of the old implementation and the presented one on an AMD Radeon HD5770. Scale is in frames per second (higher value is better).</p></div>
<p>Due to lack of hardware to use for testing, I&#8217;ve checked only with one card, namely a Radeon HD5770 with Catalyst 10.6 drivers. I noticed roughly a 10% speedup as the the new version of the Nature demo showed 100 FPS compared to the 90 FPS observed with the old implementation.</p>
<p>Even though this was not exactly the outcome I&#8217;ve expected from the new implementation, maybe the assumption is still valid for older generation of GPUs or for NVIDIA cards. I suspect so because for Shader Model 4.0 cards the hardware implementation of the texture fetching unit and the vertex fetching unit was most probably more differentiated than that of the latest GPUs. Also my guess is that on NVIDIA cards the difference is maybe higher as the vertex fetching hardware in SM 4.0 GeForce cards is less flexible than that of AMD&#8217;s taking in consideration that the first HD series Radeons already had some form of tessellation functionality that requires more freedom from the vertex pushing hardware.</p>
<p>In order to get a better picture about how effective the presented optimization is, I would like to ask all the visitors of this post to try the two releases and send me feedback about it.</p>
<h3>Conclusion</h3>
<p>We&#8217;ve seen that how easy it was to take advantage of instanced arrays in an existing implementation of the ICR technique and how does it perform on the latest generation of GPUs compared to the previous version. While this small addition provides some benefits, it also comes at a cost and we have to talk about that as well.</p>
<p><strong>Advantages:</strong></p>
<ul>
<li>Eliminates the need for texture fetching in the vertex shader thus improving performance.</li>
<li>Does not compromise the goal and the implementation architecture of the original method.</li>
<li>Frees up one texture unit that was previously reserved for the texture buffer containing the instance data.</li>
</ul>
<p><strong>Disadvantages:</strong></p>
<ul>
<li>Requires OpenGL 3.3 or the <a title="GL_ARB_instanced_arrays" href="http://www.opengl.org/registry/specs/ARB/instanced_arrays.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/instanced_arrays.txt?referer=');">GL_ARB_instanced_arrays</a> extension in addition to the OpenGL 3.2 features.</li>
<li>We have to possibly sacrifice multiple vertex input attributes to feed the instance data to the shaders.</li>
</ul>
<p>Most of the mentioned benefits and drawbacks are self-explanatory, however I would like to say a few words about the last mentioned one&#8230;</p>
<p>For the purpose of showcase I used a simple translation factor as instance data that means a single vector of floats. In real life situation one may need more complex transformation data that can only be stored in the matrix. While in the demo the feeding of instance data consumed only one vertex attribute slot, in case of a full transformation matrix it would require four of them (not to mention other possible instance attributes). As the maximum number of input attributes is severely limited, usually to 16, the application of the optimization is restricted to situations when all the vertex and instance attributes fit into this limit.</p>
<p>In case of the original implementation, where a texture buffer was used as input, this did not cause any problem as the vertex shader is free to fetch any number of texels from that (still, performance can be a concern in this case). In order to help situations when input attribute slots are at a premium, in real life scenarios it is recommended to use quaternions instead of transformation matrices as they consume two times less attribute resources. Actually this can be a general recommendation as using quaternions decreases the bandwidth requirements of the instance data fetch thus increasing performance even in situations when there are enough input attribute slots available.</p>
<p>In order to ease the performance comparison for you, you can find download links for both versions of the Nature demo.</p>
<h3>Old version binary release</h3>
<p><strong>Platform:</strong> Windows<br />
<strong>Dependency:</strong> OpenGL 3.2 capable graphics driver<br />
<strong>Download link:</strong> <a href="http://rastergrid.com/blog/wp-content/uploads/2010/06/nature12_win32.zip">nature12_win32.zip (3.58MB)</a><br />
<strong>Comments:</strong> This version does <strong>NOT </strong>include the optimization presented in this article.</p>
<h3>Old version source code</h3>
<p><strong>Language: <span style="font-weight: normal;">C++</span><br />
Platform:</strong> cross-platform<br />
<strong>Dependency:</strong> GLEW, SFML, GLM<br />
<strong>Download link:</strong> <a href="http://rastergrid.com/blog/wp-content/uploads/2010/06/nature12_src.zip">nature12_src.zip (12.6KB)</a><br />
<strong>Comments:</strong> This version does <strong>NOT </strong>include the optimization presented in this article.</p>
<h3>New version binary release</h3>
<p><strong>Platform:</strong> Windows<br />
<strong>Dependency:</strong> OpenGL 3.3 capable graphics driver<br />
<strong>Download link:</strong> <a href="http://rastergrid.com/blog/wp-content/uploads/2010/06/nature20_win32.zip">nature20_win32.zip (3.58MB)</a><br />
<strong>Comments:</strong> This version includes the optimization presented in this article.</p>
<h3>New version source code</h3>
<p><strong>Language:</strong> C++<br />
<strong>Platform:</strong> cross-platform<br />
<strong>Dependency:</strong> GLEW, SFML, GLM<br />
<strong>Download link:</strong> <a href="http://rastergrid.com/blog/wp-content/uploads/2010/06/nature20_src.zip">nature20_src.zip (12.8KB)</a><br />
<strong>Comments:</strong> This version includes the optimization presented in this article.</p>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/06/instance-cloud-reduction-reloaded/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>A brief preview of the new features introduced by OpenGL 3.3 and 4.0</title>
		<link>http://rastergrid.com/blog/2010/03/a-brief-preview-of-the-new-features-introduced-by-opengl-3-3-and-4-0/</link>
		<comments>http://rastergrid.com/blog/2010/03/a-brief-preview-of-the-new-features-introduced-by-opengl-3-3-and-4-0/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 16:23:17 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[fragment shader]]></category>
		<category><![CDATA[geometry instancing]]></category>
		<category><![CDATA[geometry shader]]></category>
		<category><![CDATA[GLSL]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[synchronization]]></category>
		<category><![CDATA[tessellation]]></category>
		<category><![CDATA[tessellation control shader]]></category>
		<category><![CDATA[tessellation evaluation shader]]></category>
		<category><![CDATA[texture array]]></category>
		<category><![CDATA[texture buffer]]></category>
		<category><![CDATA[transform feedback]]></category>
		<category><![CDATA[uniform buffer]]></category>
		<category><![CDATA[vertex shader]]></category>
		<category><![CDATA[vertex stream]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=207</guid>
		<description><![CDATA[The Khronos Group continues the progress of streamlining the OpenGL API. One very important step in this battle has been made just a few days ago by releasing two concurrent core releases of the OpenGL specification, namely version 3.3 and 4.0. This is a major update of the standard containing many revolutionary additions to the]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frastergrid.com%252Fblog%252F2010%252F03%252Fa-brief-preview-of-the-new-features-introduced-by-opengl-3-3-and-4-0%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FceIGqq%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22A%20brief%20preview%20of%20the%20new%20features%20introduced%20by%20OpenGL%203.3%20and%204.0%22%20%7D);"></div>
<p>The Khronos Group continues the progress of streamlining the OpenGL API. One very important step in this battle has been made just a few days ago by releasing two concurrent core releases of the OpenGL specification, namely version 3.3 and 4.0. This is a major update of the standard containing many revolutionary additions to the tool-set of OpenGL that need careful examination. In this article I would like to talk about these new features trying to point out their importance and touching also some practical use case scenarios.</p>
<p><span id="more-207"></span>This is the fourth revision of the OpenGL API standard in the last two years. This fast pace revolution started about one and half years ago with the release of the version 3.0 of the specification. At that time, a great feel of disappointment has overcame the developers due to the lack of the promised rewrite of the whole API. Others, who had to deal with legacy code were also disappointed but they felt so because the new revision of the API threatened them with removing old features. These two opposing forces have put the Khronos Group into a situation where there was very difficult to make a decision that would make everybody happy. After two releases, this issue has been mostly resolved with OpenGL 3.2 and also lots of missing features have been integrated into the core API meanwhile.</p>
<p>Even though great steps has been made in order to fulfill everybody&#8217;s needs, the gap between the core functionality of OpenGL and the DirectX API still increased, especially due to the introduction of Shader Model 5.0 hardware. OpenGL was in a position when it had to adopt the features of the new hardware generation and also try to make up leeway in case of Shader Model 4.0 hardware. My personal wish was that there should be two new versions of the API: one that complements the OpenGL 3.x API with the missing features and another that catches up to DirectX 11. Actually my wish became true as the first time in the history of OpenGL we got two new releases of the standard at once, and finally, we got an API that is a really competitive alternative for Microsoft&#8217;s DirectX API. I think I can say this in the name of every OpenGL developer: Thank you Khronos!</p>
<p>Okay, but that&#8217;s enough about history and acknowledgements. Lets see what&#8217;s under the hood of the new API revisions! When I read the good news at <a title="OpenGL.org" href="http://www.opengl.org/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/?referer=');">OpenGL.org</a> I felt myself like a child at Christmas just taking the first look at the presents under the tree: I was in great ecstasy and started to &#8220;open the presents&#8221; as fast as I could&#8230;</p>
<h2>New features of OpenGL 3.3</h2>
<p>Let&#8217;s start with the new version of the API targeting Shader Model 4.x hardware. It seems that the concentration on the major release 4.0 didn&#8217;t capture the attention of the ARB explicitly as we have many interesting features already in the first box&#8230;</p>
<h3><a title="ARB_blend_func_extended" href="http://www.opengl.org/registry/specs/ARB/blend_func_extended.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/blend_func_extended.txt?referer=');">ARB_blend_func_extended</a></h3>
<p>This is a feature for what I&#8217;ve seen many requests on the OpenGL discussion forums. It enables fragment shaders to output an additional color per render target that can be used as a blending factor for either source or destination colors providing an additional degree of freedom to affect the way how fragments are blended into the destination buffers. This is one functionality that is supported by the underlying hardware for a while but without API support it was impossible to take advantage of it. As it is very straightforward how this feature works I would not even talk about it too much. Just one additional comment: surprisingly <a title="ATI Catalyst 10.2: Better CrossFire and OpenGL Support" href="http://www.geeks3d.com/20100218/test-ati-catalyst-10-2-better-crossfire-and-opengl-support/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.geeks3d.com/20100218/test-ati-catalyst-10-2-better-crossfire-and-opengl-support/?referer=');">AMD already supports this extension</a> in its latest graphics drivers which is a remarkable thing taking in consideration that AMD drivers were always a step behind the NVIDIA ones in the race of adopting latest OpenGL features. It seems that now AMD takes seriously the OpenGL support and this is good news for all the developers out there, especially for me, being an ATI fan.</p>
<h3><a title="ARB_explicit_attrib_location" href="http://www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt?referer=');">ARB_explicit_attrib_location</a></h3>
<p>Most probably not just for me, the way how the binding of vertex attributes to shader attributes and the binding of shader outputs to render targets happened earlier caused a big headache from both the point of view of modular software design and efficiency. Previously, the application developer had little to no control over how to automatically connect these elements together in a shader independent way. This tight coupling between the host application code and the shaders just make the work of the developers cumbersome. This feature leverages the way how this binding process is done by allowing to globally assign a particular semantic meaning to an attribute location without knowing how that attribute will be named in any particular shader, decoupling the host application from the shaders. This extension is a typical example how design abstractions can ease the life of the developer without any dependency on hardware support.</p>
<h3><a title="ARB_occlusion_query2" href="http://www.opengl.org/registry/specs/ARB/occlusion_query2.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/occlusion_query2.txt?referer=');">ARB_occlusion_query2</a></h3>
<p>Well, there isn&#8217;t too much to say about this extension as it just adds a new occlusion query type that reports just a boolean value about the visibility of the object rather than the actual samples. It is somewhat equivalent to the occlusion query extensions prior to <a title="ARB_occlusion_query" href="http://www.opengl.org/registry/specs/ARB/occlusion_query.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/occlusion_query.txt?referer=');">ARB_occlusion_query</a>. Don&#8217;t ask me why this feature is important but they felt that it might be useful. One thing I can think about that with such a query we might get our results about the occlusion query of the proxy object sooner as we have to wait only till the first passed sample but I&#8217;m not confident whether such thing is supported by either the hardware or the drivers.</p>
<h3><a title="ARB_sampler_objects" href="http://www.opengl.org/registry/specs/ARB/sampler_objects.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/sampler_objects.txt?referer=');">ARB_sampler_objects</a></h3>
<p>This is one another feature that people have been waiting for years. This extension decouples texture image data from sampler state. Previously, if a texture image had to be used with different sampler modes, no matter if we talk about various filtering modes or texture coordinate wrapping, one had to do expensive state changes to modify the sampler state of the texture object, accomplish the needed filtering or wrapping from within shaders or, in worst case, duplicating texture image data in order to have access to the same texture with different sampler parameters. The primary intend of this feature is to solve these problems.</p>
<p>One thing to remark regarding to this extension is that even though it is a long waited addition to the API, several people already expressed their discontent regarding to the fact that the texture unit semantics have been kept. Nevertheless, I also expected that the introduction of this feature should be the point when the texture unit semantics has to go but after seeing the example of <a title="ARB_explicit_attrib_location" href="http://www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt?referer=');">ARB_explicit_attrib_location</a> as a way to decouple the shader code from the host application code I tend to agree with Khronos in this decision as we can think about the texture units from now as an adapter layer between GPU and CPU code and as such the decision seems reasonable.</p>
<h3><a title="ARB_shader_bit_encoding" href="http://www.opengl.org/registry/specs/ARB/shader_bit_encoding.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/shader_bit_encoding.txt?referer=');">ARB_shader_bit_encoding</a></h3>
<p>This extension adds built-in functions for getting and setting the bit encoding for floating-point values in the OpenGL Shading Language. As it is more like an indicator extension regarding to added functionality in the Shading Language I would rather not go into details as I will talk about the new Shading Language later.</p>
<h3><a title="ARB_texture_rgb10_a2ui" href="http://www.opengl.org/registry/specs/ARB/texture_rgb10_a2ui.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_rgb10_a2ui.txt?referer=');">ARB_texture_rgb10_a2ui</a></h3>
<p>Again, an extension that is quite self-explanatory: new texture image format called RGB10_A2 with non-normalized unsigned integers in them. This is nothing more than another hole filled in the gap between hardware and API support.</p>
<h3><a title="ARB_texture_swizzle" href="http://www.opengl.org/registry/specs/ARB/texture_swizzle.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_swizzle.txt?referer=');">ARB_texture_swizzle</a></h3>
<p>Especially when using one or two component texture formats, like in the case of shadow maps, the specification was somewhat unclear how these components are finally mapped to RGBA quadruples and provided little to no facilities to control this process. If the developers weren&#8217;t already fed up with this, the possibility of a problem increased even further because often the driver implementations behaved differently as well. This issue has been finally clarified with this extension by providing an explicit tool for the application developer to control the swizzling of the components that is done implicitly afterwards in case of every single texture fetch. The new state is introduced as part of texture object state that provides fine grained control over when and how to use the swizzling. According to the extension specification, this feature has a notable role in helping porting issues of legacy OpenGL applications as well as those of the games written for PlayStation 3 as the console provides such functionality already.</p>
<h3><a title="ARB_timer_query" href="http://www.opengl.org/registry/specs/ARB/timer_query.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/timer_query.txt?referer=');">ARB_timer_query</a></h3>
<p>Prior to this extension, runtime performance measurements were limited to the use of client side timing information or relying on the use of offline profiling mechanisms like that of AMD&#8217;s <a title="GPU PerfStudio" href="http://developer.amd.com/gpu/perfstudio/Pages/default.aspx" target="_blank" onclick="pageTracker._trackPageview('/outgoing/developer.amd.com/gpu/perfstudio/Pages/default.aspx?referer=');">GPUPerfStudio</a>. During development, this timing information can help identify application, driver or GPU bottlenecks. At runtime, this data can be used to dynamically optimize the scene to achieve reasonable frame rates. While today&#8217;s hardware provides a great repertoire of performance measurement metrics there was no API support to access these previously. This feature provides an additional asynchronous query type that enables application developers to measure the driver and GPU time that is required to complete a set of rendering commands, thus providing additional flexibility for both offline and runtime optimizations. While this extension does not guarantee 100% consistency and repeatability, the information gathered with timer queries will definitely make it possible to identify server side bottlenecks and the reasons behind them.</p>
<h3><a title="ARB_instanced_arrays" href="http://www.opengl.org/registry/specs/ARB/instanced_arrays.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/instanced_arrays.txt?referer=');">ARB_instanced_arrays</a></h3>
<p>Many people argued with me at the OpenGL discussion forums when I stated that instanced arrays should be included in core OpenGL. Their reasoning was built on the fact that we already have the <a title="ARB_draw_instanced" href="http://www.opengl.org/registry/specs/ARB/draw_instanced.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/draw_instanced.txt?referer=');">ARB_draw_instanced</a> extension that provides a shader based thus much more flexible way to handle instanced geometry. While from this point of view I tend to agree with them, there are many non-trivial use cases which prove that my reasoning is not pointless. It seems that Khronos agrees with me regarding to this topic.</p>
<p>In a nutshell, the instanced arrays feature enables the use of vertex attributes as a source of instance data. This is done by introducing a so called &#8220;array divisor&#8221; that specifies how the corresponding vertex attributes are mapped to instances. Usually a vertex attribute advances on a per-vertex basis. In case of instanced arrays this advance happens only after ever<span style="font-size: small;">y Nth conceptual draw calls that is equivalent to  a traditional draw command, excluding instanced draw commands.</span></p>
<p>One use case can be when one deals with huge number of instances where the per-instance data simply not fits into uniform buffers. While in such cases one can use a texture buffer instead to source the instance data like it was mentioned in my article <a title="Uniform Buffers VS Texture Buffers - RasterGrid Blog" href="http://rastergrid.com/blog/2010/01/uniform-buffers-vs-texture-buffers/">Uniform Buffers VS Texture Buffers</a>, accepting the additional overhead of using texture fetches may prove to be a not-so-performance-wise decision. Beside standard instancing use cases, there are plenty of nasty tricks that can be efficiently achieved using this feature but that goes far beyond the scope of this article and requires a separate discussion on what I will most probably recap in the near future.</p>
<h3><a title="ARB_vertex_type_2_10_10_10_rev" href="http://www.opengl.org/registry/specs/ARB/vertex_type_2_10_10_10_rev.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/vertex_type_2_10_10_10_rev.txt?referer=');">ARB_vertex_type_2_10_10_10_rev</a></h3>
<p>We&#8217;ve arrived to the final new extension included in core OpenGL 3.3. This is another gap filling extension to provide two new vertex attribute data formats: a signed and an unsigned format with 10 bits for each significant coordinate. The most typical use of this format is to store vertex normals in the signed-normalized version of the format in order to have a compact (4 bytes per normal) yet high precision (due to 10 bits per component) format that can reduce memory needs and bandwidth requirements while retaining sufficient precision. Previously, there was no way to have such high precision for the vertex attributes in case of a 4-byte footprint.</p>
<h3>The OpenGL Shading Language 3.30</h3>
<p>The first remarkable thing is the shift in the versioning of the Shading Language. It seems that from now it will be in align with the core specification version. This decision was most probably made because of the introduction of two release branches of the standard specification in order to avoid confusion regarding to the correspondence between API and Shading Language versioning.</p>
<p>As in case of talking about the OpenGL Shading Language it is much more difficult to easily summarize the new features with corresponding use cases I will simply limit my comments to an excerpt from its specification regarding to the features added in this new version:</p>
<ul>
<li>Layout qualifiers can be used to declare the location of vertex shader inputs and fragment shader outputs in align with the API functionality provided by <a title="ARB_explicit_attrib_location" href="http://www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt?referer=');">ARB_explicit_attrib_location</a> as mentioned before.</li>
<li>Built-in functions provided to converting floating-point values to integer ones representing their encoding.</li>
<li>Some clarification of already existing facilities of the language.</li>
</ul>
<h2>New features of OpenGL 4.0</h2>
<p>It is very obvious that the major version number change indicates that this revision of the specification is targeting Shader Model 5.0 hardware. To be honest, as I was never really interested in DirectX, I barely know all the features introduced by DX11 but seems that there are some great facilities in OpenGL 4.0 that I&#8217;ve never heard that hardware supports it. This can be due to DX11 does not even support such functionalities but it is maybe because I don&#8217;t know enough details about DX11. Anyway, let&#8217;s see the revolutionary things that we face we checking out the latest version of the OpenGL specification&#8230;</p>
<h3><a title="ARB_draw_buffers_blend" href="http://www.opengl.org/registry/specs/ARB/draw_buffers_blend.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/draw_buffers_blend.txt?referer=');">ARB_draw_buffers_blend</a></h3>
<p>Using this feature one is able to select individual blend equations and blend functions for each render target. This extension was already exposed for a few months now so most probably everybody heard about it or even if not the functionality is very straightforward. It simply removes some of the restrictions when dealing with multiple render targets (MRT). One interesting thing is still that the Khronos Group decided to include this extension in the 4.0 version of the API but not in 3.3. This is odd as Shader Model 4.0 capable hardware already supports this feature or at least I have the extension on my Radeon HD2600 which raises the question: why only in 4.0? Unfortunately, I don&#8217;t know the answer but I hope the ARB has a good reason behind this, as we will see later, there are other features that for some reason were only exposed in the latest version of the API but not in core for Shader Model 4.0 hardware.</p>
<h3><a title="ARB_sample_shading" href="http://www.opengl.org/registry/specs/ARB/sample_shading.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/sample_shading.txt?referer=');">ARB_sample_shading</a></h3>
<p>In case of traditional multisample rendering the hardware optimizes the multisampling in a way that the fragment shader is executed only once for each fragment. This can be done as the standard specification relaxes the way how the implementation behaves regarding to feeding color and texture coordinate values for each sample. While this optimization usually does not provide any rendering artifacts and it heavily reduces the amount of pressure on the GPU, there are some situations when this optimization results in aliasing artifacts. One sample use case is when alpha-tested primitives are rendered.</p>
<p>This extension provides a global state for enabling and disabling sample shading and a way to control how fine-grained per-sample shading should be by supplying a minimum number of samples that need to be shaded. Beside this, it also introduces the required language elements to the OpenGL Shading Language to support sample shading.</p>
<h3><a title="ARB_shader_subroutine" href="http://www.opengl.org/registry/specs/ARB/shader_subroutine.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/shader_subroutine.txt?referer=');">ARB_shader_subroutine</a></h3>
<p>In my humble opinion, this is one of the most important features introduced in this new version of the API specification. So far, many engine and shader developers faced the problems that where inherently there in the Shading Language that heavily reduced the ability to create a modular shader design in order to separate the independent tasks done in shaders nowadays. One initiative was the idea behind the <a title="EXT_separate_shaders" href="http://www.opengl.org/registry/specs/EXT/separate_shader_objects.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/EXT/separate_shader_objects.txt?referer=');">EXT_separate_shader_objects</a> extension. While that extension removed the dependency between shader stages, it does not address the problem with tight coupling inside one shader stage, also the aforementioned extension defeats some of the design goals of the Shading Language introducing complicated language semantics in order to solve the problem of inter-stage dependency.</p>
<p>Just to emphasize the importance of this new functionality with a very basic example, let&#8217;s take a simple rendering engine that supports skeletal animated geometry, materials and lights. In such a use case both the vertex and fragment shaders have multiple roles: the vertex shader has to perform the skeletal animation (property of the geometry) and the view transformation (property of the camera or of the light in case of shadow map rendering), and the fragment shader has to calculate the incident light to the surface point (property of the light) and then calculate the illuminance factor (property of the material). With the traditional tool-set these components of the shaders were tightly coupled and in order to support the combination of any geometry type (animated or not, skeletal or morph animation, etc.), any light type (directional, point, etc.) and material type (diffuse, phong, environment mapped, etc.), one had to compile all possible combinations of the shaders or create uber-shaders that do run-time decisions in order to solve the problem of heterogeneous inputs. Both of these solutions provide additional hardware resource usage and possible runtime overhead.</p>
<p>This extension adds some kind of polymorphism support to shaders. This way a single shader can include many alternative subroutines for a particular task and dynamically select through the API which subroutine is called from each call site. This opens the doors for modular shader designs while retaining most of the performance of specialized shaders.</p>
<h3><a title="ARB_tessellation_shader" href="http://www.opengl.org/registry/specs/ARB/tessellation_shader.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/tessellation_shader.txt?referer=');">ARB_tessellation_shader</a></h3>
<p>Yes, this is about the new geometry tessellation mechanism introduced by Shader Model 5.0 hardware. The extension itself introduces three new stages that are roughly situated between the vertex shader and the geometry shader:</p>
<ul>
<li><strong>Tessellation Control Shader</strong> &#8211; This new shader type operates on a patch that is actually nothing more than a fixed-size collection of vertices, each with per-vertex attributes and a number of associated per-patch attributes. Also note that while it operates on a patch, it is invoked on a per-vertex basis. The most important rule of this shader is to perturb the tessellation level for the patch that controls how finely the patch will be tesselated. Usually think about a patch as a triangle or quad. This shader is equivalent to DX11&#8242;s hull shader.</li>
<li><strong>Fixed-function tessellation primitive generator</strong> &#8211; The role of this new stage is to subdivide the incoming patch based on the tessellation level and related configuration that the unit gets as input.</li>
<li><strong>Tessellation Evaluation Shader</strong> &#8211; This new shader type is responsible of calculating the position and other attributes of the vertices produced by the tesselator. This shader is equivalent to DX11&#8242;s domain shader.</li>
</ul>
<p>One important thing to notice is that a new primitive type is introduced, namely a patch. A patch on its own it is not directly or indirectly related to any traditional OpenGL primitive as it cannot be directly rendered. It is used only as the input type for the tesselator, however, a patch supplies the control grid of the geometry to be generated via tessellation so in practice it is most likely to be equivalent with triangles or quads but it is important to remark the difference.</p>
<p>As this is maybe the most well known feature of Shader Model 5.0 hardware I wouldn&#8217;t like to talk about it more as everybody knows what is it for and it would be rather long to explain how to use it. Also, it is not the intension of this article to fully cover the usage of all the new features, it is just a quick summarization of the new possibilities.</p>
<h3><a title="ARB_texture_buffer_object_rgb32" href="http://www.opengl.org/registry/specs/ARB/texture_buffer_object_rgb32.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_buffer_object_rgb32.txt?referer=');">ARB_texture_buffer_object_rgb32</a></h3>
<p>Yet another extension that introduces an additional format, now for texture buffers. Previously, texture buffers supported only four-component formats, this is extended with three-component formats. As currently there is no any practical use case in my mind when this can be useful, I would rather not come up with one. However, my opinion is that these formats most probably work with reduced performance compared to the four-component ones even though the memory footprint and bandwidth usage is maybe somewhat lower, I have concerns regarding to alignment related performance issues.</p>
<h3><a title="ARB_texture_cube_map_array" href="http://www.opengl.org/registry/specs/ARB/texture_cube_map_array.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_cube_map_array.txt?referer=');">ARB_texture_cube_map_array</a></h3>
<p>Those who already use texture arrays to help batching issues and remove unnecessary state changes most probably adore this extension as it enables texture array capabilities also for cube map textures. This comes handy especially in case when many materials use environment cube maps or when shadow cube maps are used for point lights. To come up with even a more concrete example, you can render the shadow cube maps for many hundreds of point lights with a single draw call by taking advantage of the layered rendering capability of geometry shaders and the possibility to bind texture arrays as render targets.</p>
<p>One more thing to notice here is that cube map arrays are already supported by Shader Model 4.1 hardware so the question to the ARB is again there, however, as OpenGL 3.3 still targets Shader Model 4.0 hardware maybe we will see a 3.x version of the specification that will also include this extension. The judgement is up to you whether you agree with me or not.</p>
<h3><a title="ARB_texture_gather" href="http://www.opengl.org/registry/specs/ARB/texture_gather.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_gather.txt?referer=');">ARB_texture_gather</a></h3>
<p>Another feature from the repertoire of Shader Model 4.1. This extension introduces new texture fetching functions to the Shading Language that determine a 2&#215;2 footprint of the texture that would be used for linear filtering in a texture lookup and returns a vector consisting of the first component from each of the four texels in the footprint. This is the so called Gather4 texture fetching mode and can be useful to accelerate percentage closer filtering of shadow maps as it can fetch four samples at once. Still, there are some limitations on the use of this fetching mode, one important thing is that a shader cannot use normal and gather fetches on the same sampler. This makes me think about whether this feature is not part of the sampler object state instead of being a Shading Language construct. Anyway, as in typical use cases these limitations does not defeat the goal of the feature, I would not consider this problem a design issue.</p>
<h3><a title="ARB_transform_feedback2" href="http://www.opengl.org/registry/specs/ARB/transform_feedback2.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/transform_feedback2.txt?referer=');">ARB_transform_feedback2</a></h3>
<p>The transform feedback mechanism already proved to me that is a great addition to the tool-set of graphics application developers. This feature extends transform feedback with an object type that encapsulates transform feedback related state to enable configuration reuse. Also it provides a way to pause and resume transform feedback mode if, for some reason, some rendering commands should be excluded from the feedback process.</p>
<p>The last and maybe most important benefit of this extension is the ability to draw primitives captured in transform feedback mode without querying the captured primitive count. It is roughly equivalent to DX10&#8242;s AutoDraw feature and the purpose of it is to eliminate the need to query the number of previously generated primitives in order to supply it to an OpenGL draw command. This solves the synchronization issues that previously happened between the CPU and the GPU.</p>
<p>One example is when a skeletal animated geometry has to be used in a multipass rendering technique. We can think about traditional forward rendering or when dealing with multiple shadow maps that have to be generated. Anyway, as the calculations needed to perform skeletal animation are rather expensive, it is wastage to perform these calculations in each pass.  A common way to solve this problem is to use transform feedback to capture the geometry emitted by a vertex shader that simply executes the skeletal animation on the input geometry. In subsequent rendering passes this feedback buffer can be used to source the geometry data to eliminate the need to recompute the animation. Without this extension, in such cases the application is most probably stalled until the feedback process ends as it needs to query the number of generated primitives. With this extension, this is solved as we don&#8217;t have to know the results of the previous transform feedback in order to issue a draw command that sources the data from the feedback buffer. By the way, this seems to be logical as the information is already on the GPU so why it should ping-pong between the CPU and the GPU?</p>
<p>As I mentioned before, the functionality provided by this extension is equivalent to DX10&#8242;s AutoDraw feature. This time my question is really serious: why this feature haven&#8217;t been included in OpenGL 3.3? It would provide a great benefit for those who use transform feedback and I don&#8217;t see any reason behind not supporting it because, as far as I can tell, it is supported on the corresponding hardware.</p>
<h3><a title="ARB_transform_feedback3" href="http://www.opengl.org/registry/specs/ARB/transform_feedback3.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/transform_feedback3.txt?referer=');">ARB_transform_feedback3</a></h3>
<p>Surprisingly, OpenGL 4.0 comes with another transform feedback extension as well but this time a true Shader Model 5.0 feature. The new hardware generation has the ability to emit vertices from the geometry shader to multiple vertex streams. In order to provide clever API support, the ARB decided to relax the previous limitation of transform feedback mode that output can be in either interleaved format or to separate buffers. This new extension enables the use of both together also providing a way to group geometry shader outputs to groups in order to target the individual vertex streams.</p>
<p>The most important benefit of this feature is still that we have separate streams, each with its own primitive emission counter so the outputs should not necessarily have the same granularity. This provide room for very clever rendering techniques. As an example, remember NVIDIA&#8217;s <a title="NVIDIA Skinned Instancing demo" href="http://developer.download.nvidia.com/SDK/10/direct3d/samples.html" target="_blank" onclick="pageTracker._trackPageview('/outgoing/developer.download.nvidia.com/SDK/10/direct3d/samples.html?referer=');">Skinned Instancing</a> demo that used one draw call per geometry LOD to sort instance data on a per-LOD basis. Using this extension, this preprocessing step can be done with a single draw call, but the abilities of this feature goes far beyond such a simple use case, I will also talk a bit about another in the next section.</p>
<p>One of my less technical notes is that it seems that the Khronos Group members have good sense of humor. I realized this when I met the &#8220;manbearbig&#8221; when reading one of the examples in the extension specification.</p>
<h3><a title="ARB_draw_indirect" href="http://www.opengl.org/registry/specs/ARB/draw_indirect.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/draw_indirect.txt?referer=');">ARB_draw_indirect</a></h3>
<p>We&#8217;ve arrived to the most culminating point in the list of features introduced. It is hard to say such a thing, but in my humble opinion this extension can be the Holy Grail of next generation rendering engines. I will explain why I think so&#8230;</p>
<p>The extension provides a way to source the parameters of instanced draw commands from within buffer objects. One naive use case would be to put all the rendering command parameters to a buffer object using the host application and then draw everything with a single command. While this simple method already has its benefits, this feature provides much more flexibility than this. The most revolutionary is that, using this extension, one is able to generate instanced draw commands with the GPU on-the-fly. Together with <a title="ARB_transform_feedback3" href="http://www.opengl.org/registry/specs/ARB/transform_feedback3.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/transform_feedback3.txt?referer=');">ARB_transform_feedback3</a> it is possible to write a completely GPU based scene management system.</p>
<p>Those who remember my <em>Instance Cloud Reduction</em> (ICR) algorithm, presented in the article <a title="Instance culling using geometry shaders - RasterGrid Blog" href="http://rastergrid.com/blog/2010/02/instance-culling-using-geometry-shaders/">Instance culling using geometry shaders</a>, know that the required synchronization points between the CPU and the GPU heavily limited the practical utility of the culling technique. By taking advantage of the aforementioned features in case of ICR does not just eliminate the synchronization issues that I&#8217;ve spoken of but makes the technique practical also in case of heavily heterogeneous scenes with virtually any number of geometries even if there are multiple number of LOD level for them, and this whole stuff can be done with even less number of draw calls than that of the demo that accompanied my article. As soon as we will see OpenGL 4.0 capable drivers I will write an article about this technique, supplying also a reference implementation.</p>
<h3><a title="ARB_texture_query_lod" href="http://www.opengl.org/registry/specs/ARB/texture_query_lod.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_query_lod.txt?referer=');">ARB_texture_query_lod</a></h3>
<p>This extension provides new fragment shader texture functions, namely textureLOD*, that return the results of automatic LOD computations that would be performed if a texture lookup would be performed. These functions return a two-component vector. The X component of the result vector contains information about the mipmap level that would be used if a normal texture lookup would have been made with the same coordinates. This value can be a concrete mipmap level or a value between two levels if trilinear filtering is in use. The Y component of the result holds the computed LOD lambda-prime, see the OpenGL specification in order to check out where it is actually coming from and how it is calculated.</p>
<p>One interesting thing that this extension can be used for is when one implements some shader based filtering and addressing method for textures. As an example, lets take a mega-texture implemented that uses a 3D texture for storage, without actual mipmaps, and the addressing, filtering and mipmapping is done with shader code. As right now this is the only example that came into my mind and this is already awkward enough, I would rather leave the further discussion of the importance of this feature to more competent people.</p>
<h3><a title="ARB_gpu_shader5" href="http://www.opengl.org/registry/specs/ARB/gpu_shader5.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/gpu_shader5.txt?referer=');">ARB_gpu_shader5</a></h3>
<p>Basically, this extension is nothing more than a big umbrella feature under what all the additional general or minor API changes go. Just to sum up the miscellaneous features provided by this extension, here is an excerpt from the extension specification:</p>
<ul>
<li>Support for indexing into arrays of samplers using non-constant indices.</li>
<li>Support for indexing into an array of uniform blocks.</li>
<li>Extending Gather4 with the ability to select any single component of a multi-component texture, to perform per-sample depth comparison, and to specify arbitrary offsets computed at runtime when gathering the 2&#215;2 footprint.</li>
<li>Support for instanced geometry shaders, where a geometry shader may be run multiple times for each primitive.</li>
</ul>
<p>For a full list of new facilities introduced by the extension refer to the extension specification.</p>
<h3><a title="ARB_gpu_shader_fp64" href="http://www.opengl.org/registry/specs/ARB/gpu_shader_fp64.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/gpu_shader_fp64.txt?referer=');">ARB_gpu_shader_fp64</a></h3>
<p>This extension enables the use of double-precision floating-point data types and arithmetic from within shaders, also providing API entry points for double-precision data where it was missing. While one may think that the added precision is somewhat wastage in case of real-time graphics, it is important to note that GPUs are more and more often used for scientific calculations, not even necessarily in case of graphics related tasks. Taking in consideration this fact, the importance of double-precision floating-point support should not be underestimated. Beside that, maybe standard graphics application developers can also take advantage of the higher precision in some extreme use case scenarios.</p>
<h3>The OpenGL Shading Language 4.00</h3>
<p>Beside what I&#8217;ve already mentioned, there is no important thing to mention regarding to the Shading Language. There where many changes but most of them are simply provide Shading Language support to the API extensions. What I haven&#8217;t mentioned so far is the synchronization possibility for tessellation shaders, more implicit conversions, more integer functions, packing and unpacking facilities for floating-point formats and a new qualifier to force precision and disallow optimizations that re-order operations or treat different instances of the same operator with different precision.</p>
<h2>Conclusion</h2>
<p>I hope that some of you didn&#8217;t give up the reading so far. Sorry, but it seems that this article gone wild and still didn&#8217;t manage to cover all the topics I intended to talk about. But still, maybe I&#8217;ll recap on those subjects later.</p>
<blockquote><p>Where is direct state access?</p></blockquote>
<p>The original promise of eliminating the bind-to-modify semantics from the OpenGL API is still not done. The first reaction of many people is still to ask this question. While the bind-to-modify semantics is a rather annoying &#8220;feature&#8221; of OpenGL, I tend to state that if we are not talking about legacy OpenGL, the importance of direct state access is less and less relevant as we can already heavily reduce the number of state changes and API calls in our applications, thanks to the fast pace evolution of OpenGL. I sincerely think that with a modern rendering engine design built upon the idioms behind the new versions of the OpenGL API one should not face any significant scalability issues due to the outdated bind-to-modify semantics but maybe I&#8217;m wrong.</p>
<p>Personally, I have only one problem with the newly released specification versions that I&#8217;ve already tried to emphasize several times: the fact that so far many Shader Model 4.x features are missing from the 3.x line of the API specification. Hopefully that will be solved sooner or later, however addressing these issues should happen before the hardware to support will become outdated.</p>
<p>Anyway, we should not have any harsh complains as the Khronos Group did a great job again. They managed to keep again the half-year schedule and they even published two parallel releases at once! If someone still says that the DirectX API is superior compared to OpenGL should think it twice, as it seems that the tendency is that OpenGL just starts to evolve more and more fast. Beside that as now also AMD is being active in the OpenGL world, we can expect good support from both industry and developer community point of view.</p>
<p>My respect for the Khronos Group and thanks for reading the article!</p>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/03/a-brief-preview-of-the-new-features-introduced-by-opengl-3-3-and-4-0/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Instance culling using geometry shaders</title>
		<link>http://rastergrid.com/blog/2010/02/instance-culling-using-geometry-shaders/</link>
		<comments>http://rastergrid.com/blog/2010/02/instance-culling-using-geometry-shaders/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 22:58:53 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Samples]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[culling]]></category>
		<category><![CDATA[fragment shader]]></category>
		<category><![CDATA[geometry instancing]]></category>
		<category><![CDATA[geometry shader]]></category>
		<category><![CDATA[GLEW]]></category>
		<category><![CDATA[GLM]]></category>
		<category><![CDATA[GLSL]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[SFML]]></category>
		<category><![CDATA[texture buffer]]></category>
		<category><![CDATA[transform feedback]]></category>
		<category><![CDATA[uniform buffer]]></category>
		<category><![CDATA[vertex buffer]]></category>
		<category><![CDATA[vertex shader]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=135</guid>
		<description><![CDATA[Since the appearance of Shader Model 4.0 people wonder how to take advantage of the newly introduced programmable pipeline stage. The most important feature enabled by geometry shaders is that one can change the amount of emitted primitives inside the pipeline. The first thing that a naive developer would try to do with it is]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frastergrid.com%252Fblog%252F2010%252F02%252Finstance-culling-using-geometry-shaders%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FanKmpg%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Instance%20culling%20using%20geometry%20shaders%22%20%7D);"></div>
<div id="attachment_136" class="wp-caption alignleft" style="width: 160px"><a href="http://rastergrid.com/blog/wp-content/uploads/2010/02/Nature-2010-02-08-20-20-36-24.png"><img class="size-thumbnail wp-image-136  " title="Nature demo screenshot" src="http://rastergrid.com/blog/wp-content/uploads/2010/02/Nature-2010-02-08-20-20-36-24-150x150.png" alt="Nature demo screenshot" width="150" height="150" /></a><p class="wp-caption-text">OpenGL 3.2 - Nature</p></div>
<p>Since the appearance of Shader Model 4.0 people wonder how to take advantage of the newly introduced programmable pipeline stage. The most important feature enabled by geometry shaders is that one can change the amount of emitted primitives inside the pipeline. The first thing that a naive developer would try to do with it is geometry tesselation. However, the new shader performs very bad when used for tesselation in a real life scenario even though there are demos show casting this possibility. If we take a closer look at the new feature we observe that the most revolutionary in it is not that it can raise the number of emitted primitives but that it can discard them. This article would like to present a rendering technique that takes advantage of this aspect of geometry shaders to enable the GPU accelerated culling of higher order primitives.</p>
<p><span id="more-135"></span>Geometry shaders can be used for many different advanced rendering techniques that were impossible before the introduction of this flexible programmable shader stage. In this article I would like to present one use case that for me seemed to be one of the most practical application of primitive manipulation possibilities introduced by geometry shaders. As I haven&#8217;t seen any whitepaper talking specifically about this particular technique, even if some of them inherently used it, I would dare name the technique myself as <strong>Instance Cloud Reduction</strong>. I will also present a demo program that shows how to take advantage of the technique in a heavy workload situation.</p>
<p>The idea itself was inspired by AMD&#8217;s  tech demo for the Radeon 4800 series cards called <a title="March of the Froblins" href="http://developer.amd.com/samples/demos/pages/froblins.aspx" target="_blank" onclick="pageTracker._trackPageview('/outgoing/developer.amd.com/samples/demos/pages/froblins.aspx?referer=');">March of the Froblins</a>. An almost identical technique presented in this article is used in the mentioned demo for the culling of large amount of animated creatures against the view frustum. Also a somewhat similar technique is used in NVIDIA&#8217;s <a title="Skinned Instancing" href="http://developer.download.nvidia.com/SDK/10/direct3d/samples.html" target="_blank" onclick="pageTracker._trackPageview('/outgoing/developer.download.nvidia.com/SDK/10/direct3d/samples.html?referer=');">Skinned Instancing</a> demo for determining LOD instance sets. Unfortunately, both demos are for DirectX only and, as far as I can tell, there is no OpenGL demo showing any of the aforementioned rendering techniques.</p>
<h3>Motivation</h3>
<p>Nowadays, as the computational capabilities of GPUs is growing in a much faster pace than that of CPUs, graphics developers meet more and more optimization problems related to CPU bound applications. More and more focus is on minimizing the number of driver invocations, actually that&#8217;s what motivated the restructuring of the two most commonly used graphics APIs. As a result we have now DirectX 10+ and OpenGL 3+. However, even if the introduction of geometry instancing, texture arrays and local memory buffer storage for the most important inputs of the rendering, there is still need for wise decisions from graphics programmers to take full advantage of the horsepower coming with the latest GPUs.</p>
<p>Earlier graphics applications strongly relied on CPU based culling techniques, whether it be the usage of the quite outdated BSPs or the more generic and still heavily applied hierarchical culling techniques. We&#8217;ve already reached the point that sometimes even the most efficient CPU based culling techniques seem to be too expensive and usually introduce the small batch problem. Instanced rendering is not an exception.</p>
<p>The applicability of geometry instancing is strongly limited by several factors. One of the most important ones is the culling of instanced geometries. One may choose to cull these objects in the same fashion as others, using the CPU, but that usually breaks the batch and maybe we loose the benefits of geometry instancing. It is more and more imminent to have a GPU based alternative. Without CPU based culling, by sending the whole bunch of instances down the graphics pipeline may choke our vertex processor in case we have high poly geometries and quite large amount of instances of it.</p>
<p>The rendering technique presented in this article will try to achieve this goal. We will use a multi-pass technique that in the first pass culls the object instances against the view frustum using the GPU and in the second pass renders only those instances that are likely to be visible in the final scene. This way we can severely reduce the amount of vertex data sent through the graphics pipeline.</p>
<h3>Implementation</h3>
<p>For some people it might seem that the promise for such a technique is simply too naive and is most probably relying on very exotic OpenGL features, heavy misuse of some basic features or need of data conversions during the frame rendering. Wondrously, this is not the case as we have all we need in OpenGL 3.2 to implement the object culling method sketched above. All we need are the followings:</p>
<ul>
<li>instanced rendering (core since OpenGL 3.1)</li>
<li>geometry shaders (core since OpenGL 3.2)</li>
<li>transform feedback (core since OpenGL 3.0)</li>
<li>uniform or texture buffers (core since OpenGL 3.1)</li>
</ul>
<p>The method itself is a multi-pass rendering technique, however, unlike other multi-pass rendering techniques it does not produce any fragments in the first pass, instead the first pass does the view frustum culling and processes data entirely only inside buffer objects.</p>
<h3>Culling pass</h3>
<p>In the first pass we will feed the graphics pipeline with information about the instances that are needed to perform the view frustum culling. For this we need two inputs for the executed shaders in order to be able to perform the required calculations:</p>
<ol>
<li><strong>Instance transformation data</strong> (whether it be a simple transformation matrix or quaternions or whatever) -- This preferably comes from one or more buffer objects that are bound as vertex buffers to the context.</li>
<li><strong>Object extents information</strong> -- Beside the instance positions we have to know the extents of an instance in order to perform correct culling. This can be either a single float representing the object radius if we choose to use bounding spheres for the culling or a three-dimensional extent vector if we would like to use bounding boxes.</li>
</ol>
<p>Using these as input we can feed in the instance transformation data as attributes of point primitives to our culling shader. The culling shader is composed of a vertex and a geometry shader. In a typical setup the role of each is the following: the vertex shader determines whether the actual object instance&#8217;s bounding volume is inside the view frustum and sends a flag about the culling to the geometry shader, that will emit the instance data to the destination buffer if the flag says that the instance is likely to be visible or does not emit anything if it is determined that the object instance is out of view.</p>
<p>Next, transform feedback is used to capture the primitives emitted by the geometry shader into another buffer object that will be used in the actual rendering pass to source instance transformation data. Beside this, we also need to have an asynchronous query to determine the number of primitives generated to know how many instances of the object do we actually need to render. The following figure shows the workflow of the first pass:</p>
<div id="attachment_146" class="wp-caption aligncenter" style="width: 460px"><a href="http://rastergrid.com/blog/wp-content/uploads/2010/02/icr_pass1.png"><img class="size-full wp-image-146" title="Culling pass" src="http://rastergrid.com/blog/wp-content/uploads/2010/02/icr_pass1.png" alt="Culling pass" width="450" height="200" /></a><p class="wp-caption-text">Instance Cloud Reduction - Pass 1: Culling</p></div>
<p>The actual geometry shader implementation needed to perform the actual culling based on the view frustum check performed by the vertex shader should look like the following chunk:</p>
<pre class="brush: c">#version 150 core

layout(points) in;
layout(points, max_vertices = 1) out;

in vec4 OrigPosition[1];
flat in int objectVisible[1];

out vec4 CulledPosition;

void main() {

	/* only emit primitive if the object is visible */
	if ( objectVisible[0] == 1 )
	{
		CulledPosition = OrigPosition[0];
		EmitVertex();
		EndPrimitive();
	}
}</pre>
<p>In this example we used only simply a four-component position vector for the instance transformation data but the technique works well for transformation matrices and quaternions as well.</p>
<p>One more thing is that beside that we set up transform feedback in a way that we feed our buffer object dedicated for the culled instance data and we also started an asynchronous query to be able to determine the number of primitives written into the buffer object, it is also useful to turn of rasterization as we wouldn&#8217;t like to produce any fragments as a result of the first pass.</p>
<h3>Rendering pass</h3>
<p>In the second pass there is nothing special to do. Simply use whatever rendering setup you would like to use. The only things that need to be changed in this step compared to your already existing rendering path is that the instance data for the rendering must be sourced from the generated culled instance data buffer and, as a result, the number of instances passed for the instanced drawing functions shall be changed in order to render only the visible instances. This number can be read from the asynchronous query&#8217;s result that we started in the first pass.</p>
<p>The instance data in the rendering pass can be, of course, sourced from either a uniform or a texture buffer object. This depends on the actual use case and is more clearly explained in the article <a href="http://rastergrid.com/blog/2010/01/uniform-buffers-vs-texture-buffers/">Uniform Buffers VS Texture Buffers</a>.</p>
<p>Important note is that when one has to deal with several instanced geometries it is recommended to do the culling phase prior to rendering any instanced primitives because of the following reasons:</p>
<ul>
<li>The result of the first instance cloud&#8217;s culling is more likely to be finished on the GPU so no sync issues arise from reading the asynchronous query result to determine the number of visible instances.</li>
<li>Probably less state changes are needed as very different setup is required by the two passes.</li>
<li>Results in tidier renderer design as culling is clearly separated from actual rendering.</li>
</ul>
<p>Putting everything together, the application of the presented technique would result in the following workflow on the GPU:</p>
<div id="attachment_150" class="wp-caption aligncenter" style="width: 660px"><a href="http://rastergrid.com/blog/wp-content/uploads/2010/02/icr_combined.png"><img class="size-full wp-image-150" title="Instance Cloud Reduction" src="http://rastergrid.com/blog/wp-content/uploads/2010/02/icr_combined.png" alt="Instance Cloud Reduction" width="650" height="347" /></a><p class="wp-caption-text">Instance Cloud Reduction - Combined view of Pass 1 + Pass 2</p></div>
<h3>Conclusion</h3>
<p>We&#8217;ve seen that the presented advanced rendering technique is able to help in situations when we have to deal with large number of instanced geometries and how to take advantage of the latest features of graphics cards and OpenGL to perform view frustum culling calculations on the GPU. This prevents us from having to deal with complicated and expensive CPU based object culling methods that break the drawing batches, especially when dealing with dynamic objects. For ease the decision whether to incorporate this technique in your rendering engine I would like to present the advantages and disadvantages of it.</p>
<p><strong>Advantages:</strong></p>
<ul>
<li>Heavily reduces the amount of processed data in a naive implementation.</li>
<li>No need for any space partitioning methods in the host application to handle the culling of dynamic objects.</li>
<li>Can handle huge amount of instanced objects due to the enormous horsepower of today&#8217;s GPUs.</li>
<li>Scales well with increased number of instances as the per-instance calculation is relatively low.</li>
<li>Relies strictly on OpenGL 3.2 core features.</li>
<li>No need for OpenCL capable hardware.</li>
</ul>
<p><strong>Disadvantages:</strong></p>
<ul>
<li>Needs an extra rendering pass to perform the culling.</li>
<li>Requires the usage of asynchronous queries to determine the number of visible instances.</li>
</ul>
<p>I hope you agree with me and think about this technique as one more step towards fully GPU based scene management. If you have any remarks or improvement ideas regarding to the rendering technique itself feel free to tell me.</p>
<h3>The Demo</h3>
<p>As I promised, the technique presented above comes with a live demo that actually took most of my time dedicated to writing this blog in the last two weeks. The demo itself is more like a technical show cast rather than a presentation of a real-life use case scenario.</p>
<p>First of all, I used high polygon count models for the rendering to emphasize the amount of time the culling phase spares from the very valuable time of our GPU. In a real world application one would never do something like this. As a result, the demo is more like a benchmark than an interactive application. However, maybe on high-end graphics cards it can perform pretty well.</p>
<p>The demo scene consists of two object types: trees and grass blocks. The tree model is further divided into two parts as they need different textures: the tree trunk and the tree foliage. Obviously, this additional burden can be prevented by using texture arrays to avoid the need of separate draw calls to render the trunk and the foliage.</p>
<p>The tree trunk consists of 33138 triangles, the tree foliage has 16069 triangles and the faking-free grass block consists of 8961 triangles which I had to model myself as didn&#8217;t found any suitable model. Actually this modeling step consumed quite a reasonable amount of my time spent with the demo as I&#8217;m not an expert in this domain.As you can see, these models are not the ones that one might use in an interactive real-time application like games. However, they seemed to be very suitable for the purpose of the demonstration.</p>
<p>What really kicks off the boundaries of GPUs is that the demo renders 10,000 trees and 250,000 grass blocks using instancing. This ends up in more than <strong>2.7 billion triangles</strong> in the scene. This is far more that a GPU can handle without the aid of some scene management and culling. However, we will use no scene management at all and the only culling method that we will use is the one presented in this article.</p>
<p>The actual results are quite promising. The view frustum culling step usually spares more than <strong>99.9%</strong> of the GPU horsepower as the amount of actually rendered triangles after the culling step is far below 2 million triangles. This is still quite much but as we use high polygon count models and we don&#8217;t use any LOD techniques this seems reasonable.</p>
<p>Even if the demo scene statistics doesn&#8217;t seem like a typical use case scenario, the ease of the implementation and the compelling visual results made me pleased anyway:</p>
<p style="text-align: center;"><span class="youtube">
<object width="640" height="480">
<param name="movie" value="http://www.youtube.com/v/srbOFTLTe8k?color1=3a3a3a&amp;color2=999999&amp;border=0&amp;fs=1&amp;hl=en&amp;modestbranding=1&amp;loop=&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0&amp;rel=1&amp;hd=1" />
<param name="allowFullScreen" value="true" />
<embed wmode="opaque" src="http://www.youtube.com/v/srbOFTLTe8k?color1=3a3a3a&amp;color2=999999&amp;border=0&amp;fs=1&amp;hl=en&amp;modestbranding=1&amp;loop=&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0&amp;rel=1&amp;hd=1" type="application/x-shockwave-flash" allowfullscreen="true" width="640" height="480"></embed>
<param name="wmode" value="opaque" />
</object>
</span><p><a href="http://www.youtube.com/watch?v=srbOFTLTe8k&fmt=18" onclick="pageTracker._trackPageview('/outgoing/www.youtube.com/watch?v=srbOFTLTe8k_fmt=18&amp;referer=');">www.youtube.com/watch?v=srbOFTLTe8k</a></p></p>
<p>On my Radeon HD2600XT I have achieved 6-7 frames per second which is acceptable taking in consideration the huge amount of geometry data still passed to the graphics card. On more recent cards I suppose it should run with good frame rates, however, due to the lack of hardware to test on, these are my only results. If anybody manages to take a better screen capture than mine above then please let me know.</p>
<h3>Implementation details</h3>
<p>Just to tell a few words about what techniques and tricks I&#8217;ve used during the creation of the demo here is a listing of the most important ones:</p>
<ul>
<li>Three models are used as mentioned previously with high instance counts with over 2.7 billion of total triangles in the scene as mentioned already.</li>
<li>Three 512x512 RGBA textures are used for the models that are partially handmade, and again, I&#8217;m not a texture artist so sorry if they don&#8217;t look flawless.</li>
<li>The wavefront model and TGA image loader that accompany the demo are very roughly implemented only for the demo so I would strongly encourage you not to use it to any purpose as it handles only a subset of the possibilities of the file formats.</li>
<li>The vertex data from the wavefront model files is transferred in a very naive way so vertex reuse isn&#8217;t taken into account.</li>
<li>The instance data consists of simple four-component vectors representing the world-space position of the instance. This seemed to be the most simple for the demonstration purposes.</li>
<li>In the second pass, the instance data is sourced from a texture buffer but not really because the visible instance count exceeded the amount that would fit in a uniform buffer. I used texture buffers because for this simple demonstration they seemed to be a little bit more easy to be integrated.</li>
<li>The morphing effect that simulated wind blow is done using hard-coded geometry deformation in the vertex shader. It is not physically correct but visually compelling.</li>
<li>The lighting is a simple directional light using Phong&#8217;s shading and reflection model.</li>
<li>Simple fog is simulated with some awkward formula that I&#8217;ve chosen after a few test runs.</li>
<li>Alpha testing is achieved by using the discard operation in the fragment shader.</li>
</ul>
<h3>Driver issues</h3>
<p>During the development of the demonstration program I&#8217;ve met several driver related problems as I&#8217;ve never used so heavily the latest OpenGL features previously. I&#8217;ve worked with Catalyst 9.12 and 10.1 but both seemed to lack of a proper GLSL compiler. Here are some of the issues I&#8217;ve met:</p>
<ul>
<li>When I&#8217;ve forgot to declare the varyings in the geometry shader as arrays like the standard requires then still the driver hasn&#8217;t complained about any syntax error but when tried to execute the code the program crashed.</li>
<li>Except the texture sampler uniform, all other uniforms failed to work when used in the fragment shader only so I&#8217;ve put them all in the vertex shader.</li>
<li>For loops seemed not to work when used inside the geometry shader, that&#8217;s why the culling itself is done in the vertex shader in the demo.</li>
</ul>
<p>All these problems resulted in nasty tricks to make things working and ended up in awful shader code. Sorry for that. At least now it works on my configuration but pretty unsure whether it will work on other graphics card and driver combos. Please report me any success or failure when trying out the demo. Anyway, be sure to have the latest graphics drivers installed as, at least in case of AMD, OpenGL 3.2 drivers came out only at the fall of 2009.</p>
<p><em><strong>Edit:</strong></em></p>
<p><em>Thanks to the information got from Pierre Boudier from AMD I&#8217;ve updated both the source and binary releases to support the latest drivers properly. The problem was that I didn&#8217;t use attribute location binding as specified in the standard.</em></p>
<p><em>Also have to mention that with my new Radeon HD5770 I managed to achieve over 90 frames per second that actually show that this technique can be in fact used for games and other interactive applications.</em></p>
<p><em>One more thing in the end. As you know this version of the Nature demo uses a texture buffer to source instance positions. I plan to create another version that will take advantage of the instanced arrays introduced in core with OpenGL 3.4. I expect quite a reasonable speedup as that would eliminate the need for texture fetches in the vertex array by rather dedicating a vertex fetcher for the purpose thus increasing the overall performance of the technique.</em></p>
<h3>Binary release</h3>
<p><strong>Platform:</strong> Windows<br />
<strong>Dependency:</strong> OpenGL 3.2 capable graphics driver<br />
<strong>Download link:</strong> <a href="http://rastergrid.com/blog/wp-content/uploads/2010/06/nature12_win32.zip" target="_blank">nature12_win32.zip (3.58MB)<br />
</a><strong>Comments:</strong> Includes the update that makes it work even with the latest drivers.</p>
<h3>Full source code</h3>
<p><strong>Language:</strong> C++<br />
<strong>Platform:</strong> cross-platform<br />
<strong>Dependency:</strong> GLEW, SFML, GLM<br />
<strong>Download link:</strong> <a href="http://rastergrid.com/blog/wp-content/uploads/2010/06/nature12_src.zip" target="_blank">nature12_src.zip (12.6KB)<br />
</a><strong>Comments:</strong> Sorry for the many dependencies, however, I would recommend the mentioned libraries for everybody who is doing OpenGL development.</p>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/02/instance-culling-using-geometry-shaders/feed/</wfw:commentRss>
		<slash:comments>43</slash:comments>
		</item>
		<item>
		<title>Uniform Buffers VS Texture Buffers</title>
		<link>http://rastergrid.com/blog/2010/01/uniform-buffers-vs-texture-buffers/</link>
		<comments>http://rastergrid.com/blog/2010/01/uniform-buffers-vs-texture-buffers/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 22:18:35 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[texture buffer]]></category>
		<category><![CDATA[uniform buffer]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=68</guid>
		<description><![CDATA[OpenGL 3.1 introduced two new sources from where shaders can retrieve their data, namely uniform buffers and texture buffers. These can be used to accelerate rendering when heavy usage of application provided data happens like in case of skeletal animation, especially when combined with geometry instancing. However, even if the functionality is in the core]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frastergrid.com%252Fblog%252F2010%252F01%252Funiform-buffers-vs-texture-buffers%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Uniform%20Buffers%20VS%20Texture%20Buffers%22%20%7D);"></div>
<p>OpenGL 3.1 introduced two new sources from where shaders can retrieve their data, namely uniform buffers and texture buffers. These can be used to accelerate rendering when heavy usage of application provided data happens like in case of skeletal animation, especially when combined with geometry instancing. However, even if the functionality is in the core specification for about a year now, there are few demos out there to show their usage, as so, there is a big confusion around when to use them and which one is more suitable for a particular use case.</p>
<p><span id="more-68"></span>Both AMD and NVIDIA have updated their GPU programming guides to present the latest facilities provided by both OpenGL and DirectX, however I still see that people don&#8217;t really understand how they work and that prevents them from effectively taking advantage of these features.</p>
<p>Once, at some online forum, I found somebody arguing why is this whole confusion introduced by the Khronos Group and why there is no general buffer type to use instead and the decision whether to use uniform or texture buffers should be a decision made by the driver. This particular post motivated me to write this article.</p>
<p>By the way, it seems suitable for the application to have such an abstraction, however, one should never forget that OpenGL is just a thin layer on top of any graphics capable hardware and as such, it should not hide such details that in the hand of a good programmer can provide added performance benefits.</p>
<p>When using as input to shaders, both uniform buffers and texture buffers have their strengths and weaknesses that are public to application developers, especially taking into account the detailed descriptions of each in the corresponding GPU programming guides of the vendors. It would be very difficult if not impossible for the driver to decide which particular buffer type to use based on shader source code and it would provide less flexibility to the programmer.</p>
<p>For the developer to decide which of the two should be used for a particular purpose one must investigate the characteristics of both and make the choice based on that. To ease this decision I will try to present the most important features of both. I will also talk about what I&#8217;ve used them for and what results I&#8217;ve achieved.</p>
<h2>Uniform Buffers</h2>
<p><strong>Maximum size:</strong> 64KByte (or more)<br />
<strong>Memory access pattern:</strong> coherent access<br />
<strong>Memory storage:<span style="font-weight: normal;"> usually local memory<br />
<strong>Use case examples:</strong> geometry instancing, skeletal animation, etc.</span></strong></p>
<p>Uniform buffers were introduced in OpenGL 3.1 but are available on driver implementations that don&#8217;t conform to the version 3.1 of the standard via the <a title="GL_ARB_uniform_buffer_object extension specification" href="http://www.opengl.org/registry/specs/ARB/uniform_buffer_object.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/uniform_buffer_object.txt?referer=');">GL_ARB_uniform_buffer_object</a> extension. As the specification says, uniform buffers provide a way to group GLSL uniforms into so called &#8220;uniform groups&#8221; and source their data from buffer objects to provide more streamlined access possibilities for the application.</p>
<div id="attachment_76" class="wp-caption alignleft" style="width: 138px"><a href="http://rastergrid.com/blog/wp-content/uploads/2010/01/tessellation_small.png"><img class="size-full wp-image-76      " title="Instanced tesselation using uniform buffers" src="http://rastergrid.com/blog/wp-content/uploads/2010/01/tessellation_small.png" alt="Instanced tesselation using uniform buffers" width="128" height="128" /></a><p class="wp-caption-text">Screenshot from the Instanced Tesselation demo of NVIDIA</p></div>
<p>As uniform buffers are relatively small they can easily fit in local memory. This makes data access instant thus provide optimum performance when the size constraints don&#8217;t prevent the application developer to use them. However, vendors also state that uniform buffers prefer a sequential memory access pattern. This means that it performs best when the data in the uniform buffer accesses are relative local, however, it does not necessarily mean that this sequential read must occur in one shader execution as, like in case of geometry instancing, subsequent shader executions can provide the desired access pattern.</p>
<p>Personally I use them for instanced rendering by storing the model-view matrix and related information of each and every instance in a common uniform buffer and use the instance id as an index to this combined data structure. This usage performs very well on my system.</p>
<p>Also uniform buffers can be used to store the matrices of bones and use them for implementing skeletal animation, however, I personally prefer using normal 2D textures for this purpose to take advantage of the free interpolation thanks to the dedicated texture fetching units but that&#8217;s another story.</p>
<p>Uniform buffers can also be used for other rendering techniques like skinned instancing or geometry deformation but the buffer size limitation may prevent such use case scenarios.</p>
<h2>Texture Buffers</h2>
<p><strong>Maximum size:</strong> 128MByte (or more)<br />
<strong>Memory access pattern:</strong> random access<br />
<strong>Memory storage: <span style="font-weight: normal;">global texture memory</span><br />
Use case examples:</strong> skinned instancing, geometry tesselation etc.</p>
<p>Texture buffers were also became core OpenGL in version 3.1 of the specification but are available also via the <a title="GL_ARB_texture_buffer_object extension specification" href="http://www.opengl.org/registry/specs/ARB/texture_buffer_object.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_buffer_object.txt?referer=');">GL_ARB_texture_buffer_object</a> extension (or via the <a title="GL_EXT_texture_buffer_object extension specification" href="http://www.opengl.org/registry/specs/EXT/texture_buffer_object.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/EXT/texture_buffer_object.txt?referer=');">GL_EXT_texture_buffer_object</a> extension on earlier implementations). Buffer textures are one-dimensional arrays of texels whose storage comes from an attached buffer object.</p>
<div id="attachment_77" class="wp-caption alignright" style="width: 138px"><a href="http://rastergrid.com/blog/wp-content/uploads/2010/01/texbo_small.png"><img class="size-full wp-image-77   " title="Random accessed vertex attributes using texture buffers" src="http://rastergrid.com/blog/wp-content/uploads/2010/01/texbo_small.png" alt="Random accessed vertex attributes using texture buffers" width="128" height="128" /></a><p class="wp-caption-text">Screenshot from the Simple Texture Buffer Object demo of NVIDIA</p></div>
<p>They provide the largest memory footprint for raw data access, much higher than equivalent 1D textures. However, they don&#8217;t provide texture filtering and other facilities that are usually available for other texture types. They represent formatted 1D data arrays rather than texture images. From some perspective, however, they are still textures that are resided in global memory so the access method is totally different than that of uniform buffers&#8217;. This has both advantages and disadvantages.</p>
<p>First, global texture memory access means texture fetching which involves the usage of a texture unit and possibly requires several clock cycles to complete. Anyway, thanks to the latency hiding mechanisms inside today commodity GPUs sometimes this can be as cheap as accessing uniform buffers. This part of the story is implementation dependent and is up to the hardware vendor. However, as stated in their programming guides, both AMD and NVIDIA have such latency hiding facilities and they also suggest that one should not expect a huge performance impact when using texture buffers.</p>
<p>Anyway, texture memory access provides a huge benefit compared to uniform buffers. Textures are more prone to scattered accesses and thus are more capable of dealing with random memory access. As the AMD HD2000 series programming guide says, if a certain set of data is accessed in a very random fashion it may be even faster to use texture fetches than indexed uniform access.</p>
<p>So even if texture buffers can be used in the same use case scenarios as uniform buffers, performance of either depends much more on the actual shader implementation rather than on the hardware implementation of the features.</p>
<p>Beside the aforementioned use cases, texture buffers can be used in more advanced techniques like instanced skeletal animation or even for implementing geometry tesselation, however I&#8217;m not convinced that it has any practical usage as it involves such tricks that don&#8217;t perform well on current hardware. Personally I use texture buffers for different geometry deformation techniques, to resolve batching issues when the size limitation of uniform buffers is a blocking factor, and for some inverse kinematics effects.</p>
<h2>Conclusion</h2>
<p>By the way, from now it&#8217;s your task to draw a conclusion based on the information read here but I recommend to read the mentioned programming guides to see a more accurate presentation of both methods. My personal conclusion is that there is no ultimate choice as both buffer types serve different purposes. Even if their possible use cases overlap, there are plenty of rendering techniques that would take advantage of the benefits of one but would suffer from the disadvantages of the other.</p>
<p>For further details on the topic, please refer to the <a href="http://www.opengl.org/registry/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/?referer=');">OpenGL extension registry</a> and the vendor supplied GPU programming guides:</p>
<ul>
<li>AMD&#8217;s ATI Radeon HD2000 programming guide: <a href="http://developer.amd.com/media/gpu_assets/ATI_Radeon_HD_2000_programming_guide.pdf" target="_blank" onclick="pageTracker._trackPageview('/outgoing/developer.amd.com/media/gpu_assets/ATI_Radeon_HD_2000_programming_guide.pdf?referer=');">http://developer.amd.com/media/gpu_assets/ATI_Radeon_HD_2000_programming_guide.pdf</a></li>
<li>NVIDIA&#8217;s G80 GPU programming guide: <a href="http://developer.download.nvidia.com/GPU_Programming_Guide/GPU_Programming_Guide_G80.pdf" target="_blank" onclick="pageTracker._trackPageview('/outgoing/developer.download.nvidia.com/GPU_Programming_Guide/GPU_Programming_Guide_G80.pdf?referer=');">http://developer.download.nvidia.com/GPU_Programming_Guide/GPU_Programming_Guide_G80.pdf</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/01/uniform-buffers-vs-texture-buffers/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

