On 10.10.2017 19:31, Marek Olšák wrote:
Reviewed-by: Marek Olšák <[email protected]>

BTW, desktop OpenGL does have GL_TEXTURE_SRGB_DECODE_EXT, so the
comments are incorrect.

Huh, you're right. No idea where I got that idea from. I've changed the comment to note a TODO about having to clarify the interaction between SRGB_DECODE and bindless.

Cheers,
Nicolai



Marke

On Fri, Oct 6, 2017 at 10:39 PM, Nicolai Hähnle <[email protected]> wrote:
From: Nicolai Hähnle <[email protected]>

See the comment for the relevant spec quote.

Fixes dEQP-GLES31.functional.srgb_texture_decode.skip_decode.srgba8.texel_fetch
--
Note that this is on top of the texture locking series which I have
sent out a minute ago.
---
  src/mesa/main/mtypes.h                     |  1 +
  src/mesa/state_tracker/st_atom_texture.c   | 39 +++++++++++++++++++++++++++---
  src/mesa/state_tracker/st_cb_texture.c     |  8 +++++-
  src/mesa/state_tracker/st_glsl_to_tgsi.cpp |  4 +++
  src/mesa/state_tracker/st_sampler_view.c   | 19 +++++++++------
  src/mesa/state_tracker/st_sampler_view.h   |  3 ++-
  src/mesa/state_tracker/st_texture.c        |  7 +++++-
  src/mesa/state_tracker/st_texture.h        |  7 +++---
  8 files changed, 71 insertions(+), 17 deletions(-)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index abda1a36e46..a45409ed2d9 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2081,20 +2081,21 @@ struct gl_program

     bool is_arb_asm; /** Is this an ARB assembly-style program */

     /** Is this program written to on disk shader cache */
     bool program_written_to_cache;

     GLbitfield64 SecondaryOutputsWritten; /**< Subset of OutputsWritten 
outputs written with non-zero index. */
     GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];  /**< 
TEXTURE_x_BIT bitmask */
     GLbitfield SamplersUsed;   /**< Bitfield of which samplers are used */
     GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */
+   GLbitfield TexelFetchSamplers; /**< Texture units used for texelFetch*(). */
     GLbitfield ExternalSamplersUsed; /**< Texture units used for 
samplerExternalOES */

     /* Fragement shader only fields */
     GLboolean OriginUpperLeft;
     GLboolean PixelCenterInteger;

     /** Named parameters, constants, etc. from program text */
     struct gl_program_parameter_list *Parameters;

     /** Map from sampler unit to texture unit (set by glUniform1i()) */
diff --git a/src/mesa/state_tracker/st_atom_texture.c 
b/src/mesa/state_tracker/st_atom_texture.c
index 90828bb4cf9..c350a098097 100644
--- a/src/mesa/state_tracker/st_atom_texture.c
+++ b/src/mesa/state_tracker/st_atom_texture.c
@@ -51,21 +51,22 @@
  #include "util/u_inlines.h"
  #include "cso_cache/cso_context.h"


  /**
   * Get a pipe_sampler_view object from a texture unit.
   */
  void
  st_update_single_texture(struct st_context *st,
                           struct pipe_sampler_view **sampler_view,
-                         GLuint texUnit, bool glsl130_or_later)
+                         GLuint texUnit, bool glsl130_or_later,
+                         bool ignore_srgb_decode)
  {
     struct gl_context *ctx = st->ctx;
     const struct gl_sampler_object *samp;
     struct gl_texture_object *texObj;
     struct st_texture_object *stObj;

     samp = _mesa_get_samplerobj(ctx, texUnit);

     texObj = ctx->Texture.Unit[texUnit]._Current;
     assert(texObj);
@@ -83,55 +84,85 @@ st_update_single_texture(struct st_context *st,
        *sampler_view = NULL;
        return;
     }

     if (texObj->TargetIndex == TEXTURE_EXTERNAL_INDEX &&
         stObj->pt->screen->resource_changed)
           stObj->pt->screen->resource_changed(stObj->pt->screen, stObj->pt);

     *sampler_view =
        st_get_texture_sampler_view_from_stobj(st, stObj, samp,
-                                             glsl130_or_later);
+                                             glsl130_or_later,
+                                             ignore_srgb_decode);
  }



  static void
  update_textures(struct st_context *st,
                  enum pipe_shader_type shader_stage,
                  const struct gl_program *prog,
                  struct pipe_sampler_view **sampler_views,
                  unsigned *out_num_textures)
  {
     const GLuint old_max = *out_num_textures;
     GLbitfield samplers_used = prog->SamplersUsed;
+   GLbitfield texel_fetch_samplers = prog->TexelFetchSamplers;
     GLbitfield free_slots = ~prog->SamplersUsed;
     GLbitfield external_samplers_used = prog->ExternalSamplersUsed;
     GLuint unit;

     if (samplers_used == 0x0 && old_max == 0)
        return;

     unsigned num_textures = 0;

     /* prog->sh.data is NULL if it's ARB_fragment_program */
     bool glsl130 = (prog->sh.data ? prog->sh.data->Version : 0) >= 130;

     /* loop over sampler units (aka tex image units) */
     for (unit = 0; samplers_used || unit < old_max;
-        unit++, samplers_used >>= 1) {
+        unit++, samplers_used >>= 1, texel_fetch_samplers >>= 1) {
        struct pipe_sampler_view *sampler_view = NULL;

        if (samplers_used & 1) {
           const GLuint texUnit = prog->SamplerUnits[unit];

-         st_update_single_texture(st, &sampler_view, texUnit, glsl130);
+         /* The EXT_texture_sRGB_decode extension says:
+          *
+          *    "The conversion of sRGB color space components to linear color
+          *     space is always performed if the texel lookup function is one
+          *     of the texelFetch builtin functions.
+          *
+          *     Otherwise, if the texel lookup function is one of the texture
+          *     builtin functions or one of the texture gather functions, the
+          *     conversion of sRGB color space components to linear color space
+          *     is controlled by the TEXTURE_SRGB_DECODE_EXT parameter.
+          *
+          *     If the TEXTURE_SRGB_DECODE_EXT parameter is DECODE_EXT, the
+          *     conversion of sRGB color space components to linear color space
+          *     is performed.
+          *
+          *     If the TEXTURE_SRGB_DECODE_EXT parameter is SKIP_DECODE_EXT,
+          *     the value is returned without decoding. However, if the texture
+          *     is also [statically] accessed with a texelFetch function, then
+          *     the result of texture builtin functions and/or texture gather
+          *     functions may be returned with decoding or without decoding."
+          *
+          * Note: the "statically" will be added to the language per
+          *       https://cvs.khronos.org/bugzilla/show_bug.cgi?id=14934
+          *
+          * So we simply ignore the setting entirely for samplers that are
+          * (statically) accessed with a texelFetch function.
+          */
+         st_update_single_texture(st, &sampler_view, texUnit, glsl130,
+                                  texel_fetch_samplers & 1);
           num_textures = unit + 1;
        }

        pipe_sampler_view_reference(&(sampler_views[unit]), sampler_view);
     }

     /* For any external samplers with multiplaner YUV, stuff the additional
      * sampler views we need at the end.
      *
      * Trying to cache the sampler view in the stObj looks painful, so just
diff --git a/src/mesa/state_tracker/st_cb_texture.c 
b/src/mesa/state_tracker/st_cb_texture.c
index 44e0dd11dcd..6bbfc5f83e0 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -3110,21 +3110,27 @@ st_NewTextureHandle(struct gl_context *ctx, struct 
gl_texture_object *texObj,
     struct st_texture_object *stObj = st_texture_object(texObj);
     struct pipe_context *pipe = st->pipe;
     struct pipe_sampler_view *view;
     struct pipe_sampler_state sampler = {0};

     if (texObj->Target != GL_TEXTURE_BUFFER) {
        if (!st_finalize_texture(ctx, pipe, texObj, 0))
           return 0;

        st_convert_sampler(st, texObj, sampObj, 0, &sampler);
-      view = st_get_texture_sampler_view_from_stobj(st, stObj, sampObj, 0);
+
+      /* OpenGL does not have GL_TEXTURE_SRGB_DECODE_EXT, and OpenGL ES does 
not
+       * have bindless handles. The two are incompatible (or rather, if 
bindless
+       * handles are added to ES, there needs to be an explicit resolution of 
how
+       * SRGB_DECODE should be handled).
+       */
+      view = st_get_texture_sampler_view_from_stobj(st, stObj, sampObj, 0, 
true);
     } else {
        view = st_get_buffer_sampler_view_from_stobj(st, stObj);
     }

     return pipe->create_texture_handle(pipe, view, &sampler);
  }


  static void
  st_DeleteTextureHandle(struct gl_context *ctx, GLuint64 handle)
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp 
b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index e01268bbbea..4b365c84817 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -4471,20 +4471,24 @@ count_resources(glsl_to_tgsi_visitor *v, gl_program 
*prog)
              v->samplers_used |= 1u << idx;

              debug_assert(idx < (int)ARRAY_SIZE(v->sampler_types));
              v->sampler_types[idx] = inst->tex_type;
              v->sampler_targets[idx] =
                 st_translate_texture_target(inst->tex_target, 
inst->tex_shadow);

              if (inst->tex_shadow) {
                 prog->ShadowSamplers |= 1 << (inst->resource.index + i);
              }
+
+            if (inst->op == TGSI_OPCODE_TXF || inst->op == TGSI_OPCODE_TXF_LZ) 
{
+               prog->TexelFetchSamplers |= 1u << idx;
+            }
           }
        }

        if (inst->tex_target == TEXTURE_EXTERNAL_INDEX)
           prog->ExternalSamplersUsed |= 1 << inst->resource.index;

        if (inst->resource.file != PROGRAM_UNDEFINED && (
                  is_resource_instruction(inst->op) ||
                  inst->op == TGSI_OPCODE_STORE)) {
           if (inst->resource.file == PROGRAM_MEMORY) {
diff --git a/src/mesa/state_tracker/st_sampler_view.c 
b/src/mesa/state_tracker/st_sampler_view.c
index de104355c04..cd5d7771ba3 100644
--- a/src/mesa/state_tracker/st_sampler_view.c
+++ b/src/mesa/state_tracker/st_sampler_view.c
@@ -386,38 +386,38 @@ last_layer(const struct st_texture_object *stObj)
     return stObj->pt->array_size - 1;
  }


  /**
   * Determine the format for the texture sampler view.
   */
  static enum pipe_format
  get_sampler_view_format(struct st_context *st,
                          const struct st_texture_object *stObj,
-                        const struct gl_sampler_object *samp)
+                        bool srgb_skip_decode)
  {
     enum pipe_format format;

     GLenum baseFormat = _mesa_base_tex_image(&stObj->base)->_BaseFormat;
     format = stObj->surface_based ? stObj->surface_format : stObj->pt->format;

     if (baseFormat == GL_DEPTH_COMPONENT ||
         baseFormat == GL_DEPTH_STENCIL ||
         baseFormat == GL_STENCIL_INDEX) {
        if (stObj->base.StencilSampling || baseFormat == GL_STENCIL_INDEX)
           format = util_format_stencil_only(format);

        return format;
     }

     /* If sRGB decoding is off, use the linear format */
-   if (samp->sRGBDecode == GL_SKIP_DECODE_EXT)
+   if (srgb_skip_decode)
        format = util_format_linear(format);

     /* Use R8_UNORM for video formats */
     switch (format) {
     case PIPE_FORMAT_NV12:
     case PIPE_FORMAT_IYUV:
        format = PIPE_FORMAT_R8_UNORM;
        break;
     default:
        break;
@@ -456,60 +456,65 @@ st_create_texture_sampler_view_from_stobj(struct 
st_context *st,
     templ.swizzle_a = GET_SWZ(swizzle, 3);

     return st->pipe->create_sampler_view(st->pipe, stObj->pt, &templ);
  }


  struct pipe_sampler_view *
  st_get_texture_sampler_view_from_stobj(struct st_context *st,
                                         struct st_texture_object *stObj,
                                         const struct gl_sampler_object *samp,
-                                       bool glsl130_or_later)
+                                       bool glsl130_or_later,
+                                       bool ignore_srgb_decode)
  {
     struct st_sampler_view *sv;
     struct pipe_sampler_view *view;
+   bool srgb_skip_decode = false;

     mtx_lock(&stObj->validate_mutex);
     sv = st_texture_get_sampler_view(st, stObj);
     if (!sv) {
        mtx_unlock(&stObj->validate_mutex);
        return NULL;
     }

     view = sv->view;

+   if (!ignore_srgb_decode && samp->sRGBDecode == GL_SKIP_DECODE_EXT)
+      srgb_skip_decode = true;
+
     if (view &&
         sv->glsl130_or_later == glsl130_or_later &&
-       sv->sRGBDecode == samp->sRGBDecode) {
+       sv->srgb_skip_decode == srgb_skip_decode) {
        /* Debug check: make sure that the sampler view's parameters are
         * what they're supposed to be.
         */
        MAYBE_UNUSED struct pipe_sampler_view *view = sv->view;
        assert(stObj->pt == view->texture);
        assert(!check_sampler_swizzle(st, stObj, view, glsl130_or_later));
-      assert(get_sampler_view_format(st, stObj, samp) == view->format);
+      assert(get_sampler_view_format(st, stObj, srgb_skip_decode) == 
view->format);
        assert(gl_target_to_pipe(stObj->base.Target) == view->target);
        assert(stObj->base.MinLevel + stObj->base.BaseLevel ==
               view->u.tex.first_level);
        assert(last_level(stObj) == view->u.tex.last_level);
        assert(stObj->layer_override || stObj->base.MinLayer == 
view->u.tex.first_layer);
        assert(stObj->layer_override || last_layer(stObj) == 
view->u.tex.last_layer);
        assert(!stObj->layer_override ||
               (stObj->layer_override == view->u.tex.first_layer &&
                stObj->layer_override == view->u.tex.last_layer));
     }
     else {
        /* create new sampler view */
-      enum pipe_format format = get_sampler_view_format(st, stObj, samp);
+      enum pipe_format format = get_sampler_view_format(st, stObj, 
srgb_skip_decode);

        sv->glsl130_or_later = glsl130_or_later;
-      sv->sRGBDecode = samp->sRGBDecode;
+      sv->srgb_skip_decode = srgb_skip_decode;

        pipe_sampler_view_release(st->pipe, &sv->view);
        view = sv->view =
           st_create_texture_sampler_view_from_stobj(st, stObj, format, 
glsl130_or_later);
     }

     mtx_unlock(&stObj->validate_mutex);

     return view;
  }
diff --git a/src/mesa/state_tracker/st_sampler_view.h 
b/src/mesa/state_tracker/st_sampler_view.h
index 9a7e54cff4e..e48c4b9015f 100644
--- a/src/mesa/state_tracker/st_sampler_view.h
+++ b/src/mesa/state_tracker/st_sampler_view.h
@@ -73,17 +73,18 @@ void
  st_texture_free_sampler_views(struct st_texture_object *stObj);

  struct pipe_sampler_view *
  st_texture_get_current_sampler_view(const struct st_context *st,
                                      const struct st_texture_object *stObj);

  struct pipe_sampler_view *
  st_get_texture_sampler_view_from_stobj(struct st_context *st,
                                         struct st_texture_object *stObj,
                                         const struct gl_sampler_object *samp,
-                                       bool glsl130_or_later);
+                                       bool glsl130_or_later,
+                                       bool ignore_srgb_decode);

  struct pipe_sampler_view *
  st_get_buffer_sampler_view_from_stobj(struct st_context *st,
                                        struct st_texture_object *stObj);

  #endif /* ST_SAMPLER_VIEW_H */
diff --git a/src/mesa/state_tracker/st_texture.c 
b/src/mesa/state_tracker/st_texture.c
index f749fb0a9fc..3c0dfa678d9 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -508,21 +508,26 @@ st_destroy_bound_image_handles(struct st_context *st)
   * Create a texture handle from a texture unit.
   */
  static GLuint64
  st_create_texture_handle_from_unit(struct st_context *st,
                                     struct gl_program *prog, GLuint texUnit)
  {
     struct pipe_context *pipe = st->pipe;
     struct pipe_sampler_view *view;
     struct pipe_sampler_state sampler = {0};

-   st_update_single_texture(st, &view, texUnit, prog->sh.data->Version >= 130);
+   /* OpenGL does not have GL_TEXTURE_SRGB_DECODE_EXT, and OpenGL ES does not
+    * have bindless sampler uniforms. If the two were ever enabled
+    * simultaneously, we could mimick the behavior of non-bindless texture
+    * units here.
+    */
+   st_update_single_texture(st, &view, texUnit, prog->sh.data->Version >= 130, 
true);
     if (!view)
        return 0;

     if (view->target != PIPE_BUFFER)
        st_convert_sampler_from_unit(st, &sampler, texUnit);

     assert(st->ctx->Texture.Unit[texUnit]._Current);

     return pipe->create_texture_handle(pipe, view, &sampler);
  }
diff --git a/src/mesa/state_tracker/st_texture.h 
b/src/mesa/state_tracker/st_texture.h
index df5d6dda387..f2fefee63c5 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -49,22 +49,22 @@ struct st_texture_image_transfer {


  /**
   * Container for one context's validated sampler view.
   */
  struct st_sampler_view {
     struct pipe_sampler_view *view;

     /** The glsl version of the shader seen during validation */
     bool glsl130_or_later;
-   /** The value of the sampler's sRGBDecode state during validation */
-   GLenum sRGBDecode;
+   /** Derived from the sampler's sRGBDecode state during validation */
+   bool srgb_skip_decode;
  };


  /**
   * Subclass of gl_texure_image.
   */
  struct st_texture_image
  {
     struct gl_texture_image base;

@@ -296,21 +296,22 @@ st_convert_sampler(const struct st_context *st,
                     struct pipe_sampler_state *sampler);

  void
  st_convert_sampler_from_unit(const struct st_context *st,
                               struct pipe_sampler_state *sampler,
                               GLuint texUnit);

  void
  st_update_single_texture(struct st_context *st,
                           struct pipe_sampler_view **sampler_view,
-                         GLuint texUnit, bool glsl130_or_later);
+                         GLuint texUnit, bool glsl130_or_later,
+                         bool ignore_srgb_decode);

  void
  st_make_bound_samplers_resident(struct st_context *st,
                                  struct gl_program *prog);

  void
  st_make_bound_images_resident(struct st_context *st,
                                struct gl_program *prog);

  #endif
--
2.11.0

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to