<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sat, Jan 21, 2017 at 11:12 AM, Pohjolainen, Topi <span dir="ltr"><<a href="mailto:topi.pohjolainen@gmail.com" target="_blank">topi.pohjolainen@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Sat, Jan 21, 2017 at 11:05:52AM -0800, Jason Ekstrand wrote:<br>
> On Sat, Jan 21, 2017 at 1:19 AM, Pohjolainen, Topi<br>
</span><span class="">> <[1]<a href="mailto:topi.pohjolainen@gmail.com">topi.pohjolainen@gmail.com</a><wbr>> wrote:<br>
><br>
> On Fri, Jan 20, 2017 at 04:35:23PM -0800, Jason Ekstrand wrote:<br>
> > On Mon, Jan 16, 2017 at 1:13 AM, Topi Pohjolainen<br>
</span><span class="">> > <[1][2]<a href="mailto:topi.pohjolainen@gmail.com">topi.pohjolainen@gmail.<wbr>com</a>> wrote:<br>
> ><br>
> > This is kept on purpose in i965. It can be moved to ISL if it<br>
> > is needed in vulkan.<br>
> > Pointers to miptrees are given solely for verification<br>
> purposes.<br>
> > These will be dropped in following patches.<br>
> > Signed-off-by: Topi Pohjolainen<br>
</span>> <[2][3]<a href="mailto:topi.pohjolainen@intel.com">topi.pohjolainen@intel.<wbr>com</a>><br>
<div><div class="h5">><br>
> > ---<br>
> > src/mesa/drivers/dri/i965/brw_<wbr>tex_layout.c | 65<br>
> > +++++++++++++++++++++++++++<br>
> > src/mesa/drivers/dri/i965/<wbr>gen6_depth_state.c | 14 +++---<br>
> > src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.h | 5 +++<br>
> > 3 files changed, 78 insertions(+), 6 deletions(-)<br>
> > diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_tex_layout.c<br>
> > b/src/mesa/drivers/dri/i965/<wbr>brw_tex_layout.c<br>
> > index 768f8a8..80b341a 100644<br>
> > --- a/src/mesa/drivers/dri/i965/<wbr>brw_tex_layout.c<br>
> > +++ b/src/mesa/drivers/dri/i965/<wbr>brw_tex_layout.c<br>
> > @@ -288,6 +288,71 @@ gen9_miptree_layout_1d(struct<br>
> intel_mipmap_tree<br>
> > *mt)<br>
> > }<br>
> > }<br>
> > +static unsigned<br>
> > +all_slices_at_each_lod_x_<wbr>offset(unsigned w0, unsigned align,<br>
> > unsigned level)<br>
> > +{<br>
> > + const unsigned w = level >= 2 ? minify(w0, 1) : 0;<br>
> > + return ALIGN(w, align);<br>
> > +}<br>
> > +<br>
> > +static unsigned<br>
> > +all_slices_at_each_lod_y_<wbr>offset(const struct isl_extent4d<br>
> > *phys_level0_sa,<br>
> > + enum isl_surf_dim dim, unsigned<br>
> > align,<br>
> > + unsigned level)<br>
> > +{<br>
> > + unsigned y = 0;<br>
> > +<br>
> > + /* Add vertical space taken by lower levels one by one.<br>
> Levels<br>
> > one and two<br>
> > + * are side-by-side just below level zero. Levels three and<br>
> > greater are<br>
> > + * stacked one after another below level two.<br>
> > + */<br>
> > + for (unsigned i = 1; i <= level; ++i) {<br>
> > + const unsigned d = dim == ISL_SURF_DIM_3D ?<br>
> > + minify(phys_level0_sa->depth, i - 1) :<br>
> > + phys_level0_sa->array_len;<br>
> > +<br>
> > + /* Levels two and greater are stacked just below level<br>
> zero.<br>
> > */<br>
> > + if (i != 2) {<br>
> > + const unsigned h = minify(phys_level0_sa->height, i -<br>
> 1);<br>
> > + y += d * ALIGN(h, align);<br>
> > + }<br>
> > + }<br>
> > +<br>
> > + return y;<br>
> > +}<br>
> > +<br>
> > +uint32_t<br>
> > +brw_stencil_all_slices_at_<wbr>each_lod_offset(const struct isl_surf<br>
> > *surf,<br>
> > + const struct<br>
> > intel_mipmap_tree *mt,<br>
> > + unsigned level)<br>
> > +{<br>
> > + assert(mt->array_layout == ALL_SLICES_AT_EACH_LOD);<br>
> > +<br>
> > + const unsigned halign = 64;<br>
> > + const unsigned valign = 64;<br>
> > + const unsigned level_x = all_slices_at_each_lod_x_<wbr>offset(<br>
> > + surf->phys_level0_sa.width, halign, level);<br>
> > + const unsigned level_y = all_slices_at_each_lod_y_<wbr>offset(<br>
> > + &surf->phys_level0_sa, surf->dim, valign, level);<br>
> > +<br>
> > + assert(level_x == mt->level[level].level_x);<br>
> > + assert(level_y == mt->level[level].level_y);<br>
> > +<br>
> > + /* From Vol 2a, 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field<br>
> > "Surface Pitch":<br>
> > + * The pitch must be set to 2x the value computed based<br>
> on<br>
> > width, as<br>
> > + * the stencil buffer is stored with two rows<br>
> interleaved.<br>
> > + *<br>
> > + * While ISL surface stores the pitch expected by hardware,<br>
> the<br>
> > offset<br>
> > + * into individual slices needs to be calculated as if rows<br>
> are<br>
> > + * interleaved.<br>
> > + */<br>
> > + const unsigned two_rows_interleaved_pitch = surf->row_pitch<br>
> / 2;<br>
> > +<br>
> > + assert(two_rows_interleaved_<wbr>pitch == mt->pitch);<br>
> > +<br>
> > + return level_y * two_rows_interleaved_pitch + level_x * 64;<br>
> > +}<br>
> ><br>
> > There's really no good place in this series to make this comment<br>
> but I<br>
> > think this is as good as I'm going to get...<br>
> > I can't quite tell what your long-term plan is for gen6 stencil<br>
> and<br>
> > HiZ. Eventually, I'd like to kill the ALL_SLICES_AT_EACH_LOD<br>
> stuff.<br>
> > The only reason why Jordan and the Igalia people did that in the<br>
> first<br>
> > place was so that they could re-use existing surface calculation<br>
> code.<br>
> > Really, the requirement is that gen6 doesn't support multiple<br>
> miplevels<br>
> > with HiZ and Stencil even though it does support arrays. The<br>
> point of<br>
> > the ALL_SLICES_AT_EACH_LOD layout is to, instead of making it an<br>
> array<br>
> > of miptrees, it lays it out into a bunch of single-LOD arrays.<br>
> The<br>
> > fact that they happen to be layed out like a miptree is<br>
> immaterial.<br>
> > When Nanley and I were talking about this in the office, he had a<br>
> very<br>
> > good suggestion. What he suggested was to just have an array of<br>
> > isl_surf's, one for each miplevel and lay the single-LOD arrays<br>
> out<br>
> > linearly in memory. To compute the size of the gen6 stencil or<br>
> HiZ<br>
> > buffer you would do something like this;<br>
> > uint32_t size = 0;<br>
> > for (level = 0; level < num_levels; level++) {<br>
> > isl_surf_init(&mt->gen6_per_<wbr>level[level].surf,<br>
> > .width = minify(width, level),<br>
> > .height = minify(height, level),<br>
> > .depth = 1,<br>
> > .levels = 1,<br>
> > .array_len = array_len,<br>
> > .format = ISL_FORMAT_HIZ,<br>
> > ...);<br>
> > mt->gen6_per_level[level].<wbr>offset = size;<br>
> > size += mt->gen6_per_level[level].<wbr>surf.size;<br>
> > }<br>
> > Then in the gen6 hiz and stencil setup code, you would just offset<br>
> it<br>
> > by mt->gen6_per_level[level].<wbr>offset and be done with it. There's<br>
> no<br>
> > real reason why we need to keep all this ALL_SLICES_AT_EACH_LOD<br>
> > calculation stuff indefinitely. We just need some way of putting<br>
> all<br>
> > of the per-LOD images in the same BO. (Technically, they don't<br>
> even<br>
> > need to go in the same BO but it's kind of nice to do it that<br>
> way.)<br>
> > Thoughts?<br>
><br>
> This might be becoming a matter of taste debate. I'm probably<br>
> thinking too<br>
> much from "what does the hw setup need"-point of view. I'm thinking<br>
> that<br>
> as the hw really only wants offset and row pitch why do we need to<br>
> maintain<br>
> all the extra information. This is afterall something that can be<br>
> calculated<br>
> relatively straight forward if needs be. And the need is not clear -<br>
> as hw<br>
> setup don't need it, what is it for? Accessing individual slices<br>
> using cpu<br>
> is also just about the offset and shifting the base level<br>
> dimensions.<br>
> Also continuing with matter of taste. I'm not a big fan of storing<br>
> information<br>
> in tables if it is used infrequently and rather cheap to produce<br>
> on-demand.<br>
> (I'm seeing the array of isl_surf instances as a pre-computed lookup<br>
> table).<br>
><br>
> Honestly, I'm not married to the idea of storing all of the isl_surf's<br>
> for each slice. We can store them or not. It was mostly about laying<br>
> things out sequentially in memory rather than trying to place all of<br>
> these single-LOD arrays in some sort of 2-D mipmap layout. Among other<br>
> things, doing so wastes space compared to just storing the different<br>
> LODs sequentially. Also, it makes for a bunch of painful calculations<br>
> that we're doing for really no good reason. The calculation for the<br>
> offset could be just a sum of the sizes of the previous miplevels.<br>
<br>
</div></div>I do like the idea of laying them out sequentially - like you said, current<br>
layout doesn't serve anything, it just makes the calculations unnecessaryly<br>
complex.<br>
<br>
I can work on that change, but initially to me it seems safer on top of what I<br>
have here. I'll look into it some more.<br>
</blockquote></div><br></div><div class="gmail_extra">That's perfectly reasonable. Let's just keep going and, now that we have all the helpers, making that change won't be hard. I just wanted to make sure we were on the same page before I started diving into detailed review of gen6 miptree layout calculation code. :-)<br><br></div><div class="gmail_extra">One other note: This would me we would have a different pitch per LOD. That's a bit annoying but probably not nearly as annoying as carying around a bunch of 2D layout code we don't need.<br></div></div>