<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 5, 2016 at 5:04 PM, Kristian Høgsberg <span dir="ltr"><<a href="mailto:krh@bitplanet.net" target="_blank">krh@bitplanet.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Kristian Høgsberg Kristensen <<a href="mailto:kristian.h.kristensen@intel.com">kristian.h.kristensen@intel.com</a>><br>
<br>
This lowers sampling from YUV textures to 1) one or more texture<br>
instructions to sample each plane and 2) color space conversion to RGB.<br>
---<br>
src/compiler/nir/nir.h | 7 +++<br>
src/compiler/nir/nir_lower_tex.c | 118 +++++++++++++++++++++++++++++++++++++++<br>
2 files changed, 125 insertions(+)<br>
<br>
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h<br>
index d85ea17..cf6d49d 100644<br>
--- a/src/compiler/nir/nir.h<br>
+++ b/src/compiler/nir/nir.h<br>
@@ -2273,6 +2273,13 @@ typedef struct nir_lower_tex_options {<br>
bool lower_rect;<br>
<br>
/**<br>
+ * If true, convert yuv to rgb.<br>
+ */<br>
+ unsigned lower_y_uv_external;<br>
+ unsigned lower_y_u_v_external;<br>
+ unsigned lower_yx_xuxv_external;<br>
+<br>
+ /**<br>
* To emulate certain texture wrap modes, this can be used<br>
* to saturate the specified tex coord to [0.0, 1.0]. The<br>
* bits are according to sampler #, ie. if, for example:<br>
diff --git a/src/compiler/nir/nir_lower_tex.c b/src/compiler/nir/nir_lower_tex.c<br>
index 16fee9a..c8aebb4 100644<br>
--- a/src/compiler/nir/nir_lower_tex.c<br>
+++ b/src/compiler/nir/nir_lower_tex.c<br>
@@ -167,6 +167,108 @@ lower_rect(nir_builder *b, nir_tex_instr *tex)<br>
tex->sampler_dim = GLSL_SAMPLER_DIM_2D;<br>
}<br>
<br>
+static nir_ssa_def *<br>
+sample_plane(nir_builder *b, nir_tex_instr *tex, int plane)<br>
+{<br>
+ assert(tex->dest.is_ssa);<br>
+ assert(nir_tex_instr_dest_size(tex) == 4);<br>
+ assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float);<br>
+ assert(tex->op == nir_texop_tex);<br>
+ assert(tex->coord_components == 2);<br>
+<br>
+ nir_tex_instr *plane_tex = nir_tex_instr_create(b->shader, 2);<br>
+ plane_tex->src[0].src = tex->src[0].src;<br></blockquote><div><br></div><div>You should use nir_src_copy here<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ plane_tex->src[0].src_type = nir_tex_src_coord;<br>
+ plane_tex->src[1].src = nir_src_for_ssa(nir_imm_int(b, plane));<br>
+ plane_tex->src[1].src_type = nir_tex_src_plane;<br>
+ plane_tex->op = nir_texop_tex;<br>
+ plane_tex->sampler_dim = 2;<br>
+ plane_tex->dest_type = nir_type_float;<br>
+ plane_tex->coord_components = 2;<br>
+<br>
+ plane_tex->texture_index = tex->texture_index;<br></blockquote><div><br></div><div>This should use nir_copy_deref. Right now, the deref is supposed to be ralloc parented to the instruciton so you have to make a copy. One of these days, I'm going to clean that up.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ plane_tex->texture = tex->texture;<br>
+ plane_tex->sampler_index = tex->sampler_index;<br>
+ plane_tex->sampler = tex->sampler;<br></blockquote><div><br></div><div>Same here<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+ nir_ssa_dest_init(&plane_tex->instr, &plane_tex->dest, 4, 32, NULL);<br>
+<br>
+ nir_builder_instr_insert(b, &plane_tex->instr);<br>
+<br>
+ return &plane_tex->dest.ssa;<br>
+}<br>
+<br>
+static void<br>
+convert_yuv_to_rgb(nir_builder *b, nir_tex_instr *tex,<br>
+ nir_ssa_def *y, nir_ssa_def *u, nir_ssa_def *v)<br>
+{<br>
+ nir_const_value m[3] = {<br>
+ { .f32 = { 1.0f, 0.0f, 1.59602678f, 0.0f } },<br>
+ { .f32 = { 1.0f, -0.39176229f, -0.81296764f, 0.0f } },<br>
+ { .f32 = { 1.0f, 2.01723214f, 0.0f, 0.0f } }<br>
+ };<br>
+<br>
+ nir_ssa_def *yuv =<br>
+ nir_vec4(b,<br>
+ nir_fmul(b, nir_imm_float(b, 1.16438356f),<br>
+ nir_fadd(b, y, nir_imm_float(b, -0.0625f))),<br>
+ nir_channel(b, nir_fadd(b, u, nir_imm_float(b, -0.5f)), 0),<br>
+ nir_channel(b, nir_fadd(b, v, nir_imm_float(b, -0.5f)), 0),<br>
+ nir_imm_float(b, 0.0));<br>
+<br>
+ nir_ssa_def *red = nir_fdot4(b, yuv, nir_build_imm(b, 4, m[0]));<br>
+ nir_ssa_def *green = nir_fdot4(b, yuv, nir_build_imm(b, 4, m[1]));<br>
+ nir_ssa_def *blue = nir_fdot4(b, yuv, nir_build_imm(b, 4, m[2]));<br></blockquote><div><br></div><div>I didn't bother checking your math here, but I've seen the results so it's probably ok.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+ nir_ssa_def *result = nir_vec4(b, red, green, blue, nir_imm_float(b, 1.0f));<br>
+<br>
+ nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, nir_src_for_ssa(result),<br>
+ result->parent_instr);<br></blockquote><div><br></div><div>You can just use ssa_def_rewrite_uses here. No need to use the _after version.<br><br></div><div>With those fixed, this and the other NIR patch are<br><br></div><div>Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+}<br>
+<br>
+static void<br>
+lower_y_uv_external(nir_builder *b, nir_tex_instr *tex)<br>
+{<br>
+ b->cursor = nir_after_instr(&tex->instr);<br>
+<br>
+ nir_ssa_def *y = sample_plane(b, tex, 0);<br>
+ nir_ssa_def *uv = sample_plane(b, tex, 1);<br>
+<br>
+ convert_yuv_to_rgb(b, tex,<br>
+ nir_channel(b, y, 0),<br>
+ nir_channel(b, uv, 0),<br>
+ nir_channel(b, uv, 1));<br>
+}<br>
+<br>
+static void<br>
+lower_y_u_v_external(nir_builder *b, nir_tex_instr *tex)<br>
+{<br>
+ b->cursor = nir_after_instr(&tex->instr);<br>
+<br>
+ nir_ssa_def *y = sample_plane(b, tex, 0);<br>
+ nir_ssa_def *u = sample_plane(b, tex, 1);<br>
+ nir_ssa_def *v = sample_plane(b, tex, 2);<br>
+<br>
+ convert_yuv_to_rgb(b, tex,<br>
+ nir_channel(b, y, 0),<br>
+ nir_channel(b, u, 0),<br>
+ nir_channel(b, v, 0));<br>
+}<br>
+<br>
+static void<br>
+lower_yx_xuxv_external(nir_builder *b, nir_tex_instr *tex)<br>
+{<br>
+ b->cursor = nir_after_instr(&tex->instr);<br>
+<br>
+ nir_ssa_def *y = sample_plane(b, tex, 0);<br>
+ nir_ssa_def *xuxv = sample_plane(b, tex, 1);<br>
+<br>
+ convert_yuv_to_rgb(b, tex,<br>
+ nir_channel(b, y, 0),<br>
+ nir_channel(b, xuxv, 1),<br>
+ nir_channel(b, xuxv, 3));<br>
+}<br>
+<br>
static void<br>
saturate_src(nir_builder *b, nir_tex_instr *tex, unsigned sat_mask)<br>
{<br>
@@ -351,6 +453,22 @@ nir_lower_tex_block(nir_block *block, void *void_state)<br>
state->progress = true;<br>
}<br>
<br>
+ if ((1 << tex->texture_index) & options->lower_y_uv_external) {<br>
+ lower_y_uv_external(b, tex);<br>
+ state->progress = true;<br>
+ }<br>
+<br>
+ if ((1 << tex->texture_index) & options->lower_y_u_v_external) {<br>
+ lower_y_u_v_external(b, tex);<br>
+ state->progress = true;<br>
+ }<br>
+<br>
+ if ((1 << tex->texture_index) & options->lower_yx_xuxv_external) {<br>
+ lower_yx_xuxv_external(b, tex);<br>
+ state->progress = true;<br>
+ }<br>
+<br>
+<br>
if (sat_mask) {<br>
saturate_src(b, tex, sat_mask);<br>
state->progress = true;<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.5.0<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>