u_blit,u_simple_shaders: add shader to convert from xrbias format
authorRoland Scheidegger <sroland@vmware.com>
Wed, 7 Feb 2018 04:18:17 +0000 (05:18 +0100)
committerRoland Scheidegger <sroland@vmware.com>
Wed, 7 Feb 2018 16:09:37 +0000 (17:09 +0100)
We need this to handle some oddball dx10 format
(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM). What you can do with this
format is very limited, hence we don't want to add it as a gallium
format (we could not express the properties of this format as
ordinary format properties neither, so like all special formats
it would need specific code for handling it in any case).
While here, also nuke the array for different shaders for different
writemasks, as it was not actually used (always full masks are
passed in for generating shaders).

Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
src/gallium/auxiliary/util/u_blit.c
src/gallium/auxiliary/util/u_blit.h
src/gallium/auxiliary/util/u_simple_shaders.c
src/gallium/auxiliary/util/u_simple_shaders.h

index 3f92476f0c0e79b2096fc0fb3645305b905da920..817eeac9f0dc4491c5e0bf0a461fda4bf35fef12 100644 (file)
@@ -65,7 +65,7 @@ struct blit_state
    struct pipe_vertex_element velem[2];
 
    void *vs;
-   void *fs[PIPE_MAX_TEXTURE_TYPES][TGSI_WRITEMASK_XYZW + 1][3];
+   void *fs[PIPE_MAX_TEXTURE_TYPES][4];
 
    struct pipe_resource *vbuf;  /**< quad vertices */
    unsigned vbuf_slot;
@@ -135,17 +135,15 @@ void
 util_destroy_blit(struct blit_state *ctx)
 {
    struct pipe_context *pipe = ctx->pipe;
-   unsigned i, j, k;
+   unsigned i, j;
 
    if (ctx->vs)
       pipe->delete_vs_state(pipe, ctx->vs);
 
    for (i = 0; i < ARRAY_SIZE(ctx->fs); i++) {
       for (j = 0; j < ARRAY_SIZE(ctx->fs[i]); j++) {
-         for (k = 0; k < ARRAY_SIZE(ctx->fs[i][j]); k++) {
-            if (ctx->fs[i][j][k])
-               pipe->delete_fs_state(pipe, ctx->fs[i][j][k]);
-         }
+         if (ctx->fs[i][j])
+            pipe->delete_fs_state(pipe, ctx->fs[i][j]);
       }
    }
 
@@ -159,8 +157,9 @@ util_destroy_blit(struct blit_state *ctx)
  * Helper function to set the fragment shaders.
  */
 static inline void
-set_fragment_shader(struct blit_state *ctx, uint writemask,
+set_fragment_shader(struct blit_state *ctx,
                     enum pipe_format format,
+                    boolean src_xrbias,
                     enum pipe_texture_target pipe_tex)
 {
    enum tgsi_return_type stype;
@@ -177,19 +176,29 @@ set_fragment_shader(struct blit_state *ctx, uint writemask,
       idx = 2;
    }
 
-   if (!ctx->fs[pipe_tex][writemask][idx]) {
+   if (src_xrbias) {
+      assert(stype == TGSI_RETURN_TYPE_FLOAT);
+      idx = 3;
+      if (!ctx->fs[pipe_tex][idx]) {
+         enum tgsi_texture_type tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0);
+         ctx->fs[pipe_tex][idx] =
+            util_make_fragment_tex_shader_xrbias(ctx->pipe, tgsi_tex);
+      }
+   }
+
+   else if (!ctx->fs[pipe_tex][idx]) {
       unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0);
 
       /* OpenGL does not allow blits from signed to unsigned integer
        * or vice versa. */
-      ctx->fs[pipe_tex][writemask][idx] =
+      ctx->fs[pipe_tex][idx] =
          util_make_fragment_tex_shader_writemask(ctx->pipe, tgsi_tex,
                                                  TGSI_INTERPOLATE_LINEAR,
-                                                 writemask,
+                                                 TGSI_WRITEMASK_XYZW,
                                                  stype, stype, false, false);
    }
 
-   cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][writemask][idx]);
+   cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][idx]);
 }
 
 
@@ -491,8 +500,8 @@ util_blit_pixels(struct blit_state *ctx,
  * The sampler view's first_layer indicate the layer to use, but for
  * cube maps it must point to the first face.  Face is passed in src_face.
  *
- * The main advantage over util_blit_pixels is that it allows to specify swizzles in
- * pipe_sampler_view::swizzle_?.
+ * The main advantage over util_blit_pixels is that it allows to specify
+ * swizzles in pipe_sampler_view::swizzle_?.
  *
  * But there is no control over blitting Z and/or stencil.
  */
@@ -505,7 +514,8 @@ util_blit_pixels_tex(struct blit_state *ctx,
                      struct pipe_surface *dst,
                      int dstX0, int dstY0,
                      int dstX1, int dstY1,
-                     float z, uint filter)
+                     float z, uint filter,
+                     boolean src_xrbias)
 {
    boolean normalized = src_sampler_view->texture->target != PIPE_TEXTURE_RECT;
    struct pipe_framebuffer_state fb;
@@ -593,7 +603,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
    cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &src_sampler_view);
 
    /* shaders */
-   set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW,
+   set_fragment_shader(ctx, src_xrbias,
                        src_sampler_view->format,
                        src_sampler_view->texture->target);
    set_vertex_shader(ctx);
index b50edab781e4eb900212ca4a5f2f176031fc1f3e..e2934d0983cf5c24b2441e1e2e5c3161a30d61aa 100644 (file)
@@ -72,7 +72,8 @@ util_blit_pixels_tex(struct blit_state *ctx,
                      struct pipe_surface *dst,
                      int dstX0, int dstY0,
                      int dstX1, int dstY1,
-                     float z, uint filter);
+                     float z, uint filter,
+                     boolean src_xrbias);
 
 #ifdef __cplusplus
 }
index a301c057624c242fa3095648d8ab60acc41d4a45..0b444045c428ac22c1d0d9a18494f06a45251e25 100644 (file)
@@ -221,6 +221,53 @@ ureg_load_tex(struct ureg_program *ureg, struct ureg_dst out,
    }
 }
 
+/**
+ * Make simple fragment texture shader, with xrbias->float conversion:
+ *  IMM {1023/510, -384/510, 0, 1}
+ *  TEX TEMP[0], IN[0], SAMP[0], 2D;
+ *  MAD TEMP[0].xyz TEMP[0], IMM[0].xxxx, IMM[0].yyyy
+ *  MOV OUT[0], TEMP[0]
+ *  END;
+ *
+ * \param tex_target  one of PIPE_TEXTURE_x
+ */
+void *
+util_make_fragment_tex_shader_xrbias(struct pipe_context *pipe,
+                                     enum tgsi_texture_type tex_target)
+{
+   struct ureg_program *ureg;
+   struct ureg_src sampler;
+   struct ureg_src coord;
+   struct ureg_dst temp;
+   struct ureg_dst out;
+   struct ureg_src imm;
+   enum tgsi_return_type stype = TGSI_RETURN_TYPE_FLOAT;
+
+   ureg = ureg_create(PIPE_SHADER_FRAGMENT);
+   if (!ureg)
+      return NULL;
+
+   imm = ureg_imm4f(ureg, 1023.0f/510.0f, -384.0f/510.0f, 0.0f, 1.0f);
+   sampler = ureg_DECL_sampler(ureg, 0);
+   ureg_DECL_sampler_view(ureg, 0, tex_target, stype, stype, stype, stype);
+   coord = ureg_DECL_fs_input(ureg,
+                              TGSI_SEMANTIC_GENERIC, 0,
+                              TGSI_INTERPOLATE_LINEAR);
+   out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
+   temp = ureg_DECL_temporary(ureg);
+
+   ureg_TEX(ureg, temp, tex_target, coord, sampler);
+   ureg_MAD(ureg, ureg_writemask(temp, TGSI_WRITEMASK_XYZ),
+            ureg_src(temp),
+            ureg_scalar(imm, TGSI_SWIZZLE_X),
+            ureg_scalar(imm, TGSI_SWIZZLE_Y));
+   ureg_MOV(ureg, out, ureg_src(temp));
+   ureg_END(ureg);
+
+   return ureg_create_shader_and_destroy(ureg, pipe);
+}
+
+
 /**
  * Make simple fragment texture shader:
  *  IMM {0,0,0,1}                         // (if writemask != 0xf)
index a281f573a4aa12899000262eec89524fa28fffd7..627c56331a36563d068bc5769c54db6aa846b422 100644 (file)
@@ -68,6 +68,10 @@ util_make_layered_clear_helper_vertex_shader(struct pipe_context *pipe);
 extern void *
 util_make_layered_clear_geometry_shader(struct pipe_context *pipe);
 
+void *
+util_make_fragment_tex_shader_xrbias(struct pipe_context *pipe,
+                                     enum tgsi_texture_type tex_target);
+
 extern void *
 util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
                                         unsigned tex_target,