The cso_context changes are unnecessary. It looks like that meta ops don't
enable MSAA, so they are unaffected by sample locations, and thus no need
to have any code for them in cso_context.

The names don't have to use the _state suffix, i.e. set_sample_locations.

I wouldn't add struct pipe_sample_locations. The whole array can be passed
to set_sample_locations via a pointer, and NULL can mean disabled.

Marek


On Fri, May 4, 2018 at 8:09 AM, Rhys Perry <pendingchao...@gmail.com> wrote:

> Signed-off-by: Rhys Perry <pendingchao...@gmail.com>
> ---
>  src/gallium/auxiliary/cso_cache/cso_context.c    | 31
> +++++++++++++++++++++++
>  src/gallium/auxiliary/cso_cache/cso_context.h    |  5 ++++
>  src/gallium/auxiliary/util/u_framebuffer.c       | 32
> ++++++++++++++++++++++++
>  src/gallium/auxiliary/util/u_framebuffer.h       |  6 +++++
>  src/gallium/docs/source/context.rst              |  2 ++
>  src/gallium/docs/source/screen.rst               |  3 +++
>  src/gallium/drivers/etnaviv/etnaviv_screen.c     |  1 +
>  src/gallium/drivers/freedreno/freedreno_screen.c |  1 +
>  src/gallium/drivers/i915/i915_screen.c           |  1 +
>  src/gallium/drivers/llvmpipe/lp_screen.c         |  1 +
>  src/gallium/drivers/nouveau/nv30/nv30_screen.c   |  1 +
>  src/gallium/drivers/nouveau/nv50/nv50_screen.c   |  1 +
>  src/gallium/drivers/nouveau/nvc0/nvc0_screen.c   |  2 +-
>  src/gallium/drivers/r300/r300_screen.c           |  1 +
>  src/gallium/drivers/r600/r600_pipe.c             |  1 +
>  src/gallium/drivers/radeonsi/si_get.c            |  1 +
>  src/gallium/drivers/softpipe/sp_screen.c         |  1 +
>  src/gallium/drivers/svga/svga_screen.c           |  1 +
>  src/gallium/drivers/swr/swr_screen.cpp           |  1 +
>  src/gallium/drivers/vc4/vc4_screen.c             |  1 +
>  src/gallium/drivers/vc5/vc5_screen.c             |  1 +
>  src/gallium/drivers/virgl/virgl_screen.c         |  1 +
>  src/gallium/include/pipe/p_context.h             | 17 ++++++++++++-
>  src/gallium/include/pipe/p_defines.h             |  1 +
>  src/gallium/include/pipe/p_state.h               | 26 +++++++++++++++++++
>  25 files changed, 138 insertions(+), 2 deletions(-)
>
> diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c
> b/src/gallium/auxiliary/cso_cache/cso_context.c
> index 3a3a63a332..b3e09ada6e 100644
> --- a/src/gallium/auxiliary/cso_cache/cso_context.c
> +++ b/src/gallium/auxiliary/cso_cache/cso_context.c
> @@ -121,6 +121,7 @@ struct cso_context {
>     boolean render_condition_cond, render_condition_cond_saved;
>
>     struct pipe_framebuffer_state fb, fb_saved;
> +   struct pipe_sample_locations_state sample_locations,
> sample_locations_saved;
>     struct pipe_viewport_state vp, vp_saved;
>     struct pipe_blend_color blend_color;
>     unsigned sample_mask, sample_mask_saved;
> @@ -745,6 +746,32 @@ cso_restore_framebuffer(struct cso_context *ctx)
>  }
>
>
> +void cso_set_sample_locations(struct cso_context *ctx,
> +                              const struct pipe_sample_locations_state
> *locs)
> +{
> +   size_t size = sizeof(ctx->sample_locations);
> +   if (memcmp(&ctx->sample_locations, locs, size)) {
> +      memcpy(&ctx->sample_locations, locs, size);
> +      ctx->pipe->set_sample_locations_state(ctx->pipe, locs);
> +   }
> +}
> +
> +static void
> +cso_save_sample_locations(struct cso_context *ctx)
> +{
> +   size_t size = sizeof(ctx->sample_locations);
> +   memcpy(&ctx->sample_locations_saved, &ctx->sample_locations, size);
> +}
> +
> +static void
> +cso_restore_sample_locations(struct cso_context *ctx)
> +{
> +   size_t size = sizeof(ctx->sample_locations);
> +   if (memcmp(&ctx->sample_locations, &ctx->sample_locations_saved,
> size))
> +      cso_set_sample_locations(ctx, &ctx->sample_locations_saved);
> +}
> +
> +
>  void cso_set_viewport(struct cso_context *ctx,
>                        const struct pipe_viewport_state *vp)
>  {
> @@ -1636,6 +1663,8 @@ cso_save_state(struct cso_context *cso, unsigned
> state_mask)
>        cso->pipe->set_active_query_state(cso->pipe, false);
>     if (state_mask & CSO_BIT_FRAGMENT_IMAGE0)
>        cso_save_fragment_image0(cso);
> +   if (state_mask & CSO_BIT_SAMPLE_LOCATIONS)
> +      cso_save_sample_locations(cso);
>  }
>
>
> @@ -1691,6 +1720,8 @@ cso_restore_state(struct cso_context *cso)
>        cso->pipe->set_active_query_state(cso->pipe, true);
>     if (state_mask & CSO_BIT_FRAGMENT_IMAGE0)
>        cso_restore_fragment_image0(cso);
> +   if (state_mask & CSO_BIT_SAMPLE_LOCATIONS)
> +      cso_restore_sample_locations(cso);
>
>     cso->saved_state = 0;
>  }
> diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h
> b/src/gallium/auxiliary/cso_cache/cso_context.h
> index 3a4e808f0c..3f3b0ae3d4 100644
> --- a/src/gallium/auxiliary/cso_cache/cso_context.h
> +++ b/src/gallium/auxiliary/cso_cache/cso_context.h
> @@ -133,6 +133,10 @@ void cso_set_framebuffer(struct cso_context *cso,
>                           const struct pipe_framebuffer_state *fb);
>
>
> +void cso_set_sample_locations(struct cso_context *ctx,
> +                              const struct pipe_sample_locations_state
> *locs);
> +
> +
>  void cso_set_viewport(struct cso_context *cso,
>                        const struct pipe_viewport_state *vp);
>  void cso_set_viewport_dims(struct cso_context *ctx,
> @@ -176,6 +180,7 @@ void cso_set_render_condition(struct cso_context *cso,
>  #define CSO_BIT_VIEWPORT              0x40000
>  #define CSO_BIT_PAUSE_QUERIES         0x80000
>  #define CSO_BIT_FRAGMENT_IMAGE0      0x100000
> +#define CSO_BIT_SAMPLE_LOCATIONS     0x200000
>
>  #define CSO_BITS_ALL_SHADERS (CSO_BIT_VERTEX_SHADER | \
>                                CSO_BIT_FRAGMENT_SHADER | \
> diff --git a/src/gallium/auxiliary/util/u_framebuffer.c
> b/src/gallium/auxiliary/util/u_framebuffer.c
> index c2948a5cfb..6e8a24ba6c 100644
> --- a/src/gallium/auxiliary/util/u_framebuffer.c
> +++ b/src/gallium/auxiliary/util/u_framebuffer.c
> @@ -240,3 +240,35 @@ util_framebuffer_get_num_samples(const struct
> pipe_framebuffer_state *fb)
>
>     return 1;
>  }
> +
> +
> +/**
> + * Flip the sample location state along the Y axis.
> + */
> +void
> +util_sample_locations_flip_y(struct pipe_context *ctx,
> +                             struct pipe_sample_locations_state *locs,
> +                             const struct pipe_framebuffer_state *fb)
> +{
> +   unsigned grid_width, grid_height, shift, row, i;
> +   uint8_t new_locations[
> +      PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE*PIPE_MAX_SAMPLE_LOCATION_
> GRID_SIZE*32];
> +   STATIC_ASSERT(sizeof(new_locations) == sizeof(locs->locations));
> +
> +   memset(new_locations, 0x88, sizeof(new_locations));
> +
> +   ctx->get_sample_pixel_grid(ctx, fb->samples, &grid_width,
> &grid_height);
> +   shift = fb->height % grid_height;
> +
> +   for (row = 0; row < grid_height; row++) {
> +      unsigned row_size = grid_width * fb->samples;
> +      for (i = 0; i < row_size; i++) {
> +         unsigned dest_row = grid_height - row - 1;
> +         /* this relies on unsigned integer wraparound behaviour */
> +         dest_row = (dest_row - shift) % grid_height;
> +         new_locations[dest_row * row_size + i] = locs->locations[row *
> row_size + i];
> +      }
> +   }
> +
> +   memcpy(locs->locations, new_locations, sizeof(new_locations));
> +}
> diff --git a/src/gallium/auxiliary/util/u_framebuffer.h
> b/src/gallium/auxiliary/util/u_framebuffer.h
> index c73942c9c1..4cddd8f640 100644
> --- a/src/gallium/auxiliary/util/u_framebuffer.h
> +++ b/src/gallium/auxiliary/util/u_framebuffer.h
> @@ -64,6 +64,12 @@ extern unsigned
>  util_framebuffer_get_num_samples(const struct pipe_framebuffer_state
> *fb);
>
>
> +extern void
> +util_sample_locations_flip_y(struct pipe_context *ctx,
> +                             struct pipe_sample_locations_state *locs,
> +                             const struct pipe_framebuffer_state *fb);
> +
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/src/gallium/docs/source/context.rst
> b/src/gallium/docs/source/context.rst
> index e8e80dcbc3..cc2e90f5dd 100644
> --- a/src/gallium/docs/source/context.rst
> +++ b/src/gallium/docs/source/context.rst
> @@ -68,6 +68,8 @@ objects. They all follow simple, one-method binding
> calls, e.g.
>    that this takes effect even if multisampling is not explicitly enabled
> if
>    the frambuffer surface(s) are multisampled.  Also, this mask is AND-ed
>    with the optional fragment shader sample mask output (when emitted).
> +* ``set_sample_locations_state`` sets the sample locations used for
> +  rasterization. ```get_sample_position``` still returns the default
> locations.
>  * ``set_min_samples`` sets the minimum number of samples that must be run.
>  * ``set_clip_state``
>  * ``set_polygon_stipple``
> diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/
> screen.rst
> index 3837360fb4..2c5a01dd9f 100644
> --- a/src/gallium/docs/source/screen.rst
> +++ b/src/gallium/docs/source/screen.rst
> @@ -420,6 +420,9 @@ The integer capabilities:
>    by the driver, and the driver can throw assertion failures.
>  * ``PIPE_CAP_PACKED_UNIFORMS``: True if the driver supports packed
> uniforms
>    as opposed to padding to vec4s.
> +* ``PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS``: True is the driver supports
> +  programmable sample location through ```get_sample_pixel_grid``` and
> +  ```set_sample_locations_state```.
>
>
>  .. _pipe_capf:
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c
> b/src/gallium/drivers/etnaviv/etnaviv_screen.c
> index b0f8b4bebe..c3503c658c 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c
> @@ -274,6 +274,7 @@ etna_screen_get_param(struct pipe_screen *pscreen,
> enum pipe_cap param)
>     case PIPE_CAP_FENCE_SIGNAL:
>     case PIPE_CAP_CONSTBUF0_FLAGS:
>     case PIPE_CAP_PACKED_UNIFORMS:
> +   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>        return 0;
>
>     /* Stream output. */
> diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c
> b/src/gallium/drivers/freedreno/freedreno_screen.c
> index f338d756df..2347b5e4c0 100644
> --- a/src/gallium/drivers/freedreno/freedreno_screen.c
> +++ b/src/gallium/drivers/freedreno/freedreno_screen.c
> @@ -340,6 +340,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum
> pipe_cap param)
>         case PIPE_CAP_FENCE_SIGNAL:
>         case PIPE_CAP_CONSTBUF0_FLAGS:
>         case PIPE_CAP_PACKED_UNIFORMS:
> +       case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>                 return 0;
>
>         case PIPE_CAP_CONTEXT_PRIORITY_MASK:
> diff --git a/src/gallium/drivers/i915/i915_screen.c
> b/src/gallium/drivers/i915/i915_screen.c
> index 59d2ec6628..058c07c76c 100644
> --- a/src/gallium/drivers/i915/i915_screen.c
> +++ b/src/gallium/drivers/i915/i915_screen.c
> @@ -327,6 +327,7 @@ i915_get_param(struct pipe_screen *screen, enum
> pipe_cap cap)
>     case PIPE_CAP_FENCE_SIGNAL:
>     case PIPE_CAP_CONSTBUF0_FLAGS:
>     case PIPE_CAP_PACKED_UNIFORMS:
> +   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>        return 0;
>
>     case PIPE_CAP_MAX_VIEWPORTS:
> diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c
> b/src/gallium/drivers/llvmpipe/lp_screen.c
> index 3f5d0327bf..6cfaf936f0 100644
> --- a/src/gallium/drivers/llvmpipe/lp_screen.c
> +++ b/src/gallium/drivers/llvmpipe/lp_screen.c
> @@ -362,6 +362,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum
> pipe_cap param)
>     case PIPE_CAP_FENCE_SIGNAL:
>     case PIPE_CAP_CONSTBUF0_FLAGS:
>     case PIPE_CAP_PACKED_UNIFORMS:
> +   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>        return 0;
>     }
>     /* should only get here on unhandled cases */
> diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
> b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
> index 1d1fbaad60..b5db930a67 100644
> --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
> +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
> @@ -229,6 +229,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen,
> enum pipe_cap param)
>     case PIPE_CAP_FENCE_SIGNAL:
>     case PIPE_CAP_CONSTBUF0_FLAGS:
>     case PIPE_CAP_PACKED_UNIFORMS:
> +   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>        return 0;
>
>     case PIPE_CAP_VENDOR_ID:
> diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
> b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
> index 6fd2982e3c..2b91b72310 100644
> --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
> +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
> @@ -281,6 +281,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen,
> enum pipe_cap param)
>     case PIPE_CAP_FENCE_SIGNAL:
>     case PIPE_CAP_CONSTBUF0_FLAGS:
>     case PIPE_CAP_PACKED_UNIFORMS:
> +   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>        return 0;
>
>     case PIPE_CAP_VENDOR_ID:
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> index eb50149b64..c6b1aa3ca8 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> @@ -264,7 +264,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen,
> enum pipe_cap param)
>     case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
>     case PIPE_CAP_TGSI_TES_LAYER_VIEWPORT:
>     case PIPE_CAP_POST_DEPTH_COVERAGE:
> -      return class_3d >= GM200_3D_CLASS;
>     case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
>     case PIPE_CAP_TGSI_BALLOT:
>     case PIPE_CAP_BINDLESS_TEXTURE:
> @@ -309,6 +308,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen,
> enum pipe_cap param)
>     case PIPE_CAP_FENCE_SIGNAL:
>     case PIPE_CAP_CONSTBUF0_FLAGS:
>     case PIPE_CAP_PACKED_UNIFORMS:
> +   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>        return 0;
>
>     case PIPE_CAP_VENDOR_ID:
> diff --git a/src/gallium/drivers/r300/r300_screen.c
> b/src/gallium/drivers/r300/r300_screen.c
> index 8ea2e87ce6..3a7e01e3dc 100644
> --- a/src/gallium/drivers/r300/r300_screen.c
> +++ b/src/gallium/drivers/r300/r300_screen.c
> @@ -251,6 +251,7 @@ static int r300_get_param(struct pipe_screen* pscreen,
> enum pipe_cap param)
>          case PIPE_CAP_FENCE_SIGNAL:
>          case PIPE_CAP_CONSTBUF0_FLAGS:
>          case PIPE_CAP_PACKED_UNIFORMS:
> +        case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>              return 0;
>
>          /* SWTCL-only features. */
> diff --git a/src/gallium/drivers/r600/r600_pipe.c
> b/src/gallium/drivers/r600/r600_pipe.c
> index 43f2dfae7e..eed3d5918b 100644
> --- a/src/gallium/drivers/r600/r600_pipe.c
> +++ b/src/gallium/drivers/r600/r600_pipe.c
> @@ -415,6 +415,7 @@ static int r600_get_param(struct pipe_screen* pscreen,
> enum pipe_cap param)
>         case PIPE_CAP_FENCE_SIGNAL:
>         case PIPE_CAP_CONSTBUF0_FLAGS:
>         case PIPE_CAP_PACKED_UNIFORMS:
> +       case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>                 return 0;
>
>         case PIPE_CAP_DOUBLES:
> diff --git a/src/gallium/drivers/radeonsi/si_get.c b/src/gallium/drivers/
> radeonsi/si_get.c
> index cb28920bbe..a504a39875 100644
> --- a/src/gallium/drivers/radeonsi/si_get.c
> +++ b/src/gallium/drivers/radeonsi/si_get.c
> @@ -277,6 +277,7 @@ static int si_get_param(struct pipe_screen *pscreen,
> enum pipe_cap param)
>         case PIPE_CAP_TILE_RASTER_ORDER:
>         case PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
>         case PIPE_CAP_CONTEXT_PRIORITY_MASK:
> +       case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>                 return 0;
>
>         case PIPE_CAP_FENCE_SIGNAL:
> diff --git a/src/gallium/drivers/softpipe/sp_screen.c
> b/src/gallium/drivers/softpipe/sp_screen.c
> index 25f6f74f36..9e71cd9795 100644
> --- a/src/gallium/drivers/softpipe/sp_screen.c
> +++ b/src/gallium/drivers/softpipe/sp_screen.c
> @@ -314,6 +314,7 @@ softpipe_get_param(struct pipe_screen *screen, enum
> pipe_cap param)
>     case PIPE_CAP_FENCE_SIGNAL:
>     case PIPE_CAP_CONSTBUF0_FLAGS:
>     case PIPE_CAP_PACKED_UNIFORMS:
> +   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>        return 0;
>     case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
>        return 4;
> diff --git a/src/gallium/drivers/svga/svga_screen.c
> b/src/gallium/drivers/svga/svga_screen.c
> index f5f07fa75e..8b50afe889 100644
> --- a/src/gallium/drivers/svga/svga_screen.c
> +++ b/src/gallium/drivers/svga/svga_screen.c
> @@ -452,6 +452,7 @@ svga_get_param(struct pipe_screen *screen, enum
> pipe_cap param)
>     case PIPE_CAP_FENCE_SIGNAL:
>     case PIPE_CAP_CONSTBUF0_FLAGS:
>     case PIPE_CAP_PACKED_UNIFORMS:
> +   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>        return 0;
>     }
>
> diff --git a/src/gallium/drivers/swr/swr_screen.cpp
> b/src/gallium/drivers/swr/swr_screen.cpp
> index 880a177c39..43a27c4c77 100644
> --- a/src/gallium/drivers/swr/swr_screen.cpp
> +++ b/src/gallium/drivers/swr/swr_screen.cpp
> @@ -347,6 +347,7 @@ swr_get_param(struct pipe_screen *screen, enum
> pipe_cap param)
>     case PIPE_CAP_FENCE_SIGNAL:
>     case PIPE_CAP_CONSTBUF0_FLAGS:
>     case PIPE_CAP_PACKED_UNIFORMS:
> +   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>        return 0;
>
>     case PIPE_CAP_VENDOR_ID:
> diff --git a/src/gallium/drivers/vc4/vc4_screen.c
> b/src/gallium/drivers/vc4/vc4_screen.c
> index cead71b77c..81545546c3 100644
> --- a/src/gallium/drivers/vc4/vc4_screen.c
> +++ b/src/gallium/drivers/vc4/vc4_screen.c
> @@ -289,6 +289,7 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum
> pipe_cap param)
>          case PIPE_CAP_FENCE_SIGNAL:
>         case PIPE_CAP_CONSTBUF0_FLAGS:
>          case PIPE_CAP_PACKED_UNIFORMS:
> +        case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>                  return 0;
>
>                  /* Stream output. */
> diff --git a/src/gallium/drivers/vc5/vc5_screen.c
> b/src/gallium/drivers/vc5/vc5_screen.c
> index 271c2c878b..baacbff351 100644
> --- a/src/gallium/drivers/vc5/vc5_screen.c
> +++ b/src/gallium/drivers/vc5/vc5_screen.c
> @@ -261,6 +261,7 @@ vc5_screen_get_param(struct pipe_screen *pscreen, enum
> pipe_cap param)
>          case PIPE_CAP_CONTEXT_PRIORITY_MASK:
>         case PIPE_CAP_CONSTBUF0_FLAGS:
>          case PIPE_CAP_PACKED_UNIFORMS:
> +        case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>                  return 0;
>
>                  /* Geometry shader output, unsupported. */
> diff --git a/src/gallium/drivers/virgl/virgl_screen.c
> b/src/gallium/drivers/virgl/virgl_screen.c
> index 02613f1866..a528123280 100644
> --- a/src/gallium/drivers/virgl/virgl_screen.c
> +++ b/src/gallium/drivers/virgl/virgl_screen.c
> @@ -276,6 +276,7 @@ virgl_get_param(struct pipe_screen *screen, enum
> pipe_cap param)
>     case PIPE_CAP_FENCE_SIGNAL:
>     case PIPE_CAP_CONSTBUF0_FLAGS:
>     case PIPE_CAP_PACKED_UNIFORMS:
> +   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
>        return 0;
>     case PIPE_CAP_VENDOR_ID:
>        return 0x1af4;
> diff --git a/src/gallium/include/pipe/p_context.h
> b/src/gallium/include/pipe/p_context.h
> index c3dc5edf57..3a1fcd239b 100644
> --- a/src/gallium/include/pipe/p_context.h
> +++ b/src/gallium/include/pipe/p_context.h
> @@ -52,6 +52,7 @@ struct pipe_draw_info;
>  struct pipe_grid_info;
>  struct pipe_fence_handle;
>  struct pipe_framebuffer_state;
> +struct pipe_sample_locations_state;
>  struct pipe_image_view;
>  struct pipe_query;
>  struct pipe_poly_stipple;
> @@ -279,6 +280,9 @@ struct pipe_context {
>     void (*set_framebuffer_state)( struct pipe_context *,
>                                    const struct pipe_framebuffer_state * );
>
> +   void (*set_sample_locations_state)( struct pipe_context *,
> +                                       const struct
> pipe_sample_locations_state * );
> +
>     void (*set_polygon_stipple)( struct pipe_context *,
>                                 const struct pipe_poly_stipple * );
>
> @@ -720,7 +724,7 @@ struct pipe_context {
>     /*@}*/
>
>     /**
> -    * Get sample position for an individual sample point.
> +    * Get the default sample position for an individual sample point.
>      *
>      * \param sample_count - total number of samples
>      * \param sample_index - sample to get the position values for
> @@ -732,6 +736,17 @@ struct pipe_context {
>                                 unsigned sample_index,
>                                 float *out_value);
>
> +   /**
> +    * Get the sample pixel grid's size.
> +    *
> +    * \param sample_count - total number of samples
> +    * \param out_width - the width of the pixel grid
> +    * \param out_height - the height of the pixel grid
> +    */
> +   void (*get_sample_pixel_grid)(struct pipe_context *context,
> +                                 unsigned sample_count,
> +                                 unsigned *out_width, unsigned
> *out_height);
> +
>     /**
>      * Query a timestamp in nanoseconds.  This is completely equivalent to
>      * pipe_screen::get_timestamp() but takes a context handle for drivers
> diff --git a/src/gallium/include/pipe/p_defines.h
> b/src/gallium/include/pipe/p_defines.h
> index c4ae053206..b0ce22f675 100644
> --- a/src/gallium/include/pipe/p_defines.h
> +++ b/src/gallium/include/pipe/p_defines.h
> @@ -795,6 +795,7 @@ enum pipe_cap
>     PIPE_CAP_FENCE_SIGNAL,
>     PIPE_CAP_CONSTBUF0_FLAGS,
>     PIPE_CAP_PACKED_UNIFORMS,
> +   PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS,
>  };
>
>  /**
> diff --git a/src/gallium/include/pipe/p_state.h
> b/src/gallium/include/pipe/p_state.h
> index 4dce399f84..3e6243eeda 100644
> --- a/src/gallium/include/pipe/p_state.h
> +++ b/src/gallium/include/pipe/p_state.h
> @@ -74,6 +74,7 @@ extern "C" {
>  #define PIPE_MAX_CLIP_OR_CULL_DISTANCE_COUNT 8
>  #define PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT 2
>  #define PIPE_MAX_WINDOW_RECTANGLES 8
> +#define PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE 4
>
>  #define PIPE_MAX_HW_ATOMIC_BUFFERS 32
>
> @@ -381,6 +382,31 @@ struct pipe_framebuffer_state
>  };
>
>
> +/**
> + * The samples are accessed with
> + * locations[(pixel_y*grid_x+pixel_x)*ms+i],
> + * where:
> + * ms      = the sample count
> + * grid_x  = the pixel grid width for the sample count
> + * grid_y  = the pixel grid height for the sample count
> + * pixel_x = the window x coordinate modulo grid_x
> + * pixel_y = the window y coordinate modulo grid_y
> + * i       = the sample index
> + * This gives a result with the x coordinate as the low 4 bits and the y
> + * coordinate as the high 4 bits. For each coordinate 0 is the left or
> top edge of
> + * the pixel's rectangle and 16 (not 15) is the right or bottom edge.
> + *
> + * The pixel grid is used to vary sample locations across pixels and it's
> size
> + * can be queried with get_sample_pixel_grid().
> + */
> +struct pipe_sample_locations_state
> +{
> +   bool enabled;
> +   uint8_t locations[
> +      PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE*PIPE_MAX_SAMPLE_LOCATION_
> GRID_SIZE*32];
> +};
> +
> +
>  /**
>   * Texture sampler state.
>   */
> --
> 2.14.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to