<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sat, Jan 21, 2017 at 1:19 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 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]<a href="mailto:topi.pohjolainen@gmail.com">topi.pohjolainen@gmail.com</a><wbr>> 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 purposes.<br>
> These will be dropped in following patches.<br>
</span>> Signed-off-by: Topi Pohjolainen <[2]<a href="mailto:topi.pohjolainen@intel.com">topi.pohjolainen@intel.com</a><wbr>><br>
<div><div class="h5">> ---<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 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. 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 zero.<br>
> */<br>
> + if (i != 2) {<br>
> + const unsigned h = minify(phys_level0_sa->height, i - 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 on<br>
> width, as<br>
> + * the stencil buffer is stored with two rows interleaved.<br>
> + *<br>
> + * While ISL surface stores the pitch expected by hardware, the<br>
> offset<br>
> + * into individual slices needs to be calculated as if rows are<br>
> + * interleaved.<br>
> + */<br>
> + const unsigned two_rows_interleaved_pitch = surf->row_pitch / 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 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 and<br>
> HiZ. Eventually, I'd like to kill the ALL_SLICES_AT_EACH_LOD stuff.<br>
> The only reason why Jordan and the Igalia people did that in the first<br>
> place was so that they could re-use existing surface calculation code.<br>
> Really, the requirement is that gen6 doesn't support multiple miplevels<br>
> with HiZ and Stencil even though it does support arrays. The point of<br>
> the ALL_SLICES_AT_EACH_LOD layout is to, instead of making it an array<br>
> of miptrees, it lays it out into a bunch of single-LOD arrays. The<br>
> fact that they happen to be layed out like a miptree is immaterial.<br>
> When Nanley and I were talking about this in the office, he had a 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 out<br>
> linearly in memory. To compute the size of the gen6 stencil or 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 it<br>
> by mt->gen6_per_level[level].<wbr>offset and be done with it. There's 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 all<br>
> of the per-LOD images in the same BO. (Technically, they don't even<br>
> need to go in the same BO but it's kind of nice to do it that way.)<br>
> Thoughts?<br>
<br>
</div></div>This might be becoming a matter of taste debate. I'm probably thinking too<br>
much from "what does the hw setup need"-point of view. I'm thinking that<br>
as the hw really only wants offset and row pitch why do we need to maintain<br>
all the extra information. This is afterall something that can be calculated<br>
relatively straight forward if needs be. And the need is not clear - as hw<br>
setup don't need it, what is it for? Accessing individual slices using cpu<br>
is also just about the offset and shifting the base level dimensions.<br>
<br>
Also continuing with matter of taste. I'm not a big fan of storing information<br>
in tables if it is used infrequently and rather cheap to produce on-demand.<br>
(I'm seeing the array of isl_surf instances as a pre-computed lookup table).<br></blockquote><div><br></div><div>Honestly, I'm not married to the idea of storing all of the isl_surf's for each slice. We can store them or not. It was mostly about laying things out sequentially in memory rather than trying to place all of these single-LOD arrays in some sort of 2-D mipmap layout. Among other things, doing so wastes space compared to just storing the different LODs sequentially. Also, it makes for a bunch of painful calculations that we're doing for really no good reason. The calculation for the offset could be just a sum of the sizes of the previous miplevels.<br></div></div></div></div>