On 26 April 2012 16:40, Chad Versace <span dir="ltr">&lt;<a href="mailto:chad.versace@linux.intel.com" target="_blank">chad.versace@linux.intel.com</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
A few comments below.<br>
<div><div class="h5"><br>
On 04/24/2012 12:23 PM, Paul Berry wrote:<br>
&gt; When rendering to a miplevel other than 0 within a color, depth,<br>
&gt; stencil, or HiZ buffer, we need to tell the GPU to render to an offset<br>
&gt; within the buffer, so that the data is written into the correct<br>
&gt; miplevel.  We do this using a coarse offset (in pages), and a fine<br>
&gt; adjustment (the so-called &quot;tile_x&quot; and &quot;tile_y&quot; values, which are<br>
&gt; measured in pixels).<br>
&gt;<br>
&gt; We have always computed the coarse offset and fine adjustment using<br>
&gt; intel_renderbuffer_tile_offsets() function.  This worked fine for<br>
&gt; color and combined depth/stencil buffers, but failed to work properly<br>
&gt; when HiZ and separate stencil were in use.  It failed to work because<br>
&gt; there is only one set of fine adjustment controls shared by the HiZ,<br>
&gt; depth, and stencil buffers, so we need to choose tile_x and tile_y<br>
&gt; values that are compatible with the tiling of all three buffers, and<br>
&gt; then compute separate coarse offsets for each buffer.<br>
&gt;<br>
&gt; This patch fixes the HiZ and separate stencil case by replacing the<br>
&gt; call to intel_renderbuffer_tile_offsets() with calls to two functions:<br>
&gt; intel_region_get_tile_masks(), which determines how much of the<br>
&gt; adjustment can be performed using offsets and how much can be<br>
&gt; performed using tile_x and tile_y, and<br>
&gt; intel_region_get_aligned_offset(), which computes the coarse offset.<br>
&gt;<br>
&gt; intel_region_get_tile_offsets() is still used for color renderbuffers,<br>
&gt; so to avoid code duplication, I&#39;ve re-worked it to use<br>
&gt; intel_region_get_tile_masks() and intel_region_get_aligned_offset().<br>
&gt;<br>
&gt; On i965 Gen6, fixes piglit tests<br>
&gt; &quot;texturing/depthstencil-render-miplevels 1024 X&quot; where X is one of<br>
&gt; (depth, depth_and_stencil, depth_stencil_single_binding, depth_x,<br>
&gt; depth_x_and_stencil, stencil, stencil_and_depth, stencil_and_depth_x).<br>
&gt;<br>
&gt; On i965 Gen7, the variants of<br>
&gt; &quot;texturing/depthstencil-render-miplevels&quot; that contain a stencil<br>
&gt; buffer still fail, due to another problem: Gen7 seems to ignore the 3<br>
&gt; LSB&#39;s of the tile_y adjustment (and possibly also tile_x).<br>
&gt; ---<br>
&gt;  src/mesa/drivers/dri/i965/brw_misc_state.c  |   96 ++++++++++++++++++++++++--<br>
&gt;  src/mesa/drivers/dri/i965/gen6_hiz.c        |   54 +++++++++++----<br>
&gt;  src/mesa/drivers/dri/i965/gen7_hiz.c        |   54 +++++++++++----<br>
&gt;  src/mesa/drivers/dri/i965/gen7_misc_state.c |   79 ++++++++++++++++++++--<br>
&gt;  src/mesa/drivers/dri/intel/intel_fbo.c      |   27 ++-----<br>
&gt;  src/mesa/drivers/dri/intel/intel_fbo.h      |   28 ++++++++<br>
&gt;  src/mesa/drivers/dri/intel/intel_regions.c  |   52 ++++++++++++++<br>
&gt;  src/mesa/drivers/dri/intel/intel_regions.h  |    8 ++<br>
&gt;  8 files changed, 338 insertions(+), 60 deletions(-)<br>
<br>
</div></div>[snip]<br>
<div><div class="h5"><br>
&gt; diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h<br>
&gt; index 724f141..503b006 100644<br>
&gt; --- a/src/mesa/drivers/dri/intel/intel_fbo.h<br>
&gt; +++ b/src/mesa/drivers/dri/intel/intel_fbo.h<br>
&gt; @@ -153,6 +153,34 @@ intel_flip_renderbuffers(struct gl_framebuffer *fb);<br>
&gt;  void<br>
&gt;  intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb);<br>
&gt;<br>
&gt; +void<br>
&gt; +intel_renderbuffer_fine_offset_masks(struct intel_renderbuffer *irb,<br>
&gt; +                                     uint32_t *fine_offset_mask_x,<br>
&gt; +                                     uint32_t *fine_offset_mask_y);<br>
&gt; +<br>
&gt; +/**<br>
&gt; + * When rendering to a texture with multiple miplevels, depth planes, or cube<br>
&gt; + * faces, we need to instruct the GPU to render to an offset within the<br>
&gt; + * texture image corresponding to the appropriate miplevel/plane/cubeface.  We<br>
&gt; + * do this by a combination of two techniques: by offsetting the base address<br>
&gt; + * of the texture image, and by supplying additional X and Y coordinate<br>
&gt; + * offsets to the GPU in the SURFACE_STATE structure.<br>
&gt; + *<br>
&gt; + * This function computes the additional Y coordinate offset.<br>
&gt; + */<br>
&gt; +<br>
&gt; +/**<br>
&gt; + * When rendering to a texture with multiple miplevels, depth planes, or cube<br>
&gt; + * faces, we need to instruct the GPU to render to an offset within the<br>
&gt; + * texture image corresponding to the appropriate miplevel/plane/cubeface.  We<br>
&gt; + * do this by a combination of two techniques: by offsetting the base address<br>
&gt; + * of the texture image, and by supplying additional X and Y coordinate<br>
&gt; + * offsets to the GPU in the SURFACE_STATE structure.<br>
&gt; + *<br>
&gt; + * This function computes the additional X coordinate offset.<br>
&gt; + */<br>
&gt; +<br>
&gt; +<br>
&gt;  uint32_t<br>
&gt;  intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,<br>
&gt;                               uint32_t *tile_x,<br>
<br>
</div></div>Dangling comments above.<br></blockquote><div><br>Oh, yeah.  Those were left over from an old draft of the code.  Removed.<br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<br>
[snip]<br>
<div class="im"><br>
&gt; +/**<br>
&gt; + * Compute the offset (in bytes) from the start of the region to the given x<br>
&gt; + * and y coordinate.  For tiled regions, caller must ensure that x and y are<br>
&gt; + * multiples of the tile size.<br>
&gt; + */<br>
<br>
</div>I think this function needs to assert the preconditions for x and y. It&#39;s<br>
just too easy for a caller to forget the precondition and hence introduce<br>
an easily avoided bug.<br></blockquote><div><br>Good point.<br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div class="im"><br>
&gt; +uint32_t<br>
&gt; +intel_region_get_aligned_offset(struct intel_region *region, uint32_t x,<br>
&gt; +                                uint32_t y)<br>
&gt; +{<br>
&gt; +   int cpp = region-&gt;cpp;<br>
&gt; +   uint32_t pitch = region-&gt;pitch * cpp;<br>
&gt; +<br>
&gt; +   switch (region-&gt;tiling) {<br>
&gt; +   default:<br>
&gt; +      assert(false);<br>
&gt; +   case I915_TILING_NONE:<br>
&gt; +      return y * pitch + x * cpp;<br>
&gt; +   case I915_TILING_X:<br>
&gt; +      return y * pitch + x / (512 / cpp) * 4096;<br>
&gt; +   case I915_TILING_Y:<br>
&gt; +      return y * pitch + x / (128 / cpp) * 4096;<br>
&gt; +   }<br>
&gt; +}<br>
<br>
</div>One more thing. It would be nice if the duplicate offset code in<br>
gen6_hiz.c and gen7_hiz.c were consolidated into a helper function...<br>
but, meh. I don&#39;t care that much.<br>
</blockquote></div><br>Yeah, good point.  This is somewhat improved after all of the refactoring I did for MSAA.  Tell you what, once the dust settles from that, let&#39;s have another look and see if it&#39;s still worth consolidating more of the code.<br>
<br>Updated patch to follow.<br>