<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-11077412</id><updated>2013-04-18T02:24:53.705+01:00</updated><category term='Python'/><category term='ApiTrace'/><category term='gprof2dot'/><category term='neverball'/><category term='Debian'/><category term='ipod'/><category term='SSE2'/><category term='D3D'/><category term='Eclipse'/><category term='pow'/><category term='Mesa'/><category term='Gallium3D'/><category term='DRI'/><category term='tracing'/><category term='recursion'/><category term='profile'/><title type='text'>José Fonseca's Tech blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>22</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-11077412.post-1317674020533490577</id><published>2012-09-25T19:13:00.000+01:00</published><updated>2012-09-26T09:33:15.464+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ApiTrace'/><title type='text'>Profiling OpenGL applications with ApiTrace</title><content type='html'>During the last 6 months I had the pleasure of supervising James Benton at VMware, for his industrial placement that is part of his course at Imperial College London.&lt;br /&gt;
&lt;br /&gt;
Among other things, he added to support to ApiTrace for GPU profiling of OpenGL traces, and visualize both the captured GPU/CPU profiling results.&lt;br /&gt;
&lt;br /&gt;
Visualization currently consists of a timeline showing calls start CPU/GPU time and durations, where GPU timings are grouped by the GLSL program bound:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-Yi4ZhW6DFpY/UGHg3yOy-MI/AAAAAAAAAGI/7cgslg1ze9w/s1600/profile.timeline.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="293" src="http://3.bp.blogspot.com/-Yi4ZhW6DFpY/UGHg3yOy-MI/AAAAAAAAAGI/7cgslg1ze9w/s400/profile.timeline.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
And a histogram showing GPU/CPU durations for each call:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-OHN7Zy_iVqA/UGHg3RJCM2I/AAAAAAAAAGA/S-x6sqZTKcM/s1600/profile.histogram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="291" src="http://4.bp.blogspot.com/-OHN7Zy_iVqA/UGHg3RJCM2I/AAAAAAAAAGA/S-x6sqZTKcM/s400/profile.histogram.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
The interface was slightly retrouched since this screen-shots were taken.&lt;br /&gt;
&lt;br /&gt;
Much more can be done (especially with cooperation from OpenGL driver developers to expose more GPU counters to OpenGL applications), but we are confident this new feature already can be quite handy for those looking for improving performance of their OpenGL applications.&lt;br /&gt;
&lt;br /&gt;
James also&amp;nbsp;designed&amp;nbsp;a&amp;nbsp;&lt;a href="http://apitrace.github.com/" target="_blank"&gt;new homepage for ApiTrace&lt;/a&gt;&amp;nbsp;on GitHub Pages. Please update your bookmarks!</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/1317674020533490577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=1317674020533490577' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/1317674020533490577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/1317674020533490577'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2012/09/profiling-opengl-applications-with.html' title='Profiling OpenGL applications with ApiTrace'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-Yi4ZhW6DFpY/UGHg3yOy-MI/AAAAAAAAAGI/7cgslg1ze9w/s72-c/profile.timeline.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-7919435407637989898</id><published>2012-03-10T10:57:00.005Z</published><updated>2012-03-10T12:08:26.060Z</updated><title type='text'>ApiTrace 3.0</title><content type='html'>&lt;p&gt;The Apitrace project came a long way since the &lt;a href="http://jrfonseca.blogspot.com/2008/07/tracing-d3d-applications.html"&gt;first and last time I wrote about it here&lt;/a&gt;. One obvious reason is that I don't blog much (has it really been four years already!?). But the main reason is that this project received love from a lot of people since then, gaining features I could never dream of.&lt;/p&gt;

&lt;p&gt;First, Zack Rusin &lt;a href="http://zrusin.blogspot.com/2011/04/apitrace.html"&gt;implemented an awesome GUI&lt;/a&gt; and &lt;a href="http://zrusin.blogspot.com/2011/09/apitrace-20.html"&gt;made writing/reading huge traces blazing fast&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, Carl Worth from &lt;a href="http://intellinuxgraphics.org/"&gt;Intel Linux Graphics Driver team&lt;/a&gt; implemented a top-level command, replacing the assortment of programs and scripts of with an unified command line interface, in the same spirit as &lt;i&gt;git&lt;/i&gt; or Linux &lt;i&gt;perf&lt;/i&gt; tool.  He also added ability to trim traces, and is working on automatically trimming traces.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.lunarg.com/"&gt;LunarG&lt;/a&gt; is developing several &lt;a href="http://www.lunarg.com/see-me-gaming/"&gt;services based on Apitrace for GLES on Android&lt;/a&gt; and Chia-I Wu contributed back trace and retrace support for EGL, GLES1, and GLES2 APIs on Linux. Alexandros Frantzis from &lt;a href="http://www.linaro.org/"&gt;Linaro&lt;/a&gt; and Arnaud Vrac improved portability for embedded Linux platforms.&lt;/p&gt;

&lt;p&gt;More goodies are bound to come soon, so stay tuned... to the &lt;a href="https://github.com/apitrace/apitrace"&gt;github repository&lt;/a&gt;, not this blog! ;-)&lt;/p&gt;</content><link rel='related' href='http://lists.freedesktop.org/archives/apitrace/2012-March/000222.html' title='ApiTrace 3.0'/><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/7919435407637989898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=7919435407637989898' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/7919435407637989898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/7919435407637989898'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2012/03/apitrace-30.html' title='ApiTrace 3.0'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-715001276780021031</id><published>2008-09-28T12:00:00.005+01:00</published><updated>2008-09-28T13:22:22.780+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Gallium3D'/><category scheme='http://www.blogger.com/atom/ns#' term='pow'/><category scheme='http://www.blogger.com/atom/ns#' term='SSE2'/><title type='text'>Fast SSE2 pow: tables or polynomials?</title><content type='html'>&lt;p&gt;We found that for many applications a substantial part of the time spent in software vertex processing was being spend in the powf function. So quite a few of us in Tungsten Graphics have been looking into a faster powf.&lt;/p&gt;

&lt;h2&gt;Introduction&lt;/h2&gt;

&lt;p&gt;The basic way to compute powf(x, y) efficiently is by computing the equivalent exp2(log2(x)*y)) expression, and then fiddle with &lt;a href="http://en.wikipedia.org/wiki/IEEE_754"&gt;IEEE 754&lt;/a&gt; floating point exponent to quickly estimate the log2/exp2. This by itself only gives a very coarse approximation. To improve this approximation one has to also look into the mantissa, and then take one of two alternatives: use a lookup table or fit a function like a polynomial.&lt;/p&gt;

&lt;h2&gt;Lookup table&lt;/h2&gt;

&lt;p&gt;See also:&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.hxa7241.org/articles/content/fast-pow-adjustable_hxa7241_2007.html"&gt;Fast pow() With Adjustable Accuracy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.icsi.berkeley.edu/cgi-bin/pubs/publication.pl?ID=002209"&gt;A fast logarithm implementation
with adjustable accuracy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;exp2&lt;/h3&gt;

&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;union&lt;/font&gt;&lt;/b&gt; f4 &lt;font color="#FF0000"&gt;{&lt;/font&gt;
   int32_t i&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;4&lt;/font&gt;&lt;font color="#990000"&gt;];&lt;/font&gt;
   uint32_t u&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;4&lt;/font&gt;&lt;font color="#990000"&gt;];&lt;/font&gt;
   &lt;font color="#009900"&gt;float&lt;/font&gt; f&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;4&lt;/font&gt;&lt;font color="#990000"&gt;];&lt;/font&gt;
   __m128 m&lt;font color="#990000"&gt;;&lt;/font&gt;
   __m128i mi&lt;font color="#990000"&gt;;&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;

&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; EXP2_TABLE_SIZE_LOG2 &lt;font color="#993399"&gt;9&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;EXP2_TABLE_SIZE &lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt; &lt;font color="#990000"&gt;&amp;lt;&amp;lt;&lt;/font&gt; EXP2_TABLE_SIZE_LOG2&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;EXP2_TABLE_OFFSET &lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;EXP2_TABLE_SIZE&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;EXP2_TABLE_SCALE &lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;((&lt;/font&gt;&lt;font color="#009900"&gt;float&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#990000"&gt;((&lt;/font&gt;EXP2_TABLE_SIZE&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;)-&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;))&lt;/font&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;/* 2 ^ x, for x in [-1.0, 1.0[ */&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;static&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;float&lt;/font&gt; exp2_table&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;*&lt;/font&gt;EXP2_TABLE_SIZE&lt;font color="#990000"&gt;];&lt;/font&gt;

&lt;font color="#009900"&gt;void&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;exp2_init&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#009900"&gt;void&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;font color="#FF0000"&gt;{&lt;/font&gt;
   &lt;font color="#009900"&gt;int&lt;/font&gt; i&lt;font color="#990000"&gt;;&lt;/font&gt;
   &lt;b&gt;&lt;font color="#0000FF"&gt;for&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;i &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; i &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt; EXP2_TABLE_SIZE&lt;font color="#990000"&gt;;&lt;/font&gt; i&lt;font color="#990000"&gt;++)&lt;/font&gt;
      exp2_table&lt;font color="#990000"&gt;[&lt;/font&gt;i&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#009900"&gt;float&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;pow&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;2.0&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;i &lt;font color="#990000"&gt;-&lt;/font&gt; EXP2_TABLE_OFFSET&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#990000"&gt;/&lt;/font&gt; EXP2_TABLE_SCALE&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;/**&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt; * Fast approximation to exp2(x).&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt; * Let ipart = int(x)&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt; * Let fpart = x - ipart;&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt; * So, exp2(x) = exp2(ipart) * exp2(fpart)&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt; * Compute exp2(ipart) with i &amp;lt;&amp;lt; ipart&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt; * Compute exp2(fpart) with lookup table.&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt; */&lt;/font&gt;&lt;/i&gt;
__m128
&lt;b&gt;&lt;font color="#000000"&gt;exp2f4&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;__m128 x&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;font color="#FF0000"&gt;{&lt;/font&gt;
   __m128i ipart&lt;font color="#990000"&gt;;&lt;/font&gt;
   __m128 fpart&lt;font color="#990000"&gt;,&lt;/font&gt; expipart&lt;font color="#990000"&gt;;&lt;/font&gt;
   &lt;b&gt;&lt;font color="#0000FF"&gt;union&lt;/font&gt;&lt;/b&gt; f4 index&lt;font color="#990000"&gt;,&lt;/font&gt; expfpart&lt;font color="#990000"&gt;;&lt;/font&gt;

   x &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_min_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt; &lt;font color="#993399"&gt;129&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;00000f&lt;font color="#990000"&gt;));&lt;/font&gt;
   x &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_max_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(-&lt;/font&gt;&lt;font color="#993399"&gt;126&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;99999f&lt;font color="#990000"&gt;));&lt;/font&gt;

   &lt;i&gt;&lt;font color="#9A1900"&gt;/* ipart = int(x) */&lt;/font&gt;&lt;/i&gt;
   ipart &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_cvtps_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;);&lt;/font&gt;

   &lt;i&gt;&lt;font color="#9A1900"&gt;/* fpart = x - ipart */&lt;/font&gt;&lt;/i&gt;
   fpart &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_sub_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_cvtepi32_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;ipart&lt;font color="#990000"&gt;));&lt;/font&gt;

   &lt;i&gt;&lt;font color="#9A1900"&gt;/* expipart = (float) (1 &amp;lt;&amp;lt; ipart) */&lt;/font&gt;&lt;/i&gt;
   expipart &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_castsi128_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_slli_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_add_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;ipart&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;127&lt;/font&gt;&lt;font color="#990000"&gt;)),&lt;/font&gt; &lt;font color="#993399"&gt;23&lt;/font&gt;&lt;font color="#990000"&gt;));&lt;/font&gt;

   &lt;i&gt;&lt;font color="#9A1900"&gt;/* index = EXP2_TABLE_OFFSET + (int)(fpart * EXP2_TABLE_SCALE) */&lt;/font&gt;&lt;/i&gt;
   index&lt;font color="#990000"&gt;.&lt;/font&gt;mi &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_add_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_cvtps_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_mul_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;fpart&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;EXP2_TABLE_SCALE&lt;font color="#990000"&gt;))),&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;EXP2_TABLE_OFFSET&lt;font color="#990000"&gt;));&lt;/font&gt;

   expfpart&lt;font color="#990000"&gt;.&lt;/font&gt;f&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; exp2_table&lt;font color="#990000"&gt;[&lt;/font&gt;index&lt;font color="#990000"&gt;.&lt;/font&gt;u&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]];&lt;/font&gt;
   expfpart&lt;font color="#990000"&gt;.&lt;/font&gt;f&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; exp2_table&lt;font color="#990000"&gt;[&lt;/font&gt;index&lt;font color="#990000"&gt;.&lt;/font&gt;u&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;]];&lt;/font&gt;
   expfpart&lt;font color="#990000"&gt;.&lt;/font&gt;f&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; exp2_table&lt;font color="#990000"&gt;[&lt;/font&gt;index&lt;font color="#990000"&gt;.&lt;/font&gt;u&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;]];&lt;/font&gt;
   expfpart&lt;font color="#990000"&gt;.&lt;/font&gt;f&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; exp2_table&lt;font color="#990000"&gt;[&lt;/font&gt;index&lt;font color="#990000"&gt;.&lt;/font&gt;u&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;]];&lt;/font&gt;

   &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_mul_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;expipart&lt;font color="#990000"&gt;,&lt;/font&gt; expfpart&lt;font color="#990000"&gt;.&lt;/font&gt;m&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;

&lt;h3&gt;log2&lt;/h3&gt;

&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; LOG2_TABLE_SIZE_LOG2 &lt;font color="#993399"&gt;8&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;LOG2_TABLE_SIZE &lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt; &lt;font color="#990000"&gt;&amp;lt;&amp;lt;&lt;/font&gt; LOG2_TABLE_SIZE_LOG2&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;LOG2_TABLE_SCALE &lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;((&lt;/font&gt;&lt;font color="#009900"&gt;float&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#990000"&gt;((&lt;/font&gt;LOG2_TABLE_SIZE&lt;font color="#990000"&gt;)-&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;))&lt;/font&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;/* log2(x), for x in [1.0, 2.0[ */&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;static&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;float&lt;/font&gt; log2_table&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;*&lt;/font&gt;LOG2_TABLE_SIZE&lt;font color="#990000"&gt;];&lt;/font&gt;

&lt;font color="#009900"&gt;void&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;log2_init&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#009900"&gt;void&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;font color="#FF0000"&gt;{&lt;/font&gt;
   &lt;font color="#009900"&gt;unsigned&lt;/font&gt; i&lt;font color="#990000"&gt;;&lt;/font&gt;
   &lt;b&gt;&lt;font color="#0000FF"&gt;for&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;i &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; i &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt; LOG2_TABLE_SIZE&lt;font color="#990000"&gt;;&lt;/font&gt; i&lt;font color="#990000"&gt;++)&lt;/font&gt;
      log2_table&lt;font color="#990000"&gt;[&lt;/font&gt;i&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#009900"&gt;float&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;log2&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;1.0&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt; i &lt;font color="#990000"&gt;*&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;1.0&lt;/font&gt; &lt;font color="#990000"&gt;/&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;LOG2_TABLE_SIZE&lt;font color="#990000"&gt;-&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;)));&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;

__m128
&lt;b&gt;&lt;font color="#000000"&gt;log2f4&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;__m128 x&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;font color="#FF0000"&gt;{&lt;/font&gt;
   &lt;b&gt;&lt;font color="#0000FF"&gt;union&lt;/font&gt;&lt;/b&gt; f4 index&lt;font color="#990000"&gt;,&lt;/font&gt; p&lt;font color="#990000"&gt;;&lt;/font&gt;

   __m128i exp &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;0x7F800000&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
   __m128i mant &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;0x007FFFFF&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;

   __m128i i &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_castps_si128&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;);&lt;/font&gt;

   __m128 e &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_cvtepi32_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_sub_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_srli_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_and_si128&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;i&lt;font color="#990000"&gt;,&lt;/font&gt; exp&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;font color="#993399"&gt;23&lt;/font&gt;&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;127&lt;/font&gt;&lt;font color="#990000"&gt;)));&lt;/font&gt;

   index&lt;font color="#990000"&gt;.&lt;/font&gt;mi &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_srli_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_and_si128&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;i&lt;font color="#990000"&gt;,&lt;/font&gt; mant&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;font color="#993399"&gt;23&lt;/font&gt; &lt;font color="#990000"&gt;-&lt;/font&gt; LOG2_TABLE_SIZE_LOG2&lt;font color="#990000"&gt;);&lt;/font&gt;

   p&lt;font color="#990000"&gt;.&lt;/font&gt;f&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; log2_table&lt;font color="#990000"&gt;[&lt;/font&gt;index&lt;font color="#990000"&gt;.&lt;/font&gt;u&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]];&lt;/font&gt;
   p&lt;font color="#990000"&gt;.&lt;/font&gt;f&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; log2_table&lt;font color="#990000"&gt;[&lt;/font&gt;index&lt;font color="#990000"&gt;.&lt;/font&gt;u&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;]];&lt;/font&gt;
   p&lt;font color="#990000"&gt;.&lt;/font&gt;f&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; log2_table&lt;font color="#990000"&gt;[&lt;/font&gt;index&lt;font color="#990000"&gt;.&lt;/font&gt;u&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;]];&lt;/font&gt;
   p&lt;font color="#990000"&gt;.&lt;/font&gt;f&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; log2_table&lt;font color="#990000"&gt;[&lt;/font&gt;index&lt;font color="#990000"&gt;.&lt;/font&gt;u&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;]];&lt;/font&gt;

   &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_add_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;p&lt;font color="#990000"&gt;.&lt;/font&gt;m&lt;font color="#990000"&gt;,&lt;/font&gt; e&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;


&lt;h3&gt;pow&lt;/h3&gt;

&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;static&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;inline&lt;/font&gt;&lt;/b&gt; __m128
&lt;b&gt;&lt;font color="#000000"&gt;powf4&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;__m128 x&lt;font color="#990000"&gt;,&lt;/font&gt; __m128 y&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;font color="#FF0000"&gt;{&lt;/font&gt;
   &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;exp2f4&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_mul_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;log2f4&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;),&lt;/font&gt; y&lt;font color="#990000"&gt;));&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;

&lt;h2&gt;Polynomial&lt;/h2&gt;

&lt;p&gt;For more details see:&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;Posts from Nick from Ghent, Belgium in &lt;a href="http://www.devmaster.net/forums/showthread.php?p=43580"&gt;Approximate Math Library&lt;/a&gt; thread.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.boost.org/doc/libs/1_36_0/libs/math/doc/sf_and_dist/html/math_toolkit/toolkit/internals2/minimax.html"&gt;Minimax Approximations and the Remez Algorithm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;exp2&lt;/h3&gt;

&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; EXP_POLY_DEGREE &lt;font color="#993399"&gt;3&lt;/font&gt;

&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;POLY0&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; c0&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;c0&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;POLY1&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; c0&lt;font color="#990000"&gt;,&lt;/font&gt; c1&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_add_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_mul_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;POLY0&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; c1&lt;font color="#990000"&gt;),&lt;/font&gt; x&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;c0&lt;font color="#990000"&gt;))&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;POLY2&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; c0&lt;font color="#990000"&gt;,&lt;/font&gt; c1&lt;font color="#990000"&gt;,&lt;/font&gt; c2&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_add_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_mul_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;POLY1&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; c1&lt;font color="#990000"&gt;,&lt;/font&gt; c2&lt;font color="#990000"&gt;),&lt;/font&gt; x&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;c0&lt;font color="#990000"&gt;))&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;POLY3&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; c0&lt;font color="#990000"&gt;,&lt;/font&gt; c1&lt;font color="#990000"&gt;,&lt;/font&gt; c2&lt;font color="#990000"&gt;,&lt;/font&gt; c3&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_add_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_mul_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;POLY2&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; c1&lt;font color="#990000"&gt;,&lt;/font&gt; c2&lt;font color="#990000"&gt;,&lt;/font&gt; c3&lt;font color="#990000"&gt;),&lt;/font&gt; x&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;c0&lt;font color="#990000"&gt;))&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;POLY4&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; c0&lt;font color="#990000"&gt;,&lt;/font&gt; c1&lt;font color="#990000"&gt;,&lt;/font&gt; c2&lt;font color="#990000"&gt;,&lt;/font&gt; c3&lt;font color="#990000"&gt;,&lt;/font&gt; c4&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_add_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_mul_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;POLY3&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; c1&lt;font color="#990000"&gt;,&lt;/font&gt; c2&lt;font color="#990000"&gt;,&lt;/font&gt; c3&lt;font color="#990000"&gt;,&lt;/font&gt; c4&lt;font color="#990000"&gt;),&lt;/font&gt; x&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;c0&lt;font color="#990000"&gt;))&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;POLY5&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; c0&lt;font color="#990000"&gt;,&lt;/font&gt; c1&lt;font color="#990000"&gt;,&lt;/font&gt; c2&lt;font color="#990000"&gt;,&lt;/font&gt; c3&lt;font color="#990000"&gt;,&lt;/font&gt; c4&lt;font color="#990000"&gt;,&lt;/font&gt; c5&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_add_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_mul_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;POLY4&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; c1&lt;font color="#990000"&gt;,&lt;/font&gt; c2&lt;font color="#990000"&gt;,&lt;/font&gt; c3&lt;font color="#990000"&gt;,&lt;/font&gt; c4&lt;font color="#990000"&gt;,&lt;/font&gt; c5&lt;font color="#990000"&gt;),&lt;/font&gt; x&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;c0&lt;font color="#990000"&gt;))&lt;/font&gt;

__m128 &lt;b&gt;&lt;font color="#000000"&gt;exp2f4&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;__m128 x&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;font color="#FF0000"&gt;{&lt;/font&gt;
   __m128i ipart&lt;font color="#990000"&gt;;&lt;/font&gt;
   __m128 fpart&lt;font color="#990000"&gt;,&lt;/font&gt; expipart&lt;font color="#990000"&gt;,&lt;/font&gt; expfpart&lt;font color="#990000"&gt;;&lt;/font&gt;

   x &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_min_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt; &lt;font color="#993399"&gt;129&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;00000f&lt;font color="#990000"&gt;));&lt;/font&gt;
   x &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_max_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(-&lt;/font&gt;&lt;font color="#993399"&gt;126&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;99999f&lt;font color="#990000"&gt;));&lt;/font&gt;

   &lt;i&gt;&lt;font color="#9A1900"&gt;/* ipart = int(x - 0.5) */&lt;/font&gt;&lt;/i&gt;
   ipart &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_cvtps_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_sub_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;5f&lt;font color="#990000"&gt;)));&lt;/font&gt;

   &lt;i&gt;&lt;font color="#9A1900"&gt;/* fpart = x - ipart */&lt;/font&gt;&lt;/i&gt;
   fpart &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_sub_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_cvtepi32_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;ipart&lt;font color="#990000"&gt;));&lt;/font&gt;

   &lt;i&gt;&lt;font color="#9A1900"&gt;/* expipart = (float) (1 &amp;lt;&amp;lt; ipart) */&lt;/font&gt;&lt;/i&gt;
   expipart &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_castsi128_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_slli_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_add_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;ipart&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;127&lt;/font&gt;&lt;font color="#990000"&gt;)),&lt;/font&gt; &lt;font color="#993399"&gt;23&lt;/font&gt;&lt;font color="#990000"&gt;));&lt;/font&gt;

   &lt;i&gt;&lt;font color="#9A1900"&gt;/* minimax polynomial fit of 2**x, in range [-0.5, 0.5[ */&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#if&lt;/font&gt;&lt;/b&gt; EXP_POLY_DEGREE &lt;font color="#990000"&gt;==&lt;/font&gt; &lt;font color="#993399"&gt;5&lt;/font&gt;
   expfpart &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;POLY5&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;fpart&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;9&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;9999994e&lt;font color="#990000"&gt;-&lt;/font&gt;1f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;6&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;9315308e&lt;font color="#990000"&gt;-&lt;/font&gt;1f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;4015361e&lt;font color="#990000"&gt;-&lt;/font&gt;1f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;5&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;5826318e&lt;font color="#990000"&gt;-&lt;/font&gt;2f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;8&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;9893397e&lt;font color="#990000"&gt;-&lt;/font&gt;3f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;8775767e&lt;font color="#990000"&gt;-&lt;/font&gt;3f&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#elif&lt;/font&gt;&lt;/b&gt; EXP_POLY_DEGREE &lt;font color="#990000"&gt;==&lt;/font&gt; &lt;font color="#993399"&gt;4&lt;/font&gt;
   expfpart &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;POLY4&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;fpart&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;0000026f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;6&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;9300383e&lt;font color="#990000"&gt;-&lt;/font&gt;1f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;4144275e&lt;font color="#990000"&gt;-&lt;/font&gt;1f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;5&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;2011464e&lt;font color="#990000"&gt;-&lt;/font&gt;2f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;3534167e&lt;font color="#990000"&gt;-&lt;/font&gt;2f&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#elif&lt;/font&gt;&lt;/b&gt; EXP_POLY_DEGREE &lt;font color="#990000"&gt;==&lt;/font&gt; &lt;font color="#993399"&gt;3&lt;/font&gt;
   expfpart &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;POLY3&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;fpart&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;9&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;9992520e&lt;font color="#990000"&gt;-&lt;/font&gt;1f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;6&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;9583356e&lt;font color="#990000"&gt;-&lt;/font&gt;1f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;2606716e&lt;font color="#990000"&gt;-&lt;/font&gt;1f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;7&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;8024521e&lt;font color="#990000"&gt;-&lt;/font&gt;2f&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#elif&lt;/font&gt;&lt;/b&gt; EXP_POLY_DEGREE &lt;font color="#990000"&gt;==&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;
   expfpart &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;POLY2&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;fpart&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;0017247f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;6&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;5763628e&lt;font color="#990000"&gt;-&lt;/font&gt;1f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;3718944e&lt;font color="#990000"&gt;-&lt;/font&gt;1f&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#else&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#error&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#endif&lt;/font&gt;&lt;/b&gt;

   &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_mul_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;expipart&lt;font color="#990000"&gt;,&lt;/font&gt; expfpart&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;

&lt;h3&gt;log2&lt;/h3&gt;

&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#000080"&gt;#define&lt;/font&gt;&lt;/b&gt; LOG_POLY_DEGREE &lt;font color="#993399"&gt;5&lt;/font&gt;

__m128 &lt;b&gt;&lt;font color="#000000"&gt;log2f4&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;__m128 x&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;font color="#FF0000"&gt;{&lt;/font&gt;
   __m128i exp &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;0x7F800000&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
   __m128i mant &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;0x007FFFFF&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;

   __m128 one &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;0f&lt;font color="#990000"&gt;);&lt;/font&gt;

   __m128i i &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_castps_si128&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;);&lt;/font&gt;

   __m128 e &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_cvtepi32_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_sub_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_srli_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_and_si128&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;i&lt;font color="#990000"&gt;,&lt;/font&gt; exp&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;font color="#993399"&gt;23&lt;/font&gt;&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_set1_epi32&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;127&lt;/font&gt;&lt;font color="#990000"&gt;)));&lt;/font&gt;

   __m128 m &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_or_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_castsi128_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;_mm_and_si128&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;i&lt;font color="#990000"&gt;,&lt;/font&gt; mant&lt;font color="#990000"&gt;)),&lt;/font&gt; one&lt;font color="#990000"&gt;);&lt;/font&gt;

   __m128 p&lt;font color="#990000"&gt;;&lt;/font&gt;

   &lt;i&gt;&lt;font color="#9A1900"&gt;/* Minimax polynomial fit of log2(x)/(x - 1), for x in range [1, 2[ */&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#if&lt;/font&gt;&lt;/b&gt; LOG_POLY_DEGREE &lt;font color="#990000"&gt;==&lt;/font&gt; &lt;font color="#993399"&gt;6&lt;/font&gt;
   p &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;POLY5&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt; m&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;1157899f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;-&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;3241990f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;5988452f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;-&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;2315303f&lt;font color="#990000"&gt;,&lt;/font&gt;  &lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;1821337e&lt;font color="#990000"&gt;-&lt;/font&gt;1f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;-&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;4436006e&lt;font color="#990000"&gt;-&lt;/font&gt;2f&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#elif&lt;/font&gt;&lt;/b&gt; LOG_POLY_DEGREE &lt;font color="#990000"&gt;==&lt;/font&gt; &lt;font color="#993399"&gt;5&lt;/font&gt;
   p &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;POLY4&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;m&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;8882704548164776201f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;-&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;52074962577807006663f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;48116647521213171641f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;-&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;465725644288844778798f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;0596515482674574969533f&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#elif&lt;/font&gt;&lt;/b&gt; LOG_POLY_DEGREE &lt;font color="#990000"&gt;==&lt;/font&gt; &lt;font color="#993399"&gt;4&lt;/font&gt;
   p &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;POLY3&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;m&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;61761038894603480148f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;-&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;75647175389045657003f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;688243882994381274313f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;-&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;107254423828329604454f&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#elif&lt;/font&gt;&lt;/b&gt; LOG_POLY_DEGREE &lt;font color="#990000"&gt;==&lt;/font&gt; &lt;font color="#993399"&gt;3&lt;/font&gt;
   p &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;POLY2&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;m&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;28330284476918490682f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;-&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;04913055217340124191f&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;204446009836232697516f&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#else&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#error&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#000080"&gt;#endif&lt;/font&gt;&lt;/b&gt;

   &lt;i&gt;&lt;font color="#9A1900"&gt;/* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/&lt;/font&gt;&lt;/i&gt;
   p &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_mul_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;p&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_sub_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;m&lt;font color="#990000"&gt;,&lt;/font&gt; one&lt;font color="#990000"&gt;));&lt;/font&gt;

   &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;_mm_add_ps&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;p&lt;font color="#990000"&gt;,&lt;/font&gt; e&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;

&lt;h2&gt;Results&lt;/h2&gt;

&lt;p&gt;The accuracy vs speed for several table sizes and
polynomial degrees can be seen in the chart below.&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_siK-uBftJ9E/SN9u0hKLWzI/AAAAAAAAAEI/iucDWORa7lI/s1600-h/results.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_siK-uBftJ9E/SN9u0hKLWzI/AAAAAAAAAEI/iucDWORa7lI/s800/results.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5251037539070597938" /&gt;&lt;/a&gt;

&lt;p&gt;The difference is not much, but the polynomial approach outperforms
the table approach for any desired precision. This was for 32bit
generated code in a Core 2. If generating 64bit code, the difference
between the two is bigger. The performance of the table approach will
also tend to degrade when other computation is going on at the same
time, as the likelihood the lookup tables get trashed out of the cache
is higher. So by all accounts, the polynomial approach seems a safer
bet.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/715001276780021031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=715001276780021031' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/715001276780021031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/715001276780021031'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html' title='Fast SSE2 pow: tables or polynomials?'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_siK-uBftJ9E/SN9u0hKLWzI/AAAAAAAAAEI/iucDWORa7lI/s72-c/results.png' height='72' width='72'/><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-8702550179217269394</id><published>2008-09-13T06:37:00.004+01:00</published><updated>2008-09-13T09:14:36.996+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Gallium3D'/><category scheme='http://www.blogger.com/atom/ns#' term='tracing'/><title type='text'>Tracing Gallium3D</title><content type='html'>&lt;p&gt;One nice thing about &lt;a href="http://jrfonseca.blogspot.com/2008/04/gallium3d-introduction.html"&gt;Gallium3D&lt;/a&gt; is that it provides a clean cut abstraction of (modern) 3D graphics hardware. The purpose of this abstraction is to allow a single hardware driver to target different graphic APIs (OpenGL, D3D, etc.). That is, one &lt;i&gt;pipe driver&lt;/i&gt; for many &lt;i&gt;state trackers&lt;/i&gt;.&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_siK-uBftJ9E/SBQJu-vVTJI/AAAAAAAAAB0/cfOtk3KJHGg/s1600-h/module_dataflow.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_siK-uBftJ9E/SBQJu-vVTJI/AAAAAAAAAB0/cfOtk3KJHGg/s1600/module_dataflow.png" alt="" id="BLOGGER_PHOTO_ID_5193786972985183378" border="0" /&gt;&lt;/a&gt;

&lt;p&gt;But with this abstraction in place it opens the doors to other interesting things, unthinkable until now. Namely, by intercepting the calls between the state tracker and the pipe driver one could:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;in a debugging scenario, capture the calls of an application known to cause problems to a file and analyze it, replay it in order to isolate the bug;&lt;/li&gt;
&lt;li&gt;in a virtual machine scenario, capture all calls done inside a virtual machine and replay them in the host machine;&lt;/li&gt;
&lt;li&gt;in a performance analysis scenario, compute memory/performance statistics in a per-call/resource;&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having an itch to scratch I started tackling the former, i.e., &lt;i&gt;tracing Gallium3D for debugging purposes&lt;/i&gt;. Actually, an &lt;i&gt;itch&lt;/i&gt; is an understatement, it is a rash named XP Direct3D. XP Direct3D driver model is in kernel space, and the build -&gt; reboot -&gt; upload driver -&gt; test application cycle takes me between 5 and 10 min depending of the application. While in Linux building and testing from a NFS share takes me less than 1min. Recording a D3D application in XP and replay and debugging it on Linux would boost my productivity by 5 to 10 times. This assuming that the bug is on the pipe driver and not on the state tracker, which tends to be the case now that our state trackers are quite mature.&lt;/p&gt;

&lt;p&gt;Using the learned lessons from my &lt;a href="http://jrfonseca.blogspot.com/2008/07/tracing-d3d-applications.html"&gt;previous experiment of tracing D3D applications&lt;/a&gt; I wrote a pipe driver which traces all state tracker -&gt; pipe driver interface calls to a XML file, and after an application written in Python to replay that file (using the &lt;a href="http://jrfonseca.blogspot.com/2008/09/learning-and-testing-gallium3d-with.html"&gt;Gallium3D Python bindings&lt;/a&gt;).&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_siK-uBftJ9E/SMttfZTkWPI/AAAAAAAAADw/pNfyNIwJgOQ/s1600-h/trace_dataflow.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_siK-uBftJ9E/SMttfZTkWPI/AAAAAAAAADw/pNfyNIwJgOQ/s1600/trace_dataflow.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5245406577139407090" /&gt;&lt;/a&gt;

&lt;p&gt;I chose a semantically rich XML as trace format so that the trace
dumps are cross-platform and can at least survive minor interface
changes such as addition/removal of state objects members, format
renumbering, etc. This way traces can be also used for regression testing. Nevertheless the code is structured in such way that
a space-efficient binary format is also possible in the future with
minor changes.&lt;/p&gt;

&lt;p&gt;Here is softpipe replaying a trace captured from trace of Mesa's gloss demo (also recorded on Linux).&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_siK-uBftJ9E/SMtvbzfW6vI/AAAAAAAAAD4/fDrgkic75ZI/s1600-h/retrace-gloss.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_siK-uBftJ9E/SMtvbzfW6vI/AAAAAAAAAD4/fDrgkic75ZI/s320/retrace-gloss.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5245408714471959282" /&gt;&lt;/a&gt;

&lt;p&gt;Simple apps are capture/replayed (e.g., progs/trivial/*, progs/demos/gloss, and many D3D DirectX SDK examples), but big applications like 3DMark05 produce over 10GB of trace data before reaching the first frame, and I run out of disk space or patience before that. Also, some minor glitches in the interfaces prevent are causing some state to leak behind our back. So the next steps are to allow to capture a single arbitrary frame, improve trace format space efficiency, and trim the interface corners.&lt;/p&gt;

&lt;p&gt;In case anybody gets interested, there are several README files in Mesa's git explaining how to use.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/8702550179217269394/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=8702550179217269394' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/8702550179217269394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/8702550179217269394'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2008/09/tracing-gallium3d.html' title='Tracing Gallium3D'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_siK-uBftJ9E/SBQJu-vVTJI/AAAAAAAAAB0/cfOtk3KJHGg/s72-c/module_dataflow.png' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-6461686027928596602</id><published>2008-09-04T02:25:00.003+01:00</published><updated>2008-09-04T03:28:41.259+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Gallium3D'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Learning and testing Gallium3D with Python</title><content type='html'>&lt;p&gt;Gallium3D interfaces don't match any particular graphics API 1 to 1. Likewise, conformance tests end up not doing a good coverage of Gallium3D's interface either: sometimes a single Gallium3D feature is tested in many different tests; sometimes a feature ends up not being exercised by any test, so bugs are only detected in applications, where they are much harder to narrow down. And so appeared the need to write some tests at the Gallium3D interface level.&lt;/p&gt;

&lt;p&gt;Since the ability to write tests quickly was important, and the running speed not so important, I've decided to write a Python bindings, so that tests could be scripted in Python. These bindings wrap around the pipe driver, so that they look like a pipe driver from the Python script point of view, and look like a state tracker from the pipe driver point of view.&lt;/p&gt;

&lt;p&gt;About the tests there is not much to write about yet. I wrote tests for texture formats that allowed to squash the bugs I was searching for, and I imagine that more tests will be added as needs justify it.&lt;/p&gt;

&lt;p&gt;However, having a Gallium3D bindings in Python opens several doors. One particularly is that it becomes a nice sandbox to learn Gallium3D. For example. here is the code to draw a single triangle:&lt;/p&gt;

&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;test&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;dev&lt;font color="#990000"&gt;):&lt;/font&gt;
    ctx &lt;font color="#990000"&gt;=&lt;/font&gt; dev&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;context_create&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;

    width &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;255&lt;/font&gt;
    height &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;255&lt;/font&gt;

    &lt;i&gt;&lt;font color="#9A1900"&gt;# disabled blending/masking&lt;/font&gt;&lt;/i&gt;
    blend &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;Blend&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;
    blend&lt;font color="#990000"&gt;.&lt;/font&gt;rgb&lt;font color="#009900"&gt;_&lt;/font&gt;src&lt;font color="#009900"&gt;_&lt;/font&gt;factor &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#009900"&gt;PIPE_BLENDFACTOR_ONE&lt;/font&gt;
    blend&lt;font color="#990000"&gt;.&lt;/font&gt;alpha&lt;font color="#009900"&gt;_&lt;/font&gt;src&lt;font color="#009900"&gt;_&lt;/font&gt;factor &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#009900"&gt;PIPE_BLENDFACTOR_ONE&lt;/font&gt;
    blend&lt;font color="#990000"&gt;.&lt;/font&gt;rgb&lt;font color="#009900"&gt;_&lt;/font&gt;dst&lt;font color="#009900"&gt;_&lt;/font&gt;factor &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#009900"&gt;PIPE_BLENDFACTOR_ZERO&lt;/font&gt;
    blend&lt;font color="#990000"&gt;.&lt;/font&gt;alpha&lt;font color="#009900"&gt;_&lt;/font&gt;dst&lt;font color="#009900"&gt;_&lt;/font&gt;factor &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#009900"&gt;PIPE_BLENDFACTOR_ZERO&lt;/font&gt;
    blend&lt;font color="#990000"&gt;.&lt;/font&gt;colormask &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#009900"&gt;PIPE_MASK_RGBA&lt;/font&gt;
    ctx&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;set_blend&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;blend&lt;font color="#990000"&gt;)&lt;/font&gt;

    &lt;i&gt;&lt;font color="#9A1900"&gt;# no-op depth/stencil/alpha&lt;/font&gt;&lt;/i&gt;
    depth&lt;font color="#009900"&gt;_&lt;/font&gt;stencil&lt;font color="#009900"&gt;_&lt;/font&gt;alpha &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;DepthStencilAlpha&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;
    ctx&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;set_depth_stencil_alpha&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;depth&lt;font color="#009900"&gt;_&lt;/font&gt;stencil&lt;font color="#009900"&gt;_&lt;/font&gt;alpha&lt;font color="#990000"&gt;)&lt;/font&gt;

    &lt;i&gt;&lt;font color="#9A1900"&gt;# rasterizer&lt;/font&gt;&lt;/i&gt;
    rasterizer &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;Rasterizer&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;
    rasterizer&lt;font color="#990000"&gt;.&lt;/font&gt;front&lt;font color="#009900"&gt;_&lt;/font&gt;winding &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#009900"&gt;PIPE_WINDING_CW&lt;/font&gt;
    rasterizer&lt;font color="#990000"&gt;.&lt;/font&gt;cull&lt;font color="#009900"&gt;_&lt;/font&gt;mode &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#009900"&gt;PIPE_WINDING_NONE&lt;/font&gt;
    rasterizer&lt;font color="#990000"&gt;.&lt;/font&gt;bypass&lt;font color="#009900"&gt;_&lt;/font&gt;clipping &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;
    rasterizer&lt;font color="#990000"&gt;.&lt;/font&gt;scissor &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;
    &lt;i&gt;&lt;font color="#9A1900"&gt;#rasterizer.bypass_vs = 1&lt;/font&gt;&lt;/i&gt;
    ctx&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;set_rasterizer&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;rasterizer&lt;font color="#990000"&gt;)&lt;/font&gt;

    &lt;i&gt;&lt;font color="#9A1900"&gt;# viewport (identity, we setup vertices in wincoords)&lt;/font&gt;&lt;/i&gt;
    viewport &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;Viewport&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;
    scale &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;FloatArray&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;4&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
    scale&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;1.0&lt;/font&gt;
    scale&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;1.0&lt;/font&gt;
    scale&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;1.0&lt;/font&gt;
    scale&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;1.0&lt;/font&gt;
    viewport&lt;font color="#990000"&gt;.&lt;/font&gt;scale &lt;font color="#990000"&gt;=&lt;/font&gt; scale
    translate &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;FloatArray&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;4&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
    translate&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;0.0&lt;/font&gt;
    translate&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;0.0&lt;/font&gt;
    translate&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;0.0&lt;/font&gt;
    translate&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;0.0&lt;/font&gt;
    viewport&lt;font color="#990000"&gt;.&lt;/font&gt;translate &lt;font color="#990000"&gt;=&lt;/font&gt; translate
    ctx&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;set_viewport&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;viewport&lt;font color="#990000"&gt;)&lt;/font&gt;

    &lt;i&gt;&lt;font color="#9A1900"&gt;# samplers&lt;/font&gt;&lt;/i&gt;
    sampler &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;Sampler&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;
    sampler&lt;font color="#990000"&gt;.&lt;/font&gt;wrap&lt;font color="#009900"&gt;_&lt;/font&gt;s &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#009900"&gt;PIPE_TEX_WRAP_CLAMP_TO_EDGE&lt;/font&gt;
    sampler&lt;font color="#990000"&gt;.&lt;/font&gt;wrap&lt;font color="#009900"&gt;_&lt;/font&gt;t &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#009900"&gt;PIPE_TEX_WRAP_CLAMP_TO_EDGE&lt;/font&gt;
    sampler&lt;font color="#990000"&gt;.&lt;/font&gt;wrap&lt;font color="#009900"&gt;_&lt;/font&gt;r &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#009900"&gt;PIPE_TEX_WRAP_CLAMP_TO_EDGE&lt;/font&gt;
    sampler&lt;font color="#990000"&gt;.&lt;/font&gt;min&lt;font color="#009900"&gt;_&lt;/font&gt;mip&lt;font color="#009900"&gt;_&lt;/font&gt;filter &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#009900"&gt;PIPE_TEX_MIPFILTER_NONE&lt;/font&gt;
    sampler&lt;font color="#990000"&gt;.&lt;/font&gt;min&lt;font color="#009900"&gt;_&lt;/font&gt;img&lt;font color="#009900"&gt;_&lt;/font&gt;filter &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#009900"&gt;PIPE_TEX_MIPFILTER_NEAREST&lt;/font&gt;
    sampler&lt;font color="#990000"&gt;.&lt;/font&gt;mag&lt;font color="#009900"&gt;_&lt;/font&gt;img&lt;font color="#009900"&gt;_&lt;/font&gt;filter &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#009900"&gt;PIPE_TEX_MIPFILTER_NEAREST&lt;/font&gt;
    sampler&lt;font color="#990000"&gt;.&lt;/font&gt;normalized&lt;font color="#009900"&gt;_&lt;/font&gt;coords &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;
    ctx&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;set_sampler&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; sampler&lt;font color="#990000"&gt;)&lt;/font&gt;

    &lt;i&gt;&lt;font color="#9A1900"&gt;# scissor&lt;/font&gt;&lt;/i&gt;
    scissor &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;Scissor&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;
    scissor&lt;font color="#990000"&gt;.&lt;/font&gt;minx &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;
    scissor&lt;font color="#990000"&gt;.&lt;/font&gt;miny &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;
    scissor&lt;font color="#990000"&gt;.&lt;/font&gt;maxx &lt;font color="#990000"&gt;=&lt;/font&gt; width
    scissor&lt;font color="#990000"&gt;.&lt;/font&gt;maxy &lt;font color="#990000"&gt;=&lt;/font&gt; height
    ctx&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;set_scissor&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;scissor&lt;font color="#990000"&gt;)&lt;/font&gt;

    clip &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;Clip&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;
    clip&lt;font color="#990000"&gt;.&lt;/font&gt;nr &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;
    ctx&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;set_clip&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;clip&lt;font color="#990000"&gt;)&lt;/font&gt;

    &lt;i&gt;&lt;font color="#9A1900"&gt;# framebuffer&lt;/font&gt;&lt;/i&gt;
    cbuf &lt;font color="#990000"&gt;=&lt;/font&gt; dev&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;texture_create&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;
        &lt;font color="#009900"&gt;PIPE_FORMAT_X8R8G8B8_UNORM&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
        width&lt;font color="#990000"&gt;,&lt;/font&gt; height&lt;font color="#990000"&gt;,&lt;/font&gt;
        tex&lt;font color="#009900"&gt;_&lt;/font&gt;usage&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#009900"&gt;PIPE_TEXTURE_USAGE_DISPLAY_TARGET&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;
    &lt;font color="#990000"&gt;)&lt;/font&gt;
    &lt;font color="#009900"&gt;_&lt;/font&gt;cbuf &lt;font color="#990000"&gt;=&lt;/font&gt; cbuf&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;get_surface&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;usage &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#009900"&gt;PIPE_BUFFER_USAGE_GPU_READ&lt;/font&gt;&lt;font color="#990000"&gt;|&lt;/font&gt;&lt;font color="#009900"&gt;PIPE_BUFFER_USAGE_GPU_WRITE&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
    fb &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;Framebuffer&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;
    fb&lt;font color="#990000"&gt;.&lt;/font&gt;width &lt;font color="#990000"&gt;=&lt;/font&gt; width
    fb&lt;font color="#990000"&gt;.&lt;/font&gt;height &lt;font color="#990000"&gt;=&lt;/font&gt; height
    fb&lt;font color="#990000"&gt;.&lt;/font&gt;num&lt;font color="#009900"&gt;_&lt;/font&gt;cbufs &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;
    fb&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;set_cbuf&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#009900"&gt;_&lt;/font&gt;cbuf&lt;font color="#990000"&gt;)&lt;/font&gt;
    ctx&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;set_framebuffer&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;fb&lt;font color="#990000"&gt;)&lt;/font&gt;
    &lt;font color="#009900"&gt;_&lt;/font&gt;cbuf&lt;font color="#990000"&gt;.&lt;/font&gt;clear&lt;font color="#009900"&gt;_&lt;/font&gt;value &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;0x00000000&lt;/font&gt;
    ctx&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;surface_clear&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#009900"&gt;_&lt;/font&gt;cbuf&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#009900"&gt;_&lt;/font&gt;cbuf&lt;font color="#990000"&gt;.&lt;/font&gt;clear&lt;font color="#009900"&gt;_&lt;/font&gt;value&lt;font color="#990000"&gt;)&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;del&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;_&lt;/font&gt;cbuf
    
    &lt;i&gt;&lt;font color="#9A1900"&gt;# vertex shader&lt;/font&gt;&lt;/i&gt;
    vs &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;Shader&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;'
        &lt;font color="#009900"&gt;VERT1&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;
        &lt;font color="#009900"&gt;DCL&lt;/font&gt; &lt;font color="#009900"&gt;IN&lt;/font&gt;&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;],&lt;/font&gt; &lt;font color="#009900"&gt;POSITION&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#009900"&gt;CONSTANT&lt;/font&gt;
        &lt;font color="#009900"&gt;DCL&lt;/font&gt; &lt;font color="#009900"&gt;IN&lt;/font&gt;&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;],&lt;/font&gt; &lt;font color="#009900"&gt;COLOR&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#009900"&gt;CONSTANT&lt;/font&gt;
        &lt;font color="#009900"&gt;DCL&lt;/font&gt; &lt;font color="#009900"&gt;OUT&lt;/font&gt;&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;],&lt;/font&gt; &lt;font color="#009900"&gt;POSITION&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#009900"&gt;CONSTANT&lt;/font&gt;
        &lt;font color="#009900"&gt;DCL&lt;/font&gt; &lt;font color="#009900"&gt;OUT&lt;/font&gt;&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;],&lt;/font&gt; &lt;font color="#009900"&gt;COLOR&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#009900"&gt;CONSTANT&lt;/font&gt;
        &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#009900"&gt;MOV&lt;/font&gt; &lt;font color="#009900"&gt;OUT&lt;/font&gt;&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;],&lt;/font&gt; &lt;font color="#009900"&gt;IN&lt;/font&gt;&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt;
        &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#009900"&gt;MOV&lt;/font&gt; &lt;font color="#009900"&gt;OUT&lt;/font&gt;&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;],&lt;/font&gt; &lt;font color="#009900"&gt;IN&lt;/font&gt;&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt;
        &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#009900"&gt;END&lt;/font&gt;
    '&lt;font color="#990000"&gt;)&lt;/font&gt;
    ctx&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;set_vertex_shader&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;vs&lt;font color="#990000"&gt;)&lt;/font&gt;

    &lt;i&gt;&lt;font color="#9A1900"&gt;# fragment shader&lt;/font&gt;&lt;/i&gt;
    fs &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;Shader&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;'
        &lt;font color="#009900"&gt;FRAG1&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;
        &lt;font color="#009900"&gt;DCL&lt;/font&gt; &lt;font color="#009900"&gt;IN&lt;/font&gt;&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;],&lt;/font&gt; &lt;font color="#009900"&gt;COLOR&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#009900"&gt;LINEAR&lt;/font&gt;
        &lt;font color="#009900"&gt;DCL&lt;/font&gt; &lt;font color="#009900"&gt;OUT&lt;/font&gt;&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;],&lt;/font&gt; &lt;font color="#009900"&gt;COLOR&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#009900"&gt;CONSTANT&lt;/font&gt;
        &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#009900"&gt;MOV&lt;/font&gt; &lt;font color="#009900"&gt;OUT&lt;/font&gt;&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;],&lt;/font&gt; &lt;font color="#009900"&gt;IN&lt;/font&gt;&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt;
        &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#009900"&gt;END&lt;/font&gt;
    '&lt;font color="#990000"&gt;)&lt;/font&gt;
    ctx&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;set_fragment_shader&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;fs&lt;font color="#990000"&gt;)&lt;/font&gt;

    nverts &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;3&lt;/font&gt;
    nattrs &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;
    verts &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;FloatArray&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;nverts &lt;font color="#990000"&gt;*&lt;/font&gt; nattrs &lt;font color="#990000"&gt;*&lt;/font&gt; &lt;font color="#993399"&gt;4&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;

    verts&lt;font color="#990000"&gt;[&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;128.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# x1&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;  &lt;font color="#993399"&gt;32.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# y1&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;0.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# z1&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt; &lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;1.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# w1&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt; &lt;font color="#993399"&gt;4&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;1.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# r1&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt; &lt;font color="#993399"&gt;5&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;0.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# g1&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt; &lt;font color="#993399"&gt;6&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;0.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# b1&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt; &lt;font color="#993399"&gt;7&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;1.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# a1&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt; &lt;font color="#993399"&gt;8&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;  &lt;font color="#993399"&gt;32.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# x2&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt; &lt;font color="#993399"&gt;9&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;224.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# y2&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;0.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# z2&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;11&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;1.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# w2&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;12&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;0.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# r2&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;13&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;1.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# g2&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;14&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;0.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# b2&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;15&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;1.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# a2&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;16&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;224.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# x3&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;17&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;224.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# y3&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;18&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;0.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# z3&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;19&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;1.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# w3&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;20&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;0.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# r3&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;21&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;0.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# g3&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;22&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;1.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# b3&lt;/font&gt;&lt;/i&gt;
    verts&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;23&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;   &lt;font color="#993399"&gt;1.0&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# a3&lt;/font&gt;&lt;/i&gt;

    ctx&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;draw_vertices&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#009900"&gt;PIPE_PRIM_TRIANGLES&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;
                      nverts&lt;font color="#990000"&gt;,&lt;/font&gt; 
                      nattrs&lt;font color="#990000"&gt;,&lt;/font&gt; 
                      verts&lt;font color="#990000"&gt;)&lt;/font&gt;

    ctx&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;flush&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;

&lt;p&gt;And this is the result:&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_siK-uBftJ9E/SL9GA8J7HSI/AAAAAAAAADM/J-aHAeEuuWk/s1600-h/tri.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_siK-uBftJ9E/SL9GA8J7HSI/AAAAAAAAADM/J-aHAeEuuWk/s1024/tri.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5241985473244241186" /&gt;&lt;/a&gt;

&lt;p&gt;In summary, you create several &lt;i&gt;state atoms&lt;/i&gt;, bind them to the context, and then send the geometry through the pipe driver. Full source available in &lt;a href="http://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/state_trackers/python/samples/tri.py?h=gallium-0.1"&gt;Mesa3D's git repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To use Gallium3D's Python bindings follow &lt;a href="http://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/state_trackers/python/README?h=gallium-0.1"&gt;these instructions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;BTW, &lt;a href="http://www.x.org/wiki/Events/XDS2008"&gt;XDS 2008&lt;/a&gt; is happening now. Too bad I couldn't go this year, as I would like to meet everybody. I hope you're having a great time!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/6461686027928596602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=6461686027928596602' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/6461686027928596602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/6461686027928596602'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2008/09/learning-and-testing-gallium3d-with.html' title='Learning and testing Gallium3D with Python'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_siK-uBftJ9E/SL9GA8J7HSI/AAAAAAAAADM/J-aHAeEuuWk/s72-c/tri.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-4195178253381887686</id><published>2008-07-13T00:23:00.003+01:00</published><updated>2008-07-13T00:38:17.987+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='neverball'/><category scheme='http://www.blogger.com/atom/ns#' term='ipod'/><title type='text'>Neverball on iPod</title><content type='html'>&lt;p&gt;I had a lot of fun playing &lt;a href="http://icculus.org/neverball/"&gt;Neverball&lt;/a&gt;'s minigolf alter ego, Neverputt, with my brother. Neverball itself was fun, but it was too hard to progress using the mouse. But this changed now that Neverball was &lt;a href="http://www.casey.org.uk/iphone_neverball/index.html"&gt;ported to the iPod Touch/iPhone&lt;/a&gt;, using its internal &lt;a href="http://www.apple.com/ipodtouch/features.html#accelerometer"&gt;accelerometer&lt;/a&gt; as input:&lt;/p&gt;

&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/mfS2OUjKfZQ&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/mfS2OUjKfZQ&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;

&lt;p&gt;I can't help but thinking &lt;i&gt;this&lt;/i&gt; is how the game was intended to be played.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/4195178253381887686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=4195178253381887686' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/4195178253381887686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/4195178253381887686'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2008/07/neverball-on-ipod.html' title='Neverball on iPod'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-7911027184813116829</id><published>2008-07-11T11:57:00.007+01:00</published><updated>2008-07-13T00:15:50.240+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gprof2dot'/><category scheme='http://www.blogger.com/atom/ns#' term='recursion'/><category scheme='http://www.blogger.com/atom/ns#' term='profile'/><title type='text'>Propagating time inside recursive function cycles</title><content type='html'>&lt;p&gt;I believe that a &lt;a href="http://code.google.com/p/jrfonseca/wiki/Gprof2Dot"&gt;call graph showing the total function time&lt;/a&gt; (that is, the time spent inside the function and all its descendants) is one of the most useful visualizations of profile data, as it allows to quickly grasp what is the critical code path in your program that is taking most of the execution time.&lt;/p&gt;

&lt;p&gt;Total function time is typically calculated by propagating the time along the call graph, from callees to callers. The problem with measuring total function time are recursive functions, as noted on &lt;a href="http://citeseer.ist.psu.edu/graham82gprof.html"&gt;gprof article&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;Time propagation within strongly connected components is a problem. For example, a self-recursive routine (a trivial cycle in the call graph) is accountable for all the time it uses in all its recursive instantiations. In our scheme, this time should be shared among its call graph parents. The arcs from a routine to itself are of interest, but do not participate in time propagation. Thus the simple equation for time propagation does not work within strongly connected components. Time is not propagated from one member of a cycle to another, since, by definition, this involves propagating time from a routine to itself. In addition, children of one member of a cycle must be considered children of all members of the cycle. Similarly, parents of one member of the cycle must inherit all members of the cycle as descendants. It is for these reasons that we collapse connected components. Our solution collects all members of a cycle together, summing the time and call counts for all members. All calls into the cycle are made to share the total time of the cycle, and all descendants of the cycle propagate time into the cycle as a whole. Calls among the members of the cycle do not propagate any time, though they are listed in the call graph profile.&lt;/blockquote&gt;

&lt;p&gt;This means that, for example, the recursive call of of singly recursive functions is ignored:&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_siK-uBftJ9E/SHdBzUjwrfI/AAAAAAAAACU/Ny6cQIeDrK8/s1600-h/1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp2.blogger.com/_siK-uBftJ9E/SHdBzUjwrfI/AAAAAAAAACU/Ny6cQIeDrK8/s1600/1.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5221714642907213298" /&gt;&lt;/a&gt;&lt;

&lt;p&gt;And recursion cycles with two or more functions are collapsed in a single node:&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_siK-uBftJ9E/SHdBzV-u5gI/AAAAAAAAACc/SOA4gv081pI/s1600-h/2a.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp0.blogger.com/_siK-uBftJ9E/SHdBzV-u5gI/AAAAAAAAACc/SOA4gv081pI/s1600/2a.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5221714643288778242" /&gt;&lt;/a&gt;

&lt;p&gt;In summary, the call graph is converted in a Directed Acyclic Graph (DAG).&lt;/p&gt;

&lt;p&gt;However this approach has several drawbacks. By treating alls functions in a recursion cycle as a single entity, you loose the ability to differentiate among them; you cannot prune individually the functions which have little contribution to the overall time, so the call graph gets bigger and more complex. Furthermore, nothing prevents a call graph to be full of recursion cycles. Actually, if you throw in the mix a statistical profiler like oprofile which produces spurious calls when the instruction pointer is sampled before/after the stack frame is setup/destroyed, and a environment like the linux kernel where there are IRQs artificially introducing function calls to the IRQ handler, you'll probably also end up with a &lt;a href="http://code.google.com/p/jrfonseca/issues/detail?id=6#c1"&gt;400KB dot file of &lt;i&gt;spaghetti&lt;/i&gt; inside, which graphviz's dot chews for all eternity&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I tried to find a better solution for several months. Most attempts ended up with my head in an infinite loop. The solution eventually came to me once I realized that time is a linear quantity, that is, if you propagate the time along the graph assuming zero time for all but one function, repeat for every function, and take the overall sum, then you will reach the same results as doing the computation in a single pass. Given this, and the fact that by using the gprof approach we already know the time being propagated into and out of the cycle, we can then try to estimate the time propagation inside the cycle by decompose the cycle into a DAG having as root each function that is called externally. For example, taking the two function recursion example above, you can decompose the call graph in two cases:&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_siK-uBftJ9E/SHdBzlosbuI/AAAAAAAAACk/f0a-U8BncEc/s1600-h/2b.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp3.blogger.com/_siK-uBftJ9E/SHdBzlosbuI/AAAAAAAAACk/f0a-U8BncEc/s1600/2b.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5221714647491309282" /&gt;&lt;/a&gt;

&lt;p&gt;Then it is just a matter of propagating the partial time for each case, and take the total sum. The same thing can be done with any number of nodes:&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_siK-uBftJ9E/SHdBz9R2crI/AAAAAAAAACs/NtnQyqvMi8Y/s1600-h/4b.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp2.blogger.com/_siK-uBftJ9E/SHdBz9R2crI/AAAAAAAAACs/NtnQyqvMi8Y/s1600/4b.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5221714653837947570" /&gt;&lt;/a&gt;

&lt;p&gt;The end result is an heuristic that enables gprof2dot to visually differentiate and prune recursive functions as any other function, producing &lt;a href="http://jrfonseca.googlecode.com/issues/attachment?aid=6356891578466624356&amp;name=x11perf.png"&gt;consistent and meaningful results&lt;/a&gt;.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/7911027184813116829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=7911027184813116829' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/7911027184813116829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/7911027184813116829'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2008/07/propagating-time-inside-recursive.html' title='Propagating time inside recursive function cycles'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_siK-uBftJ9E/SHdBzUjwrfI/AAAAAAAAACU/Ny6cQIeDrK8/s72-c/1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-5678472681791366244</id><published>2008-07-10T01:44:00.007+01:00</published><updated>2008-07-10T02:45:50.670+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tracing'/><category scheme='http://www.blogger.com/atom/ns#' term='D3D'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Tracing D3D applications</title><content type='html'>&lt;p&gt;I needed a tool to trace Direct3D 8 applications, like Microsoft's defunct D3DSpy or &lt;a href="http://msdn.microsoft.com/en-us/library/bb173085.aspx"&gt;PIX&lt;/a&gt;.
Unfortunately D3DSpy/PIX is for Direct3D 9 and above only, and no source is available, so I decided to roll my own tool.&lt;/p&gt;

&lt;p&gt;I started with Michael Koch's &lt;a href="http://www.codeguru.com/cpp/g-m/directx/directx8/article.php/c11453/"&gt;sample code to intercept calls to DirectX with a proxy DLL&lt;/a&gt;, but when I was done I ended up writing a framework in Python to generate automatically all the code to intercept all the Direct3D 8 API (or almost any DLL for that matter), and dump the parameters in between.&lt;p&gt;

&lt;p&gt;The code generation mechanism is inspired in Python's &lt;a href="http://python.net/crew/theller/ctypes/"&gt;ctypes module&lt;/a&gt;. One describes the APIs in Python like:&lt;p&gt;
&lt;pre&gt;D3DPRESENT_PARAMETERS &lt;span style="color: #666666"&gt;=&lt;/span&gt; Struct(&lt;span style="color: #BA2121"&gt;&amp;quot;D3DPRESENT_PARAMETERS&amp;quot;&lt;/span&gt;, [
    (UINT, &lt;span style="color: #BA2121"&gt;&amp;quot;BackBufferWidth&amp;quot;&lt;/span&gt;),
    (UINT, &lt;span style="color: #BA2121"&gt;&amp;quot;BackBufferHeight&amp;quot;&lt;/span&gt;),
    (D3DFORMAT, &lt;span style="color: #BA2121"&gt;&amp;quot;BackBufferFormat&amp;quot;&lt;/span&gt;),
    (UINT, &lt;span style="color: #BA2121"&gt;&amp;quot;BackBufferCount&amp;quot;&lt;/span&gt;),
    (D3DMULTISAMPLE_TYPE, &lt;span style="color: #BA2121"&gt;&amp;quot;MultiSampleType&amp;quot;&lt;/span&gt;),
    (DWORD, &lt;span style="color: #BA2121"&gt;&amp;quot;MultiSampleQuality&amp;quot;&lt;/span&gt;),
    (D3DSWAPEFFECT, &lt;span style="color: #BA2121"&gt;&amp;quot;SwapEffect&amp;quot;&lt;/span&gt;),
    (HWND, &lt;span style="color: #BA2121"&gt;&amp;quot;hDeviceWindow&amp;quot;&lt;/span&gt;),
    (BOOL, &lt;span style="color: #BA2121"&gt;&amp;quot;Windowed&amp;quot;&lt;/span&gt;),
    (BOOL, &lt;span style="color: #BA2121"&gt;&amp;quot;EnableAutoDepthStencil&amp;quot;&lt;/span&gt;),
    (D3DFORMAT, &lt;span style="color: #BA2121"&gt;&amp;quot;AutoDepthStencilFormat&amp;quot;&lt;/span&gt;),
    (DWORD, &lt;span style="color: #BA2121"&gt;&amp;quot;Flags&amp;quot;&lt;/span&gt;),
    (UINT, &lt;span style="color: #BA2121"&gt;&amp;quot;FullScreen_RefreshRateInHz&amp;quot;&lt;/span&gt;),
    (UINT, &lt;span style="color: #BA2121"&gt;&amp;quot;PresentationInterval&amp;quot;&lt;/span&gt;),
])

IDirect3D9&lt;span style="color: #666666"&gt;.&lt;/span&gt;methods&lt;span style="color: #666666"&gt;.&lt;/span&gt;&lt;span style="color: #008000"&gt;append&lt;/span&gt;(
    Method(HRESULT, &lt;span style="color: #BA2121"&gt;&amp;quot;CreateDevice&amp;quot;&lt;/span&gt;, [
        (UINT, &lt;span style="color: #BA2121"&gt;&amp;quot;Adapter&amp;quot;&lt;/span&gt;), 
        (D3DDEVTYPE, &lt;span style="color: #BA2121"&gt;&amp;quot;DeviceType&amp;quot;&lt;/span&gt;), 
        (HWND, &lt;span style="color: #BA2121"&gt;&amp;quot;hFocusWindow&amp;quot;&lt;/span&gt;), 
        (DWORD, &lt;span style="color: #BA2121"&gt;&amp;quot;BehaviorFlags&amp;quot;&lt;/span&gt;), 
        (OutPointer(D3DPRESENT_PARAMETERS), &lt;span style="color: #BA2121"&gt;&amp;quot;pPresentationParameters&amp;quot;&lt;/span&gt;), 
        (OutPointer(PDIRECT3DDEVICE9), &lt;span style="color: #BA2121"&gt;&amp;quot;ppReturnedDeviceInterface&amp;quot;&lt;/span&gt;)
    ]),
)
&lt;/pre&gt;

&lt;p&gt;Which will generate the following C++ code:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: #B00040"&gt;void&lt;/span&gt; DumpD3DPRESENT_PARAMETERS(&lt;span style="color: #008000; font-weight: bold"&gt;const&lt;/span&gt; D3DPRESENT_PARAMETERS &lt;span style="color: #666666"&gt;&amp;amp;&lt;/span&gt;value) {
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginElement(&lt;span style="color: #BA2121"&gt;&amp;quot;UINT&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;BackBufferWidth&amp;quot;&lt;/span&gt;);
    DumpUINT((value).BackBufferWidth);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndElement();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginElement(&lt;span style="color: #BA2121"&gt;&amp;quot;UINT&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;BackBufferHeight&amp;quot;&lt;/span&gt;);
    DumpUINT((value).BackBufferHeight);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndElement();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginElement(&lt;span style="color: #BA2121"&gt;&amp;quot;D3DFORMAT&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;BackBufferFormat&amp;quot;&lt;/span&gt;);
    DumpD3DFORMAT((value).BackBufferFormat);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndElement();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginElement(&lt;span style="color: #BA2121"&gt;&amp;quot;UINT&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;BackBufferCount&amp;quot;&lt;/span&gt;);
    DumpUINT((value).BackBufferCount);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndElement();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginElement(&lt;span style="color: #BA2121"&gt;&amp;quot;D3DMULTISAMPLE_TYPE&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;MultiSampleType&amp;quot;&lt;/span&gt;);
    DumpD3DMULTISAMPLE_TYPE((value).MultiSampleType);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndElement();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginElement(&lt;span style="color: #BA2121"&gt;&amp;quot;DWORD&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;MultiSampleQuality&amp;quot;&lt;/span&gt;);
    DumpDWORD((value).MultiSampleQuality);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndElement();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginElement(&lt;span style="color: #BA2121"&gt;&amp;quot;D3DSWAPEFFECT&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;SwapEffect&amp;quot;&lt;/span&gt;);
    DumpD3DSWAPEFFECT((value).SwapEffect);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndElement();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginElement(&lt;span style="color: #BA2121"&gt;&amp;quot;HWND&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;hDeviceWindow&amp;quot;&lt;/span&gt;);
    DumpHWND((value).hDeviceWindow);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndElement();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginElement(&lt;span style="color: #BA2121"&gt;&amp;quot;BOOL&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;Windowed&amp;quot;&lt;/span&gt;);
    DumpBOOL((value).Windowed);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndElement();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginElement(&lt;span style="color: #BA2121"&gt;&amp;quot;BOOL&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;EnableAutoDepthStencil&amp;quot;&lt;/span&gt;);
    DumpBOOL((value).EnableAutoDepthStencil);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndElement();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginElement(&lt;span style="color: #BA2121"&gt;&amp;quot;D3DFORMAT&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;AutoDepthStencilFormat&amp;quot;&lt;/span&gt;);
    DumpD3DFORMAT((value).AutoDepthStencilFormat);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndElement();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginElement(&lt;span style="color: #BA2121"&gt;&amp;quot;DWORD&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;Flags&amp;quot;&lt;/span&gt;);
    DumpDWORD((value).Flags);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndElement();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginElement(&lt;span style="color: #BA2121"&gt;&amp;quot;UINT&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;FullScreen_RefreshRateInHz&amp;quot;&lt;/span&gt;);
    DumpUINT((value).FullScreen_RefreshRateInHz);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndElement();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginElement(&lt;span style="color: #BA2121"&gt;&amp;quot;UINT&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;PresentationInterval&amp;quot;&lt;/span&gt;);
    DumpUINT((value).PresentationInterval);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndElement();
}

HRESULT &lt;span style="color: #008000; font-weight: bold"&gt;__stdcall&lt;/span&gt; WrapIDirect3D9&lt;span style="color: #666666"&gt;::&lt;/span&gt;CreateDevice(UINT Adapter, 
  D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, 
  D3DPRESENT_PARAMETERS &lt;span style="color: #666666"&gt;*&lt;/span&gt; pPresentationParameters, 
  IDirect3DDevice9 &lt;span style="color: #666666"&gt;*&lt;/span&gt; &lt;span style="color: #666666"&gt;*&lt;/span&gt; ppReturnedDeviceInterface
) {
    HRESULT result;
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginCall(&lt;span style="color: #BA2121"&gt;&amp;quot;IDirect3D9::CreateDevice&amp;quot;&lt;/span&gt;);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginArg(&lt;span style="color: #BA2121"&gt;&amp;quot;IDirect3D9 *&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;this&amp;quot;&lt;/span&gt;);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginReference(&lt;span style="color: #BA2121"&gt;&amp;quot;IDirect3D9&amp;quot;&lt;/span&gt;, m_pInstance);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndReference();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndArg();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginArg(&lt;span style="color: #BA2121"&gt;&amp;quot;UINT&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;Adapter&amp;quot;&lt;/span&gt;);
    DumpUINT(Adapter);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndArg();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginArg(&lt;span style="color: #BA2121"&gt;&amp;quot;D3DDEVTYPE&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;DeviceType&amp;quot;&lt;/span&gt;);
    DumpD3DDEVTYPE(DeviceType);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndArg();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginArg(&lt;span style="color: #BA2121"&gt;&amp;quot;HWND&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;hFocusWindow&amp;quot;&lt;/span&gt;);
    DumpHWND(hFocusWindow);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndArg();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginArg(&lt;span style="color: #BA2121"&gt;&amp;quot;DWORD&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;BehaviorFlags&amp;quot;&lt;/span&gt;);
    DumpDWORD(BehaviorFlags);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndArg();
    result &lt;span style="color: #666666"&gt;=&lt;/span&gt; m_pInstance&lt;span style="color: #666666"&gt;-&amp;gt;&lt;/span&gt;CreateDevice(Adapter, DeviceType, hFocusWindow, 
      BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginArg(&lt;span style="color: #BA2121"&gt;&amp;quot;D3DPRESENT_PARAMETERS *&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;pPresentationParameters&amp;quot;&lt;/span&gt;);
    &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt;(pPresentationParameters) {
        Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginReference(&lt;span style="color: #BA2121"&gt;&amp;quot;D3DPRESENT_PARAMETERS&amp;quot;&lt;/span&gt;, pPresentationParameters);
        DumpD3DPRESENT_PARAMETERS(&lt;span style="color: #666666"&gt;*&lt;/span&gt;pPresentationParameters);
        Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndReference();
    }
    &lt;span style="color: #008000; font-weight: bold"&gt;else&lt;/span&gt;
        Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;Text(&lt;span style="color: #BA2121"&gt;&amp;quot;NULL&amp;quot;&lt;/span&gt;);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndArg();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginArg(&lt;span style="color: #BA2121"&gt;&amp;quot;IDirect3DDevice9 * *&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;ppReturnedDeviceInterface&amp;quot;&lt;/span&gt;);
    &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt;(ppReturnedDeviceInterface) {
        Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginReference(&lt;span style="color: #BA2121"&gt;&amp;quot;IDirect3DDevice9 *&amp;quot;&lt;/span&gt;, ppReturnedDeviceInterface);
        &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt;(&lt;span style="color: #666666"&gt;*&lt;/span&gt;ppReturnedDeviceInterface) {
            Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginReference(&lt;span style="color: #BA2121"&gt;&amp;quot;IDirect3DDevice9&amp;quot;&lt;/span&gt;, &lt;span style="color: #666666"&gt;*&lt;/span&gt;ppReturnedDeviceInterface);
        Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndReference();
    }
    &lt;span style="color: #008000; font-weight: bold"&gt;else&lt;/span&gt;
        Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;Text(&lt;span style="color: #BA2121"&gt;&amp;quot;NULL&amp;quot;&lt;/span&gt;);
        Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndReference();
    }
    &lt;span style="color: #008000; font-weight: bold"&gt;else&lt;/span&gt;
        Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;Text(&lt;span style="color: #BA2121"&gt;&amp;quot;NULL&amp;quot;&lt;/span&gt;);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndArg();
    &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt;(&lt;span style="color: #666666"&gt;*&lt;/span&gt;ppReturnedDeviceInterface)
        &lt;span style="color: #666666"&gt;*&lt;/span&gt;ppReturnedDeviceInterface &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;new&lt;/span&gt; WrapIDirect3DDevice9(&lt;span style="color: #666666"&gt;*&lt;/span&gt;ppReturnedDeviceInterface);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;BeginReturn(&lt;span style="color: #BA2121"&gt;&amp;quot;HRESULT&amp;quot;&lt;/span&gt;);
    DumpHRESULT(result);
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndReturn();
    Log&lt;span style="color: #666666"&gt;::&lt;/span&gt;EndCall();
    &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; result;
}
&lt;/pre&gt;

&lt;p&gt;Which, when executed, hopefully generates something like the following XML:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;call&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;IDirect3D9::CreateDevice&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;arg&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;IDirect3D9 *&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;this&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;ref&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;IDirect3D9&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;addr=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;001481E0&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&amp;lt;/ref&amp;gt;&lt;/span&gt;
  &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
  &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;arg&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;UINT&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Adapter&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;0&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
  &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;arg&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;D3DDEVTYPE&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;DeviceType&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;D3DDEVTYPE_HAL&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
  &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;arg&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;HWND&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;hFocusWindow&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;00110138&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
  &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;arg&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;DWORD&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;BehaviorFlags&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;0x00000020&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
  &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;arg&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;D3DPRESENT_PARAMETERS *&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;pPresentationParameters&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;ref&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;D3DPRESENT_PARAMETERS&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;addr=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;0012FE84&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;elem&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;UINT&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;BackBufferWidth&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;250&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/elem&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;elem&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;UINT&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;BackBufferHeight&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;250&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/elem&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;elem&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;D3DFORMAT&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;BackBufferFormat&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;D3DFMT_X8R8G8B8&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/elem&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;elem&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;UINT&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;BackBufferCount&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;1&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/elem&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;elem&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;D3DMULTISAMPLE_TYPE&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;MultiSampleType&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;D3DMULTISAMPLE_NONE&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/elem&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;elem&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;DWORD&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;MultiSampleQuality&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;0x00000000&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/elem&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;elem&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;D3DSWAPEFFECT&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;SwapEffect&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;D3DSWAPEFFECT_DISCARD&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/elem&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;elem&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;HWND&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;hDeviceWindow&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;00110138&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/elem&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;elem&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;BOOL&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Windowed&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;1&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/elem&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;elem&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;BOOL&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;EnableAutoDepthStencil&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;0&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/elem&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;elem&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;D3DFORMAT&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;AutoDepthStencilFormat&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;D3DFMT_UNKNOWN&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/elem&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;elem&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;DWORD&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Flags&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;0x00000000&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/elem&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;elem&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;UINT&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;FullScreen_RefreshRateInHz&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;0&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/elem&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;elem&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;UINT&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;PresentationInterval&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;2147483648&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/elem&amp;gt;&lt;/span&gt;
    &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/ref&amp;gt;&lt;/span&gt;
  &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
  &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;arg&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;IDirect3DDevice9 * *&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;ppReturnedDeviceInterface&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;ref&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;IDirect3DDevice9 *&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;addr=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;0043289C&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;
      &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;ref&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;IDirect3DDevice9&amp;quot;&lt;/span&gt; &lt;span style="color: #7D9029"&gt;addr=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;0014EBA0&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&amp;lt;/ref&amp;gt;&lt;/span&gt;
    &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/ref&amp;gt;&lt;/span&gt;
  &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
  &lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;ret&lt;/span&gt; &lt;span style="color: #7D9029"&gt;type=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;HRESULT&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;D3D_OK&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/ret&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/call&amp;gt;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Which when viewed by a XML and CSS capable browser like Firefox or Internet Explorer will show:&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_siK-uBftJ9E/SHVhVQp2VBI/AAAAAAAAACM/ZNG8Ag9LiQ4/s1600-h/d3dtrace.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp2.blogger.com/_siK-uBftJ9E/SHVhVQp2VBI/AAAAAAAAACM/ZNG8Ag9LiQ4/s400/d3dtrace.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5221186360881599506" /&gt;&lt;/a&gt;

&lt;p&gt;Hovering on value will popup its type; and with Firefox, hovering on a pointer will show the referred data structure.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://cgit.freedesktop.org/~jrfonseca/d3dtrace/"&gt;Source&lt;/a&gt; and &lt;a href="http://people.freedesktop.org/~jrfonseca/d3dtrace/"&gt;binaries&lt;/a&gt; available.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/5678472681791366244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=5678472681791366244' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/5678472681791366244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/5678472681791366244'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2008/07/tracing-d3d-applications.html' title='Tracing D3D applications'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_siK-uBftJ9E/SHVhVQp2VBI/AAAAAAAAACM/ZNG8Ag9LiQ4/s72-c/d3dtrace.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-8300507620114064023</id><published>2008-06-25T02:04:00.004+01:00</published><updated>2008-06-25T03:13:56.093+01:00</updated><title type='text'>Saving desk space</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_siK-uBftJ9E/SGGmFPbjO8I/AAAAAAAAACE/8Het4dSW1Vk/s1600-h/desktop.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://bp2.blogger.com/_siK-uBftJ9E/SGGmFPbjO8I/AAAAAAAAACE/8Het4dSW1Vk/s320/desktop.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5215632452443388866" /&gt;&lt;/a&gt;

&lt;p&gt;Space is tight around here in Tokyo. The high population density is reflected on the public transportation system, land price, cultural traditions, house sizes, and ultimately on my desk size. However my daily work implies to interact with multiple hardware. This is what I do to save desk space.&lt;/p&gt;

&lt;dl&gt;

&lt;dt&gt;Buy small boxes.&lt;/dt&gt;
&lt;dd&gt;Obviously, the smaller the boxes are the more you can fit under your desk. However beware that too small and exchanging the parts becomes as delicate and time-consuming as clock making.&lt;/dd&gt;

&lt;dt&gt;Use a KVM switch.&lt;/dt&gt;
&lt;dd&gt;Using 4-way USB+VGA KVM not only eliminates the need of having a keyboard, mouse, and monitor for each box, but also saves on cabling. Decent KVM switchs allow you to switch machine directly from the keyboard, so it saves you time too.&lt;/dd&gt;

&lt;dt&gt;Use &lt;a href="http://synergy2.sourceforge.net/"&gt;synergy&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;The KVM switch is nice, but for debugging/testing it is actually more useful to have a separate monitor for the test machine. &lt;a href="http://synergy2.sourceforge.net/"&gt;synergy&lt;/a&gt; fits nicely here, as it allows to share the mouse and keyboard between multiple computers across the network, each with its own display. You switch between machines by moving the mouse off the edge of your screen. It also shares the clipboard and works seemingly across Windows and other OSes.&lt;/dd&gt;

&lt;dt&gt;Use remote access&lt;/dt&gt;
&lt;dd&gt;Often you don't even need a physically connected display, and remote access via protocals such as SSH, Remote X, &lt;a href="http://www.rdesktop.org/"&gt;Remote Desktop Protocol&lt;/a&gt;, and &lt;a href="http://www.realvnc.com/"&gt;VNC&lt;/a&gt; are sufficient for development.&lt;/dd&gt;

&lt;dt&gt;Use virtualization/emulation&lt;/dt&gt;
&lt;dd&gt;You can't beat the space taken by a virtual machine like &lt;a href="http://www.vmware.com/"&gt;VMWare&lt;/a&gt; or &lt;a href="http://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt;. Unfortunately, rarely can this be used in practice. My current use of it consists in running Windows development tools inside Linux.&lt;/dd&gt;

&lt;/dl&gt;

&lt;p&gt;I hope you find these tips useful. Please share any other desk space saving tips you have.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/8300507620114064023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=8300507620114064023' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/8300507620114064023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/8300507620114064023'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2008/06/saving-desk-space.html' title='Saving desk space'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_siK-uBftJ9E/SGGmFPbjO8I/AAAAAAAAACE/8Het4dSW1Vk/s72-c/desktop.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-2115825984142031149</id><published>2008-04-28T03:17:00.001+01:00</published><updated>2008-04-28T03:19:50.704+01:00</updated><title type='text'>Oops</title><content type='html'>&lt;p&gt;Sorry about planet.fd.o pollution...&lt;/p&gt;

&lt;p&gt;I'll stop playing with the Blogger tags now...&lt;/p&gt;

&lt;p&gt;m(_ _)m&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/2115825984142031149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=2115825984142031149' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/2115825984142031149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/2115825984142031149'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2008/04/oops.html' title='Oops'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-4048342461020588593</id><published>2008-04-27T04:08:00.018+01:00</published><updated>2008-04-28T04:00:53.947+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Gallium3D'/><title type='text'>Gallium3D: Introduction</title><content type='html'>&lt;p&gt;At &lt;a href="http://www.tungstengraphics.com/"&gt;Tungsten Graphics&lt;/a&gt; I've been working in &lt;a href="http://www.tungstengraphics.com/technologies/gallium3d.html"&gt;Gallium3D&lt;/a&gt; &amp;mdash; a very promising architecture to develop 3D graphic drivers for multiple operating systems and graphic APIs.&lt;/p&gt;

&lt;p&gt;It comes as no surprise that Gallium3D is a large and complex piece of software. So I've decided to write a bit about it in the hope of helping newcomers to get more quickly familiarized with it.&lt;/p&gt;

&lt;p&gt;A few adverts: I had little to do with Gallium3D's design — that's the work of much brighter people such as Keith Whitwell and Brian Paul — so a lot of the rationale written here is partly my own speculation; also Gallium3D architecture is still under flux (much less than before, but still), so this refers to its current state.&lt;/p&gt;

&lt;h2&gt;Architecture&lt;/h2&gt;

&lt;p&gt;Gallium3D architecture can be described as &lt;i&gt;a set of interfaces and a collection of supporting libraries&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;Gallium3D is &lt;b&gt;not&lt;/b&gt; a &lt;a href="http://en.wikipedia.org/wiki/Software_framework"&gt;framework&lt;/a&gt;. All attempts of using the &lt;a href="http://en.wikipedia.org/wiki/Hollywood_Principle"&gt;Hollywood Principle&lt;/a&gt; of &lt;i&gt;"Don’t call us, we’ll call you."&lt;/i&gt; for 3D driver development imply making assumptions about the hardware behavior which quickly are proven wrong as new hardware generations come along. Instead, by simply providing a set of libraries, Gallium3D's can more easily adapt in this rapidly evolving field. So Gallium3D's principle is indeed &lt;i&gt;"Is up to you to call us, as we won't call you".&lt;/i&gt; Is is necessary to have this principle in mind to understand how all Gallium pieces fit together.&lt;/p&gt;

&lt;h2&gt;Modules&lt;/h2&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_siK-uBftJ9E/SBQESevVTHI/AAAAAAAAABk/j-VXqNsdmo0/s1600-h/module_dependencies.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_siK-uBftJ9E/SBQESevVTHI/AAAAAAAAABk/j-VXqNsdmo0/s400/module_dependencies.png" alt="" id="BLOGGER_PHOTO_ID_5193780985800772722" border="0" /&gt;&lt;/a&gt;

&lt;dl&gt;
&lt;dt&gt;State tracker&lt;/dt&gt;
&lt;dd&gt;Translates the graphics API state (e.g., blend mode, texture sampling mode, etc.), shaders, and graphics primitives into something that the pipe driver below understands.&lt;/dd&gt;
&lt;dt&gt;Pipe driver&lt;/dt&gt;
&lt;dd&gt;Translates the state, shaders, and primitives in something that the hardware understands (e.g., register writes, shader/command buffers, and vertex buffers).&lt;/dd&gt;
&lt;dt&gt;Winsys&lt;/dt&gt;
&lt;dd&gt;Instantiates and binds all pieces above (state tracker and pipe driver) together with the OS, window system, and 2D display driver.&lt;/dd&gt;
&lt;dt&gt;Auxiliary modules&lt;/dt&gt;
&lt;dd&gt;Provide optional auxiliary services such as, software interpretation of shaders for hardware without hardware vertex shader support, state caching, buffer management, etc.&lt;/dd&gt;
&lt;/dl&gt;

&lt;table&gt;
&lt;caption&gt;Module dependency table&lt;/caption&gt;
&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Graphics API&lt;/th&gt;&lt;th&gt;Graphics Hardware&lt;/th&gt;&lt;th&gt;OS&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Auxiliary modules&lt;/th&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;State Tracker&lt;/th&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes/No(1)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Pipe driver&lt;/th&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Winsys&lt;/th&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;(1) The state tracker depends on the graphics API, so it can be made OS-independent for OS-independent APIs (such as OpenGL), but not for OS-dependent APIs (such as Direct3D)&lt;/p&gt;

&lt;p&gt;The higher the module is in the previous table the more it is reused (auxiliary modules,State Tracker). The lower it is, more times it will have to be rewritten (Winsys). Although the dividing line between these modules is blurry, we are always interested in moving functionality upwards as much as possible. This is one of the areas where Gallium3D architecture is under flux: when we support a new graphics hardware, graphics API, or OS and realize that there is some functionality that can be generalized then we move it upwards; if we realize that previously made assumptions no longer hold, then we move that functionality downwards.&lt;/p&gt;

&lt;h2&gt;Interfaces&lt;/h2&gt;

&lt;a onblur=" try=" href="http://bp1.blogger.com/_siK-uBftJ9E/SBQJuuvVTII/AAAAAAAAABs/wag_q0CZAyM/s1600-h/module_interfaces.png" border="1"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_siK-uBftJ9E/SBQJuuvVTII/AAAAAAAAABs/wag_q0CZAyM/s400/module_interfaces.png" alt="" id="BLOGGER_PHOTO_ID_5193786968690216066" border="0" /&gt;&lt;/a&gt;

&lt;dl&gt;
&lt;dt&gt;State tracker &lt;-&gt; Pipe driver&lt;/dt&gt;
&lt;dd&gt;There is a per-context interface(&lt;a href="http://dri.freedesktop.org/doxygen/gallium/p__context_8h.html"&gt;p_context.h&lt;/a&gt;) and a global/per-screen interface(&lt;a href="http://dri.freedesktop.org/doxygen/gallium/p__screen_8h.html"&gt;p_screen.h&lt;/a&gt;).&lt;/dd&gt;
&lt;dt&gt;State tracker &lt;-&gt; Winsys &lt;/dt&gt;
&lt;dd&gt;&lt;a href="http://dri.freedesktop.org/doxygen/gallium/p__winsys_8h.html"&gt;p_winsys.h&lt;/a&gt;&lt;/dd&gt;
&lt;dt&gt;Pipe driver &lt;-&gt; Winsys&lt;/dt&gt;
&lt;dd&gt;Besides p_winsys.h above, each pipe driver has its own additional winsys interface: &lt;a href="http://dri.freedesktop.org/doxygen/gallium/sp__winsys_8h.html"&gt;sp_winsys.h&lt;/a&gt; (pure-software pipe driver), &lt;a href="http://dri.freedesktop.org/doxygen/gallium/i915__winsys_8h.html"&gt;i915_winsys.h&lt;/a&gt; (Intel 915/945 pipe driver), etc.&lt;/dd&gt;
&lt;/dl&gt;

&lt;h2&gt;Data flow&lt;/h2&gt;

&lt;p&gt;The data flow is actually quite simple to understand:&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_siK-uBftJ9E/SBQJu-vVTJI/AAAAAAAAAB0/cfOtk3KJHGg/s1600-h/module_dataflow.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_siK-uBftJ9E/SBQJu-vVTJI/AAAAAAAAAB0/cfOtk3KJHGg/s800/module_dataflow.png" alt="" id="BLOGGER_PHOTO_ID_5193786972985183378" border="0" /&gt;&lt;/a&gt;

&lt;p&gt;The graphics state and primitives created in the application are successively broken down in things more close to the hardware as they progress in the pipe line. One of Gallium3D's biggest achievement is defining a set of interfaces that allows the central piece -- the pipe driver --, to be reused in different graphics APIs and OSes.&lt;/p&gt;

&lt;p&gt;If you zoom up the microscope one level, you can detect two extra (auxiliary) modules:&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_siK-uBftJ9E/SBQJvOvVTKI/AAAAAAAAAB8/tjvrfh0aMQM/s1600-h/module_dataflow2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/_siK-uBftJ9E/SBQJvOvVTKI/AAAAAAAAAB8/tjvrfh0aMQM/s800/module_dataflow2.png" alt="" id="BLOGGER_PHOTO_ID_5193786977280150690" border="0" /&gt;&lt;/a&gt;

&lt;dl&gt;
&lt;dt&gt;CSO context&lt;/dt&gt;
&lt;dd&gt;Optionally used by the state tracker for Constant State Object (CSO) caching. The state passed to the pipe driver is immutable (constant) to simplify the pipe driver implementation. To avoid the performance penalty of always destroying/creating these state objects, these are stored in a cache.&lt;/dd&gt;
&lt;dt&gt;Draw module&lt;/dt&gt;
&lt;dd&gt;Optionally used by the pipe driver to do vertex transform, lighting, and primitive clipping in software, for hardware without support for it.&lt;/dd&gt;
&lt;/dl&gt;

&lt;h2&gt;The rest...&lt;/h2&gt;

&lt;/p&gt;&lt;p&gt;That's all for today. Hopefully soon I'll write a bit more about these modules in more detail. I actually started my way in Gallium3D from Winsys and only recently started working on the State tracker, so there is some studying left to do.&lt;/p&gt;

&lt;p&gt;Until then, to learn more about Gallium3D see:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.tungstengraphics.com/wiki/index.php/Gallium3D"&gt;TG Wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.tungstengraphics.com/wiki/files/gallium3d-xds2007.pdf"&gt;Talk from XDS 2007&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dri.freedesktop.org/doxygen/gallium/"&gt;Cross-referenced source code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/4048342461020588593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=4048342461020588593' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/4048342461020588593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/4048342461020588593'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2008/04/gallium3d-introduction.html' title='Gallium3D: Introduction'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_siK-uBftJ9E/SBQESevVTHI/AAAAAAAAABk/j-VXqNsdmo0/s72-c/module_dependencies.png' height='72' width='72'/><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-6956027004416488857</id><published>2008-01-30T03:47:00.000Z</published><updated>2008-04-28T03:17:12.428+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DRI'/><title type='text'>TextChas</title><content type='html'>&lt;p&gt;I've enabled &lt;a href="http://moinmo.in/TextCha"&gt;TextChas&lt;/a&gt; on the &lt;a href="http://dri.freedesktop.org/wiki/"&gt;DRI Wiki&lt;/a&gt;. It is now necessary to answer a question when creating an user account and editing pages.&lt;/p&gt;

&lt;p&gt;Two weeks have passed, and there was no new spam since TextChas were enabled, which is really nice for a change.&lt;/p&gt;

&lt;p&gt;I'm sure spammers can try harder and beat TextChas if they are up to the challenge. But I
definitely think that TextChas is a simple and effective solution for the current spam in freedesktop.org wikis. It will, at the very lest, allow us to fight spam against spammers more evenly.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/6956027004416488857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=6956027004416488857' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/6956027004416488857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/6956027004416488857'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2008/01/textchas.html' title='TextChas'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-697062933166683503</id><published>2007-12-11T13:41:00.000Z</published><updated>2008-04-28T03:17:05.133+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Gallium3D'/><category scheme='http://www.blogger.com/atom/ns#' term='DRI'/><category scheme='http://www.blogger.com/atom/ns#' term='Mesa'/><title type='text'>Profiling DRI drivers</title><content type='html'>&lt;p&gt;I've been spending a lot of time profiling DRI drivers for &lt;a href="http://www.tungstengraphics.com/gallium3D.htm"&gt;Gallium 3D&lt;/a&gt;.
I've tried gprof, &lt;a href="http://valgrind.org/"&gt;valgrind&lt;/a&gt;, and finally &lt;a href="http://oprofile.sourceforge.net/"&gt;oprofile&lt;/a&gt;. Oprofile seems the
best in my opinion for this purpose. More details on the &lt;a href="http://dri.freedesktop.org/wiki/Profiling"&gt;DRI Wiki&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I also wrote a &lt;a href="http://code.google.com/p/jrfonseca/wiki/Gprof2Dot"&gt;script to generate a time-colored call graph from oprofile output, using graphviz&lt;/a&gt;. See an output
example of profiling glxgears on Gallium 3D:&lt;/p&gt;

&lt;!--
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_siK-uBftJ9E/R16VTSRvnGI/AAAAAAAAABY/zZVc92sNSBY/s1600-h/oprofile-gallium.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp0.blogger.com/_siK-uBftJ9E/R16VTSRvnGI/AAAAAAAAABY/zZVc92sNSBY/s400/oprofile-gallium.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5142711983059999842" /&gt;&lt;/a&gt;
--&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://people.freedesktop.org/~jrfonseca/profiling/oprofile-gallium.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp0.blogger.com/_siK-uBftJ9E/R16VTSRvnGI/AAAAAAAAABY/zZVc92sNSBY/s400/oprofile-gallium.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5142711983059999842" /&gt;&lt;/a&gt;

&lt;p&gt;The hotter the colour of a function is, more time is spent on that
function and its children.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/697062933166683503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=697062933166683503' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/697062933166683503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/697062933166683503'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2007/12/profiling-dri-drivers.html' title='Profiling DRI drivers'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_siK-uBftJ9E/R16VTSRvnGI/AAAAAAAAABY/zZVc92sNSBY/s72-c/oprofile-gallium.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-456743138240863531</id><published>2007-12-11T13:05:00.000Z</published><updated>2008-04-28T03:15:19.997+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='DRI'/><title type='text'>Using Eclipse for X.Org/DRI development</title><content type='html'>&lt;p&gt;I've never learned to use Emacs. I love vim, but it doesn't scale for
me when editing more than three files at the same time or projects
with more than one directory. After two years using &lt;a href="http://pydef.sourceforge.net/"&gt;Eclipse for Python&lt;/a&gt;
and &lt;a href="http://www.eclipse.org/cdt/"&gt;Windows C++&lt;/a&gt; development, I've been using almost exclusively Eclipse for &lt;a href="http://www.x.org/"&gt;X.Org&lt;/a&gt;/&lt;a href="http://www.mesa3d.org"&gt;Mesa&lt;/a&gt;/&lt;a href="http://dri.freedesktop.org"&gt;DRI&lt;/a&gt; development during the last three months.&lt;/p&gt;

&lt;p&gt;I think Eclipse is really a pleasant development environment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it has a good code navigator, which is also fast (&lt;a href="http://cdtdoug.blogspot.com/2006/06/cant-talk-now-coding.html"&gt;they used
Mozilla's source tree as a benchmark&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;excellent support for remote debugging (&lt;a href="http://cdtdoug.blogspot.com/2006/02/cool-eclipse-cdt-for-embedded-tutorial.html"&gt;embedded companies are major
contributors to Eclipse&lt;/a&gt;, since almost every embedded SDK nowadays is
based on it);&lt;/li&gt;
&lt;li&gt;it rarely stands it the way (e.g., it integrates with any build
system from autotools to hand written shell scripts, you still have
the power of regular expression at your finger tips, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, the &lt;a href="http://www.eclipse.org/cdt/"&gt;CDT (the C/C++ Development Plugin for Eclipse)&lt;/a&gt; folks are now actively
working to get Eclipse not only to debug remote applications, but also
&lt;a href="http://dev.eclipse.org/mhonarc/lists/dsdp-tm-dev/msg01369.html"&gt;build remotely&lt;/a&gt;, which will greatly simplify testing on multiple
software/hardware configurations.&lt;/p&gt;

&lt;p&gt;The thing I miss the most is &lt;a href="http://git.or.cz/gitwiki/EclipsePlugin"&gt;better git integration&lt;/a&gt;. Of course, it is advisable to have a big screen and lots of memory.&lt;/p&gt;

&lt;p&gt;For those interested, I've wrote some instructions to get you
started on the &lt;a href="http://www.x.org/wiki/Development/Documentation/UsingEclipse"&gt;X.Org Wiki&lt;/a&gt;.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/456743138240863531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=456743138240863531' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/456743138240863531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/456743138240863531'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2007/12/using-eclipse-for-xorgdri-development.html' title='Using Eclipse for X.Org/DRI development'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-5143830971915279621</id><published>2007-12-07T11:48:00.000Z</published><updated>2008-04-28T03:14:05.171+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Debian'/><title type='text'>Loading ~/.bash_profile when logging from X</title><content type='html'>&lt;p&gt;In Debian/Ubuntu, when logging from gdm your ~/.bash_profile or even ~/.bash_rc are loaded, preventing you to set environment variables for all your session. The reason is that gdm starts /usr/bin/x-session-manager directly.&lt;/p&gt;

&lt;p&gt;There are many ways to get ~/.bash_profile loaded. Many of which are &lt;a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=354523"&gt;wrong&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I found that a very simple way to loading ~/.bash_profile when starting X is to write the following ~/.xsession script:&lt;/p&gt;

&lt;pre&gt;
&lt;font color="#0000ff"&gt;#!/bin/bash --login&lt;/font&gt;
&lt;font color="#a52a2a"&gt;&lt;b&gt;exec&lt;/b&gt;&lt;/font&gt;&amp;nbsp;/usr/bin/x-session-manager
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/5143830971915279621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=5143830971915279621' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/5143830971915279621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/5143830971915279621'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2007/12/loading-bashprofile-when-logging-from-x.html' title='Loading ~/.bash_profile when logging from X'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-114795339364895632</id><published>2006-05-18T12:36:00.000+01:00</published><updated>2007-12-22T12:48:24.042Z</updated><title type='text'>Mass Renaming in Nautilus</title><content type='html'>&lt;p&gt;One can easily add new actions in Nautilus context menu by adding shell scripts to &lt;code&gt;~/.gnome2/nautilus-scripts&lt;/code&gt; . Below is a script for mass file renaming, using Perl's rename utility and zenity. Add it to &lt;code&gt;~/.gnome2/nautilus-scripts/Mass Rename&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;
&lt;font color="#0000ff"&gt;#!/bin/sh&lt;/font&gt;
&lt;font color="#0000ff"&gt;# Nautilus script for mass file renaming&lt;/font&gt;

&lt;font color="#a52a2a"&gt;&lt;b&gt;set&lt;/b&gt;&lt;/font&gt; &lt;font color="#008b8b"&gt;-e&lt;/font&gt;

&lt;font color="#008b8b"&gt;TITLE&lt;/font&gt;=&lt;font color="#6a5acd"&gt;`basename &lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$0&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;`&lt;/font&gt;

&lt;font color="#0000ff"&gt;# Path to perl's rename&lt;/font&gt;
&lt;font color="#008b8b"&gt;RENAME&lt;/font&gt;=/usr/bin/rename


rename_all&lt;font color="#a52a2a"&gt;&lt;b&gt;()&lt;/b&gt;&lt;/font&gt; &lt;font color="#6a5acd"&gt;{&lt;/font&gt;
        &lt;font color="#008b8b"&gt;IFS&lt;/font&gt;=&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;$'&lt;/font&gt;&lt;/span&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;'&lt;/font&gt;&lt;/span&gt;
        &lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt; FILE &lt;font color="#a52a2a"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt; &lt;font color="#a020f0"&gt;$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS&lt;/font&gt;
        &lt;font color="#a52a2a"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/font&gt;
                &lt;font color="#a52a2a"&gt;&lt;b&gt;cd&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;`dirname &lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$FILE&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;`&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;
                &lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$RENAME&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$@&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$EXPR&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt; -- &lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;`basename &lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$FILE&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;`&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;
        &lt;font color="#a52a2a"&gt;&lt;b&gt;done&lt;/b&gt;&lt;/font&gt;
&lt;font color="#6a5acd"&gt;}&lt;/font&gt;


&lt;font color="#008b8b"&gt;EXPR&lt;/font&gt;=&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt;s///&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;
while true
&lt;font color="#a52a2a"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/font&gt;
        &lt;font color="#008b8b"&gt;EXPR&lt;/font&gt;=&lt;font color="#6a5acd"&gt;`zenity --title &lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$TITLE&lt;/font&gt;&lt;font color="#ff00ff"&gt; - expression&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt; --entry --text &lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt;Specify the Perl expression for modifying the filenames.&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt; --entry-text &lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$EXPR&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;`&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;||&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;exit&lt;/b&gt;&lt;/font&gt;

        rename_all &lt;font color="#a52a2a"&gt;&lt;b&gt;-n&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;|&lt;/b&gt;&lt;/font&gt; sed &lt;font color="#a52a2a"&gt;&lt;b&gt;-e&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt;s/^\(.*\) renamed as \(.*\)$/\2\n\1/&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;|&lt;/b&gt;&lt;/font&gt; zenity --list --width &lt;font color="#ff00ff"&gt;800&lt;/font&gt; --height &lt;font color="#ff00ff"&gt;600&lt;/font&gt; --title  &lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$TITLE&lt;/font&gt;&lt;font color="#ff00ff"&gt; - Preview&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt; --text &lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&amp;quot;&lt;/b&gt;&lt;/font&gt; --column &lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt;New name&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt; --column &lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt;Old name&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;amp;&amp;amp;&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;break&lt;/b&gt;&lt;/font&gt;
&lt;font color="#a52a2a"&gt;&lt;b&gt;done&lt;/b&gt;&lt;/font&gt;

rename_all
&lt;/pre&gt;

&lt;p&gt;Here are some screenshots:&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/7495/883/1600/s1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/7495/883/320/s1.png" border="0" alt="" /&gt;&lt;/a&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/7495/883/1600/s2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/7495/883/320/s2.png" border="0" alt="" /&gt;&lt;/a&gt;

&lt;p&gt;The latest version of this script can be found &lt;a href="http://code.google.com/p/jrfonseca/wiki/NautilusMassRenaming"&gt;here&lt;/a&gt;.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/114795339364895632/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=114795339364895632' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/114795339364895632'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/114795339364895632'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2006/05/mass-renaming-in-nautilus.html' title='Mass Renaming in Nautilus'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-114388612151612161</id><published>2006-04-01T10:59:00.000+01:00</published><updated>2008-04-28T03:14:05.172+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Debian'/><title type='text'>Building the whole Debian archive with GCC 4.1</title><content type='html'>&lt;p&gt;A lot of hard work from Martin Michlmayr which provided quite an &lt;a href="http://os.newsforge.com/article.pl?sid=06/03/31/1937226"&gt;interesting&lt;/a&gt; &lt;a href="http://lists.debian.org/debian-devel/2006/03/msg01084.html"&gt;reading&lt;/a&gt;.&lt;p&gt;

&lt;p&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tags/debian" rel="tag"&gt;debian&lt;/a&gt;, &lt;a href="http://www.technorati.com/tags/gcc" rel="tag"&gt;gcc&lt;/a&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/114388612151612161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=114388612151612161' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/114388612151612161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/114388612151612161'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2006/04/building-whole-debian-archive-with-gcc.html' title='Building the whole Debian archive with GCC 4.1'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-114374219562211248</id><published>2006-03-30T18:36:00.000+01:00</published><updated>2006-10-30T22:54:54.254Z</updated><title type='text'>XML based CVs</title><content type='html'>&lt;p&gt;XML + a XSLT toolchain is an excellent way to maintain your Curriculum Vitae, supporting several languages and several formats with minimum effort.  I've been using the &lt;a href="http://xmlresume.sourceforge.net/"&gt;XML Résumé Library&lt;/a&gt; for my CV for a while, but the lack of recent updates and a slight unsatisfaction with the look of the PDF output made me want to take a peek on what else is out there.&lt;/p&gt;

&lt;p&gt;Didn't find much though: the overall feeling I get is that, though not perfect, the XML Résumé Library seems to be the safest bet out there.&lt;/p&gt;

&lt;p&gt;The sole exception worth mention is the work done by David Sora for a subject of his masters degree. He designed a XSD schema together with HTML and PDF XSLT stylesheets for CVs based upon the &lt;a href="http://europass.cedefop.eu.int/"&gt;Europass Curriculum Vitae&lt;/a&gt; layout. His &lt;a href="http://dsora.home.cern.ch/dsora/paginas/ProjectoXML/Doc/RelatorioCV.html"&gt;report&lt;/a&gt; is written in portuguese, but an example CV and XSLT are available for english too (in the parent directory of the report). This might not be picked up a community (such as the one behind XML Résumé Library), but the schema is complete and the output looks nice. Also the layout of the Europass CV is comprehensive and professional &amp;mdash; as you'd expect from an initiative backed by the European Union. So definitelyinetly something to look upon whenever I need to tweak or drop the XML Résumé Library.&lt;/p&gt;

&lt;span class="technoratitag"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tags/xml" rel="tag"&gt;xml&lt;/a&gt;, &lt;a href="http://www.technorati.com/tags/xslt" rel="tag"&gt;xslt&lt;/a&gt;, &lt;a href="http://www.technorati.com/tags/cv" rel="tag"&gt;cv&lt;/a&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/114374219562211248/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=114374219562211248' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/114374219562211248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/114374219562211248'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2006/03/xml-based-cvs.html' title='XML based CVs'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-114277090088868247</id><published>2006-03-19T11:49:00.000Z</published><updated>2008-04-28T03:14:19.993+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Debian'/><title type='text'>Detecting the insertion/removal of USB modems with udev</title><content type='html'>&lt;p&gt;udev has replaced hotplug in the Debian distribution. However not all hotplug's functionality is available (or at least simple to use): with hotplug one could easily write scripts which processed add and remove events, while with udev that has proved to be quite an ordeal.&lt;/p&gt;

&lt;p&gt;The device I wanted to detect was the SpeedTouch USB ADSL modem. The first problem I ran into was that &lt;a href="http://www.disaggregate.com/blog/technicalweblog/archives/000013.html"&gt;"sysfs values are not readable at remove, because the device directory is already gone"&lt;/a&gt;. The solution is either using an environment variable with the DEVPATH (which didn't work for me), or matching the device with the reduced information available (my only remaining option). Thankfully there was this PRODUCT environment variable which could precisely match the device. This is how the udev rules look:&lt;/p&gt;

&lt;pre&gt;
&lt;font color="#0000ff"&gt;# /etc/udev/rules.d/z80_speedtch.rules&lt;/font&gt;

BUS==&amp;quot;usb&amp;quot;, SUBSYSTEM==&amp;quot;usb&amp;quot;, SYSFS{idVendor}==&amp;quot;06b9&amp;quot;, SYSFS{idProduct}==&amp;quot;4061&amp;quot;, ACTION==&amp;quot;add&amp;quot;, RUN+=&amp;quot;/bin/sh -c '/usr/local/sbin/speedtouch &amp;amp;'&amp;quot;
BUS==&amp;quot;usb&amp;quot;, SUBSYSTEM==&amp;quot;usb&amp;quot;, ENV{PRODUCT}==&amp;quot;6b9/4061/0&amp;quot;, ACTION==&amp;quot;remove&amp;quot;, RUN+=&amp;quot;/bin/sh -c '/usr/local/sbin/speedtouch &amp;amp;'&amp;quot;
&lt;/pre&gt;

&lt;p&gt;The actions I wanted to take was to start/stop the ppp interface. The second problem is that the above rules matched many add/remove events (driver, and several USB subdevices). To ensure only one add/remove action is taken, a solution is to use the SEQNUM environment variable, whose value is a always increasing integer, and keep track of its value when the device first got inserted. This is how /usr/local/sbin/speedtouch looks like:&lt;/p&gt;

&lt;pre&gt;
&lt;font color="#0000ff"&gt;#!/bin/sh&lt;/font&gt;

&lt;font color="#008b8b"&gt;RUN&lt;/font&gt;=/var/run/speedtouch.seqnum

&lt;font color="#008b8b"&gt;TIMEOUT&lt;/font&gt;=&lt;font color="#ff00ff"&gt;60&lt;/font&gt;

&lt;font color="#0000ff"&gt;# test whether the device is currently added or not&lt;/font&gt;
device_added &lt;font color="#a52a2a"&gt;&lt;b&gt;()&lt;/b&gt;&lt;/font&gt; &lt;font color="#6a5acd"&gt;{&lt;/font&gt;
        &lt;font color="#a52a2a"&gt;&lt;b&gt;test&lt;/b&gt;&lt;/font&gt; -e &lt;font color="#a020f0"&gt;$RUN&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;amp;&amp;amp;&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;test&lt;/b&gt;&lt;/font&gt; &lt;font color="#6a5acd"&gt;`cat &lt;/font&gt;&lt;font color="#a020f0"&gt;$RUN&lt;/font&gt;&lt;font color="#6a5acd"&gt;`&lt;/font&gt; -lt &lt;font color="#a020f0"&gt;$SEQNUM&lt;/font&gt;
&lt;font color="#6a5acd"&gt;}&lt;/font&gt;

&lt;font color="#0000ff"&gt;# wait for the &amp;quot;ADSL line is up&amp;quot; kernel message to appear&lt;/font&gt;
wait_for_adsl_up &lt;font color="#a52a2a"&gt;&lt;b&gt;()&lt;/b&gt;&lt;/font&gt; &lt;font color="#6a5acd"&gt;{&lt;/font&gt;
        local TIME

        dmesg -c &lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;gt;&lt;/b&gt;&lt;/font&gt; /dev/null
        &lt;font color="#008b8b"&gt;TIME&lt;/font&gt;=&lt;font color="#ff00ff"&gt;0&lt;/font&gt;
        while &lt;font color="#a52a2a"&gt;&lt;b&gt;!&lt;/b&gt;&lt;/font&gt; dmesg &lt;font color="#a52a2a"&gt;&lt;b&gt;|&lt;/b&gt;&lt;/font&gt; grep -q &lt;font color="#a52a2a"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt;ADSL line is up&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;
        &lt;font color="#a52a2a"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/font&gt;
                sleep &lt;font color="#ff00ff"&gt;1&lt;/font&gt;
                &lt;font color="#008b8b"&gt;TIME&lt;/font&gt;=&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;$(&lt;/font&gt;&lt;/span&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$TIME&lt;/font&gt;&lt;font color="#6a5acd"&gt;+&lt;/font&gt;&lt;font color="#ff00ff"&gt;1&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;)&lt;/font&gt;&lt;/span&gt;
                &lt;font color="#a52a2a"&gt;&lt;b&gt;test&lt;/b&gt;&lt;/font&gt; &lt;font color="#a020f0"&gt;$TIME&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;-ge&lt;/b&gt;&lt;/font&gt; &lt;font color="#a020f0"&gt;$TIMEOUT&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;amp;&amp;amp;&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt; &lt;font color="#ff00ff"&gt;1&lt;/font&gt;
        &lt;font color="#a52a2a"&gt;&lt;b&gt;done&lt;/b&gt;&lt;/font&gt;
&lt;font color="#6a5acd"&gt;}&lt;/font&gt;

&lt;font color="#a52a2a"&gt;&lt;b&gt;case&lt;/b&gt;&lt;/font&gt; &lt;font color="#a020f0"&gt;$ACTION&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt;
        add&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;
                &lt;font color="#0000ff"&gt;# ignore repeated &amp;quot;add&amp;quot; actions&lt;/font&gt;
                device_added &lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;amp;&amp;amp;&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;exit&lt;/b&gt;&lt;/font&gt;
                &lt;font color="#a52a2a"&gt;&lt;b&gt;echo&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt; &lt;/font&gt;&lt;font color="#a020f0"&gt;$SEQNUM&lt;/font&gt;&lt;font color="#ff00ff"&gt; &lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;&amp;gt;&lt;/b&gt;&lt;/font&gt; &lt;font color="#a020f0"&gt;$RUN&lt;/font&gt;

                wait_for_adsl_up

                ifup ppp0
                &lt;font color="#a52a2a"&gt;&lt;b&gt;;;&lt;/b&gt;&lt;/font&gt;
        remove&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;
                &lt;font color="#0000ff"&gt;# ignore repeated &amp;quot;remove&amp;quot; actions&lt;/font&gt;
                device_added &lt;font color="#a52a2a"&gt;&lt;b&gt;||&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;exit&lt;/b&gt;&lt;/font&gt;
                rm -f &lt;font color="#a020f0"&gt;$RUN&lt;/font&gt;

                ifdown ppp0
                &lt;font color="#a52a2a"&gt;&lt;b&gt;;;&lt;/b&gt;&lt;/font&gt;
&lt;font color="#a52a2a"&gt;&lt;b&gt;esac&lt;/b&gt;&lt;/font&gt;
&lt;/pre&gt;

&lt;p&gt;The script has a bit more magic for waiting for the ADSL line is up, which was taken from the &lt;a href="http://www.linux-usb.org/SpeedTouch/"&gt;SpeedTouch Linux kernel driver homepage&lt;/a&gt;.&lt;/p&gt;

&lt;span class="technoratitag"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tags/linux" rel="tag"&gt;linux&lt;/a&gt;, &lt;a href="http://www.technorati.com/tags/debian" rel="tag"&gt;debian&lt;/a&gt;, &lt;a href="http://www.technorati.com/tags/shell+scripts" rel="tag"&gt;shell scripts&lt;/a&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/114277090088868247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=114277090088868247' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/114277090088868247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/114277090088868247'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2006/03/detecting-insertionremoval-of-usb.html' title='Detecting the insertion/removal of USB modems with udev'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-114173026228649352</id><published>2006-03-07T10:49:00.000Z</published><updated>2008-04-28T03:14:41.795+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Mix'n'matching</title><content type='html'>&lt;p&gt;Have you ever did mental math to figure out how to best fit a collection of data into a set of DVDs, trying to squeeze the most into every single DVD? It happens more and more to me, so I wrote a Python script to do it for me.&lt;/p&gt;

&lt;p&gt;The algorithm used to efficiently find the largest path combinations below a threshold is inspired in the &lt;a href="http://en.wikipedia.org/wiki/Apriori_algorithm"&gt;apriori algorithm&lt;/a&gt; for association rule discovery. Since the largest path combination is a superset of smaller combinations, we can start building those starting from single paths, combine those with the initial to make two-item sets while removing all larger than the threshold, then three-item, four-item, and so on; until no larger combination below the threshold can be found.&lt;/p&gt;

&lt;p&gt;Here is the script:&lt;/p&gt;

&lt;pre&gt;
&lt;font color="#0000ff"&gt;#!/usr/bin/env python&lt;/font&gt;
&lt;font color="#0000ff"&gt;# mixnmatch.py - find combination of files/dirs that sum below a given threshold&lt;/font&gt;
&lt;font color="#0000ff"&gt;# -- Jose Fonseca&lt;/font&gt;

&lt;font color="#a020f0"&gt;import&lt;/font&gt; os
&lt;font color="#a020f0"&gt;import&lt;/font&gt; os.path
&lt;font color="#a020f0"&gt;import&lt;/font&gt; optparse
&lt;font color="#a020f0"&gt;import&lt;/font&gt; sys

&lt;font color="#a020f0"&gt;from&lt;/font&gt; sets &lt;font color="#a020f0"&gt;import&lt;/font&gt; ImmutableSet as set


&lt;font color="#a52a2a"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt; &lt;font color="#008b8b"&gt;get_size&lt;/font&gt;(path):
    &lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; os.path.isdir(path):
        result = 0
        &lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt; name &lt;font color="#a52a2a"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt; os.listdir(path):
            result += get_size(os.path.join(path, name))
        &lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt; result
    &lt;font color="#a52a2a"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/font&gt;:
        &lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt; os.path.getsize(path)


&lt;font color="#a52a2a"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt; &lt;font color="#008b8b"&gt;mix_and_match&lt;/font&gt;(limit, items, verbose = False):

    &lt;font color="#0000ff"&gt;# filter items&lt;/font&gt;
    items = [(size, name) &lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt; size, name &lt;font color="#a52a2a"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt; items &lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; size &amp;lt;= limit]
    &lt;font color="#0000ff"&gt;# sort them by size&lt;/font&gt;
    items.sort(&lt;font color="#a52a2a"&gt;&lt;b&gt;lambda&lt;/b&gt;&lt;/font&gt; (xsize, xname), (ysize, yname): cmp(xsize, ysize))

    &lt;font color="#0000ff"&gt;# initialize variables&lt;/font&gt;
    added_collections = dict([(set([name]), size) &lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt; size, name &lt;font color="#a52a2a"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt; items])
    collections = added_collections

    &lt;font color="#a52a2a"&gt;&lt;b&gt;while&lt;/b&gt;&lt;/font&gt; True:
        &lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; verbose:
            sys.stderr.write(&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;&lt;font color="#ff00ff"&gt;%d&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt; % len(collections))

        &lt;font color="#0000ff"&gt;# find unique combinations of the recent collections &lt;/font&gt;
        new_collections = {}
        &lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt; names1, size1 &lt;font color="#a52a2a"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt; added_collections.iteritems():
            &lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt; size2, name2 &lt;font color="#a52a2a"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt; items:
                size3 = size1 + size2
                &lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; size3 &amp;gt; limit:
                    &lt;font color="#0000ff"&gt;# we can break here as all collections that follow are&lt;/font&gt;
                    &lt;font color="#0000ff"&gt;#  bigger in size due to the sorting above&lt;/font&gt;
                    &lt;font color="#a52a2a"&gt;&lt;b&gt;break&lt;/b&gt;&lt;/font&gt;
                &lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; name2 &lt;font color="#a52a2a"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt; names1:
                    &lt;font color="#a52a2a"&gt;&lt;b&gt;continue&lt;/b&gt;&lt;/font&gt;
                names3 = names1.union(set([name2]))
                &lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; names3 &lt;font color="#a52a2a"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt; new_collections:
                    &lt;font color="#a52a2a"&gt;&lt;b&gt;continue&lt;/b&gt;&lt;/font&gt;
                new_collections[names3] = size3

        &lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; len(new_collections) == 0:
            &lt;font color="#a52a2a"&gt;&lt;b&gt;break&lt;/b&gt;&lt;/font&gt;

        collections.update(new_collections)
        added_collections = new_collections

    &lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt; [(size, names) &lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt; names, size &lt;font color="#a52a2a"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt; collections.iteritems()]


&lt;font color="#a52a2a"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt; &lt;font color="#008b8b"&gt;main&lt;/font&gt;():
    parser = optparse.OptionParser(usage=&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;&lt;font color="#6a5acd"&gt;\n\t&lt;/font&gt;&lt;font color="#ff00ff"&gt;%prog [options] path ...&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;)
    parser.add_option(
        &lt;span style="background-color: #f2f2f2"&gt;'&lt;/span&gt;&lt;font color="#ff00ff"&gt;-l&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;'&lt;/span&gt;, &lt;span style="background-color: #f2f2f2"&gt;'&lt;/span&gt;&lt;font color="#ff00ff"&gt;--limit&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;'&lt;/span&gt;,
        type=&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;&lt;font color="#ff00ff"&gt;int&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;, dest=&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;&lt;font color="#ff00ff"&gt;limit&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;, default=4700000000,
        help=&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;&lt;font color="#ff00ff"&gt;total size limit&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;)
    parser.add_option(
        &lt;span style="background-color: #f2f2f2"&gt;'&lt;/span&gt;&lt;font color="#ff00ff"&gt;-s&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;'&lt;/span&gt;, &lt;span style="background-color: #f2f2f2"&gt;'&lt;/span&gt;&lt;font color="#ff00ff"&gt;--show&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;'&lt;/span&gt;,
        type=&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;&lt;font color="#ff00ff"&gt;int&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;, dest=&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;&lt;font color="#ff00ff"&gt;show&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;, default=10,
        help=&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;&lt;font color="#ff00ff"&gt;number of combinations to show&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;)
    parser.add_option(
        &lt;span style="background-color: #f2f2f2"&gt;'&lt;/span&gt;&lt;font color="#ff00ff"&gt;-v&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;'&lt;/span&gt;, &lt;span style="background-color: #f2f2f2"&gt;'&lt;/span&gt;&lt;font color="#ff00ff"&gt;--verbose&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;'&lt;/span&gt;,
        action=&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;&lt;font color="#ff00ff"&gt;store_true&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;, dest=&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;&lt;font color="#ff00ff"&gt;verbose&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;, default=False,
        help=&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;&lt;font color="#ff00ff"&gt;verbose output&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;)
    (options, args) = parser.parse_args(sys.argv[1:])

    limit = options.limit

    items = [(get_size(arg), arg) &lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt; arg &lt;font color="#a52a2a"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt; args]

    collections = mix_and_match(limit, items, options.verbose)
    collections.sort(&lt;font color="#a52a2a"&gt;&lt;b&gt;lambda&lt;/b&gt;&lt;/font&gt; (xsize, xnames), (ysize, ynames): -cmp(xsize, ysize))
    &lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; options.show != 0:
        collections = collections[0:options.show]

    &lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt; size, names &lt;font color="#a52a2a"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt; collections:
        percentage = 100.0*float(size)/float(limit)
        &lt;font color="#a52a2a"&gt;&lt;b&gt;try&lt;/b&gt;&lt;/font&gt;:
            sys.stdout.write(&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;&lt;font color="#ff00ff"&gt;%10d&lt;/font&gt;&lt;font color="#6a5acd"&gt;\t&lt;/font&gt;&lt;font color="#ff00ff"&gt;%02.2f%%&lt;/font&gt;&lt;font color="#6a5acd"&gt;\t&lt;/font&gt;&lt;font color="#ff00ff"&gt;%s&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt; % (size, percentage, &lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;&lt;font color="#ff00ff"&gt; &lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;&amp;quot;&lt;/span&gt;.join(names)))
        &lt;font color="#a52a2a"&gt;&lt;b&gt;except&lt;/b&gt;&lt;/font&gt; IOError:
            &lt;font color="#0000ff"&gt;# ignore broken pipe&lt;/font&gt;
            &lt;font color="#a52a2a"&gt;&lt;b&gt;pass&lt;/b&gt;&lt;/font&gt;


&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; __name__ == &lt;span style="background-color: #f2f2f2"&gt;'&lt;/span&gt;&lt;font color="#ff00ff"&gt;__main__&lt;/font&gt;&lt;span style="background-color: #f2f2f2"&gt;'&lt;/span&gt;:
    main()
&lt;/pre&gt;

&lt;p&gt;This script has also been posted as a &lt;a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/475169"&gt;Python Cookbook Recipe&lt;/a&gt;.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/114173026228649352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=114173026228649352' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/114173026228649352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/114173026228649352'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2006/03/mixnmatching.html' title='Mix&apos;n&apos;matching'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-114070967254960188</id><published>2006-02-23T15:12:00.000Z</published><updated>2006-10-30T22:54:54.051Z</updated><title type='text'>Using rrdtool to monitor traffic on different schedules</title><content type='html'>&lt;p&gt;I upgraded my broadband connection to one where there is no traffic limit during the night (appropriately referred by my ISP as "happy hours"!). I was already using &lt;a href="http://people.ee.ethz.ch/%7Eoetiker/webtools/rrdtool/"&gt;rrdtool&lt;/a&gt; to monitor the total incoming traffic of my router, but now I wanted to separate the traffic according to a schedule.&lt;/p&gt;

&lt;p&gt;It was obvious that at least two data sources are needed: one for the &lt;span style="font-style: italic;"&gt;normal&lt;/span&gt; (limited) traffic and another for the &lt;span style="font-style: italic;"&gt;happy&lt;/span&gt; (unlimited) traffic. The first (naive) approach was to create these two data sources plus an automatically computed total data source, as&lt;/p&gt;
&lt;pre&gt;
rrdtool create &lt;font color="#a020f0"&gt;$RRD&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  &lt;font color="#6a5acd"&gt;-s&lt;/font&gt; &lt;font color="#a020f0"&gt;$STEP&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  DS:normal:COUNTER:&lt;font color="#a020f0"&gt;$HEARTBEAT&lt;/font&gt;:&lt;font color="#a020f0"&gt;$MIN&lt;/font&gt;:&lt;font color="#a020f0"&gt;$MAX&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  DS:happy:COUNTER:&lt;font color="#a020f0"&gt;$HEARTBEAT&lt;/font&gt;:&lt;font color="#a020f0"&gt;$MIN&lt;/font&gt;:&lt;font color="#a020f0"&gt;$MAX&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  DS:total:COMPUTE:normal,happy,+ &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  RRA:AVERAGE:&lt;font color="#a020f0"&gt;$XFF&lt;/font&gt;:&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;$(&lt;/font&gt;&lt;/span&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$STEP&lt;/font&gt;&lt;font color="#6a5acd"&gt;/&lt;/font&gt;&lt;font color="#a020f0"&gt;$STEP&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;)&lt;/font&gt;&lt;/span&gt;:&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;$(&lt;/font&gt;&lt;/span&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt;2&lt;/font&gt;&lt;font color="#6a5acd"&gt;*&lt;/font&gt;&lt;font color="#a020f0"&gt;$DAY&lt;/font&gt;&lt;font color="#6a5acd"&gt;/&lt;/font&gt;&lt;font color="#a020f0"&gt;$STEP&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;)&lt;/font&gt;&lt;/span&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  RRA:AVERAGE:&lt;font color="#a020f0"&gt;$XFF&lt;/font&gt;:&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;$(&lt;/font&gt;&lt;/span&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$HOUR&lt;/font&gt;&lt;font color="#6a5acd"&gt;/&lt;/font&gt;&lt;font color="#a020f0"&gt;$STEP&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;)&lt;/font&gt;&lt;/span&gt;:&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;$(&lt;/font&gt;&lt;/span&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt;2&lt;/font&gt;&lt;font color="#6a5acd"&gt;*&lt;/font&gt;&lt;font color="#a020f0"&gt;$MONTH&lt;/font&gt;&lt;font color="#6a5acd"&gt;/&lt;/font&gt;&lt;font color="#a020f0"&gt;$HOUR&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;)&lt;/font&gt;&lt;/span&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  RRA:AVERAGE:&lt;font color="#a020f0"&gt;$XFF&lt;/font&gt;:&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;$(&lt;/font&gt;&lt;/span&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$DAY&lt;/font&gt;&lt;font color="#6a5acd"&gt;/&lt;/font&gt;&lt;font color="#a020f0"&gt;$STEP&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;)&lt;/font&gt;&lt;/span&gt;:&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;$(&lt;/font&gt;&lt;/span&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt;2&lt;/font&gt;&lt;font color="#6a5acd"&gt;*&lt;/font&gt;&lt;font color="#a020f0"&gt;$YEAR&lt;/font&gt;&lt;font color="#6a5acd"&gt;/&lt;/font&gt;&lt;font color="#a020f0"&gt;$DAY&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;)&lt;/font&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;and feed either according to the current time of the day:&lt;/p&gt;
&lt;pre&gt;
&lt;font color="#008b8b"&gt;TIME&lt;/font&gt;=N
&lt;font color="#008b8b"&gt;COUNTER&lt;/font&gt;=&lt;font color="#6a5acd"&gt;`snmpget ...`&lt;/font&gt;

&lt;font color="#008b8b"&gt;TIMEOFDAY&lt;/font&gt;=&lt;font color="#6a5acd"&gt;`date +&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt;%H%M&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;`&lt;/font&gt;
&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;[&lt;/b&gt;&lt;/font&gt; &lt;font color="#a020f0"&gt;$TIMEOFDAY&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;-gt&lt;/b&gt;&lt;/font&gt; &lt;font color="#a020f0"&gt;$HAPPYSTART&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;-a&lt;/b&gt;&lt;/font&gt; &lt;font color="#a020f0"&gt;$TIMEOFDAY&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;-le&lt;/b&gt;&lt;/font&gt; &lt;font color="#a020f0"&gt;$HAPPYEND&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;]&lt;/b&gt;&lt;/font&gt;
&lt;font color="#a52a2a"&gt;&lt;b&gt;then&lt;/b&gt;&lt;/font&gt;
    &lt;font color="#008b8b"&gt;NORMAL&lt;/font&gt;=&lt;font color="#ff00ff"&gt;0&lt;/font&gt;
    &lt;font color="#008b8b"&gt;HAPPY&lt;/font&gt;=&lt;font color="#a020f0"&gt;$COUNTER&lt;/font&gt;
&lt;font color="#a52a2a"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/font&gt;
    &lt;font color="#008b8b"&gt;NORMAL&lt;/font&gt;=&lt;font color="#a020f0"&gt;$COUNTER&lt;/font&gt;
    &lt;font color="#008b8b"&gt;HAPPY&lt;/font&gt;=&lt;font color="#ff00ff"&gt;0&lt;/font&gt;
&lt;font color="#a52a2a"&gt;&lt;b&gt;fi&lt;/b&gt;&lt;/font&gt;

rrdtool update &lt;font color="#a020f0"&gt;$RRD&lt;/font&gt; &lt;font color="#a020f0"&gt;$TIME&lt;/font&gt;:&lt;font color="#a020f0"&gt;$NORMAL&lt;/font&gt;:&lt;font color="#a020f0"&gt;$HAPPY&lt;/font&gt;
&lt;/pre&gt;
&lt;p&gt;where HAPPYSTART and TIMEOFDAY have the happy hour start and end times in &lt;span style="font-style:italic;"&gt;hhmm&lt;/span&gt; format.&lt;/p&gt;

&lt;p&gt;However this does not work as expected due to the way rrdtool treats the COUNTER data sources, and the impact of the schedule transition on such treatment. For illustration purposes, suppose in one instant t1 the counter value is 1000 bytes and in the normal schedule, and the next instant t2 the counter value is 1001 bytes but on the happy schedule. The updates will be&lt;/p&gt;
&lt;pre&gt;
t1:1000:0
t2:0:1001
&lt;/pre&gt;
&lt;p&gt;but rrdtool will see and count the happy counter vary from 0 to 1001, therefore counting 1001 bytes, and not the correct value of 1 byte!&lt;/p&gt;

&lt;p&gt;The solution is have only &lt;span style="font-weight:bold;"&gt;one&lt;/span&gt; COUNTER, and separate the traffic kind using a factor in the [0, 1] range as:&lt;/p&gt;


&lt;pre&gt;
rrdtool create &lt;font color="#a020f0"&gt;$RRD&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  &lt;font color="#6a5acd"&gt;-s&lt;/font&gt; &lt;font color="#a020f0"&gt;$STEP&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  DS:total:COUNTER:&lt;font color="#a020f0"&gt;$HEARTBEAT&lt;/font&gt;:&lt;font color="#a020f0"&gt;$MIN&lt;/font&gt;:&lt;font color="#a020f0"&gt;$MAX&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  DS:ratio:GAUGE:&lt;font color="#a020f0"&gt;$HEARTBEAT&lt;/font&gt;:&lt;font color="#ff00ff"&gt;0&lt;/font&gt;:&lt;font color="#ff00ff"&gt;1&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  DS:normal:COMPUTE:total,ratio,* &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  DS:happy:COMPUTE:total,&lt;font color="#ff00ff"&gt;1&lt;/font&gt;,ratio,-,* &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  RRA:AVERAGE:&lt;font color="#a020f0"&gt;$XFF&lt;/font&gt;:&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;$(&lt;/font&gt;&lt;/span&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$STEP&lt;/font&gt;&lt;font color="#6a5acd"&gt;/&lt;/font&gt;&lt;font color="#a020f0"&gt;$STEP&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;)&lt;/font&gt;&lt;/span&gt;:&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;$(&lt;/font&gt;&lt;/span&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt;2&lt;/font&gt;&lt;font color="#6a5acd"&gt;*&lt;/font&gt;&lt;font color="#a020f0"&gt;$DAY&lt;/font&gt;&lt;font color="#6a5acd"&gt;/&lt;/font&gt;&lt;font color="#a020f0"&gt;$STEP&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;)&lt;/font&gt;&lt;/span&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  RRA:AVERAGE:&lt;font color="#a020f0"&gt;$XFF&lt;/font&gt;:&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;$(&lt;/font&gt;&lt;/span&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$HOUR&lt;/font&gt;&lt;font color="#6a5acd"&gt;/&lt;/font&gt;&lt;font color="#a020f0"&gt;$STEP&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;)&lt;/font&gt;&lt;/span&gt;:&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;$(&lt;/font&gt;&lt;/span&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt;2&lt;/font&gt;&lt;font color="#6a5acd"&gt;*&lt;/font&gt;&lt;font color="#a020f0"&gt;$MONTH&lt;/font&gt;&lt;font color="#6a5acd"&gt;/&lt;/font&gt;&lt;font color="#a020f0"&gt;$HOUR&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;)&lt;/font&gt;&lt;/span&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;\&lt;/b&gt;&lt;/font&gt;
  RRA:AVERAGE:&lt;font color="#a020f0"&gt;$XFF&lt;/font&gt;:&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;$(&lt;/font&gt;&lt;/span&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/font&gt;&lt;font color="#a020f0"&gt;$DAY&lt;/font&gt;&lt;font color="#6a5acd"&gt;/&lt;/font&gt;&lt;font color="#a020f0"&gt;$STEP&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;)&lt;/font&gt;&lt;/span&gt;:&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;$(&lt;/font&gt;&lt;/span&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt;2&lt;/font&gt;&lt;font color="#6a5acd"&gt;*&lt;/font&gt;&lt;font color="#a020f0"&gt;$YEAR&lt;/font&gt;&lt;font color="#6a5acd"&gt;/&lt;/font&gt;&lt;font color="#a020f0"&gt;$DAY&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;&lt;span style="background-color: #ff0000"&gt;&lt;font color="#ffffff"&gt;)&lt;/font&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;and for the update:&lt;/p&gt;
&lt;pre&gt;
&lt;font color="#008b8b"&gt;TIME&lt;/font&gt;=N
&lt;font color="#008b8b"&gt;COUNTER&lt;/font&gt;=&lt;font color="#6a5acd"&gt;`snmpget ...`&lt;/font&gt;

&lt;font color="#008b8b"&gt;TIMEOFDAY&lt;/font&gt;=&lt;font color="#6a5acd"&gt;`date +&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff00ff"&gt;%H%M&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;`&lt;/font&gt;
&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;[&lt;/b&gt;&lt;/font&gt; &lt;font color="#a020f0"&gt;$TIMEOFDAY&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;-gt&lt;/b&gt;&lt;/font&gt; &lt;font color="#a020f0"&gt;$HAPPYSTART&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;-a&lt;/b&gt;&lt;/font&gt; &lt;font color="#a020f0"&gt;$TIMEOFDAY&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;-le&lt;/b&gt;&lt;/font&gt; &lt;font color="#a020f0"&gt;$HAPPYEND&lt;/font&gt; &lt;font color="#a52a2a"&gt;&lt;b&gt;]&lt;/b&gt;&lt;/font&gt;
&lt;font color="#a52a2a"&gt;&lt;b&gt;then&lt;/b&gt;&lt;/font&gt;
    &lt;font color="#008b8b"&gt;RATIO&lt;/font&gt;=&lt;font color="#ff00ff"&gt;0&lt;/font&gt;
&lt;font color="#a52a2a"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/font&gt;
    &lt;font color="#008b8b"&gt;RATIO&lt;/font&gt;=&lt;font color="#ff00ff"&gt;1&lt;/font&gt;
&lt;font color="#a52a2a"&gt;&lt;b&gt;fi&lt;/b&gt;&lt;/font&gt;

rrdtool update &lt;font color="#a020f0"&gt;$RRD&lt;/font&gt; &lt;font color="#a020f0"&gt;$TIME&lt;/font&gt;:&lt;font color="#a020f0"&gt;$COUNTER&lt;/font&gt;:&lt;font color="#a020f0"&gt;$RATIO&lt;/font&gt;
&lt;/pre&gt;

&lt;p&gt;With this I get nice pictures such as this one:&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/7495/883/1600/adsl-daily.1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/7495/883/400/adsl-daily.jpg" border="0" alt="" /&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://jrfonseca.blogspot.com/feeds/114070967254960188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11077412&amp;postID=114070967254960188' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/114070967254960188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/114070967254960188'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2006/02/using-rrdtool-to-monitor-traffic-on.html' title='Using rrdtool to monitor traffic on different schedules'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11077412.post-110934620380272485</id><published>2005-02-25T15:26:00.000Z</published><updated>2006-10-30T22:54:53.980Z</updated><title type='text'>First post!</title><content type='html'>&lt;p&gt;So I've finally created a blog...&lt;/p&gt;

&lt;p&gt;I'm not sure yet what sort of stuff I want to write about (Nem tenho a certeza que língua usar!)  but I hope the answer eventually comes to me and that this blog becomes something useful to me or others.&lt;/p&gt;

&lt;p&gt;At the very least I've got a hold of the blogspot address with my name! :)&lt;/p&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/110934620380272485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11077412/posts/default/110934620380272485'/><link rel='alternate' type='text/html' href='http://jrfonseca.blogspot.com/2005/02/first-post.html' title='First post!'/><author><name>José Fonseca</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry></feed>