[Mesa-dev] [PATCH 3/3] nvc0: add ARB_clear_texture support

Samuel Pitoiset samuel.pitoiset at gmail.com
Mon Nov 9 11:58:24 PST 2015



On 11/09/2015 07:40 PM, Ilia Mirkin wrote:
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
>   docs/GL3.txt                                    |  2 +-
>   docs/relnotes/11.1.0.html                       |  1 +
>   src/gallium/drivers/nouveau/nvc0/nvc0_screen.c  |  2 +-
>   src/gallium/drivers/nouveau/nvc0/nvc0_surface.c | 82 +++++++++++++++++++++++++
>   4 files changed, 85 insertions(+), 2 deletions(-)
>
> diff --git a/docs/GL3.txt b/docs/GL3.txt
> index 7abdcd8..da0ffca 100644
> --- a/docs/GL3.txt
> +++ b/docs/GL3.txt
> @@ -177,7 +177,7 @@ GL 4.4, GLSL 4.40:
>
>     GL_MAX_VERTEX_ATTRIB_STRIDE                          DONE (all drivers)
>     GL_ARB_buffer_storage                                DONE (i965, nv50, nvc0, r600, radeonsi)
> -  GL_ARB_clear_texture                                 DONE (i965) (gallium - in progress, VMware)
> +  GL_ARB_clear_texture                                 DONE (i965, nvc0)
>     GL_ARB_enhanced_layouts                              in progress (Timothy)
>     - compile-time constant expressions                  in progress
>     - explicit byte offsets for blocks                   in progress
> diff --git a/docs/relnotes/11.1.0.html b/docs/relnotes/11.1.0.html
> index 11fbdff..33fd0b8 100644
> --- a/docs/relnotes/11.1.0.html
> +++ b/docs/relnotes/11.1.0.html
> @@ -46,6 +46,7 @@ Note: some of the new features are only available with certain drivers.
>   <ul>
>   <li>GL_ARB_arrays_of_arrays on i965</li>
>   <li>GL_ARB_blend_func_extended on freedreno (a3xx)</li>
> +<li>GL_ARB_clear_texture on nvc0</li>
>   <li>GL_ARB_copy_image on nv50, nvc0, radeonsi</li>
>   <li>GL_ARB_gpu_shader_fp64 on r600 for Cypress/Cayman/Aruba chips</li>
>   <li>GL_ARB_gpu_shader5 on r600 for Evergreen and later chips</li>
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> index f2e3bf0..fbeec7f 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> @@ -182,6 +182,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
>      case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
>      case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
>      case PIPE_CAP_SHAREABLE_SHADERS:
> +   case PIPE_CAP_CLEAR_TEXTURE:
>         return 1;
>      case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
>         return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
> @@ -204,7 +205,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
>      case PIPE_CAP_VERTEXID_NOBASE:
>      case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
>      case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
> -   case PIPE_CAP_CLEAR_TEXTURE:
>         return 0;
>
>      case PIPE_CAP_VENDOR_ID:
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
> index 5f47bad..3ae9943 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
> @@ -319,6 +319,8 @@ nvc0_clear_render_target(struct pipe_context *pipe,
>         PUSH_DATA(push, dst->u.tex.first_layer + sf->depth);
>         PUSH_DATA(push, mt->layer_stride >> 2);
>         PUSH_DATA(push, dst->u.tex.first_layer);
> +
> +      IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), mt->ms_mode);
>      } else {
>         if (res->base.target == PIPE_BUFFER) {
>            PUSH_DATA(push, 262144);
> @@ -540,6 +542,7 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe,
>      PUSH_DATA (push, (unk << 16) | (dst->u.tex.first_layer + sf->depth));
>      BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1);
>      PUSH_DATA (push, dst->u.tex.first_layer);
> +   IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), mt->ms_mode);
>
>      BEGIN_NIC0(push, NVC0_3D(CLEAR_BUFFERS), sf->depth);
>      for (z = 0; z < sf->depth; ++z) {
> @@ -550,6 +553,84 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe,
>      nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
>   }
>
> +static void
> +nvc0_clear_texture(struct pipe_context *pipe,
> +                   struct pipe_resource *res,
> +                   unsigned level,
> +                   const struct pipe_box *box,
> +                   const void *data)
> +{
> +   struct nv50_miptree *mt = nv50_miptree(res);
> +   struct nv50_surface sf = {{{0}}};

I'm just curious about this, does '= {}' is not enough?

> +
> +   assert(res->target != PIPE_BUFFER);
> +
> +   sf.base.texture = res;
> +   sf.base.format = res->format;
> +   sf.base.u.tex.first_layer = box->z;
> +   sf.base.u.tex.last_layer = box->depth;
> +   sf.base.u.tex.level = level;
> +   sf.base.width = sf.width = res->width0 << mt->ms_x;
> +   sf.base.height = sf.height = res->height0 << mt->ms_y;
> +   sf.depth = box->depth;
> +   sf.offset = mt->level[level].offset;
> +
> +   if (util_format_is_depth_or_stencil(res->format)) {
> +      float depth = 0;
> +      uint8_t stencil = 0;
> +      unsigned clear = 0;
> +      const struct util_format_description *desc =
> +         util_format_description(res->format);
> +
> +      if (util_format_has_depth(desc)) {
> +         clear |= PIPE_CLEAR_DEPTH;
> +         desc->unpack_z_float(&depth, 0, data, 0, 1, 1);
> +      }
> +      if (util_format_has_stencil(desc)) {
> +         clear |= PIPE_CLEAR_STENCIL;
> +         desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1);
> +      }
> +      nvc0_clear_depth_stencil(pipe, &sf.base, clear, depth, stencil,
> +                               box->x, box->y, box->width, box->height);
> +   } else {
> +      union pipe_color_union color;
> +
> +      switch (util_format_get_blocksizebits(res->format)) {
> +      case 128:
> +         sf.base.format = PIPE_FORMAT_R32G32B32A32_UINT;
> +         memcpy(&color.ui, data, 128 / 8);
> +         break;
> +      case 64:
> +         sf.base.format = PIPE_FORMAT_R32G32_UINT;
> +         memcpy(&color.ui, data, 64 / 8);
> +         memset(&color.ui[2], 0, 64 / 8);
> +         break;
> +      case 32:
> +         sf.base.format = PIPE_FORMAT_R32_UINT;
> +         memcpy(&color.ui, data, 32 / 8);
> +         memset(&color.ui[1], 0, 96 / 8);
> +         break;
> +      case 16:
> +         sf.base.format = PIPE_FORMAT_R16_UINT;
> +         color.ui[0] = util_cpu_to_le32(
> +            util_le16_to_cpu(*(unsigned short *)data));
> +         memset(&color.ui[1], 0, 96 / 8);
> +         break;
> +      case 8:
> +         sf.base.format = PIPE_FORMAT_R8_UINT;
> +         color.ui[0] = util_cpu_to_le32(*(unsigned char *)data);
> +         memset(&color.ui[1], 0, 96 / 8);
> +         break;
> +      default:
> +         assert(!"Unknown texel element size");
> +         return;
> +      }
> +
> +      nvc0_clear_render_target(pipe, &sf.base, &color,
> +                               box->x, box->y, box->width, box->height);
> +   }
> +}
> +
>   void
>   nvc0_clear(struct pipe_context *pipe, unsigned buffers,
>              const union pipe_color_union *color,
> @@ -1541,5 +1622,6 @@ nvc0_init_surface_functions(struct nvc0_context *nvc0)
>      pipe->flush_resource = nvc0_flush_resource;
>      pipe->clear_render_target = nvc0_clear_render_target;
>      pipe->clear_depth_stencil = nvc0_clear_depth_stencil;
> +   pipe->clear_texture = nvc0_clear_texture;
>      pipe->clear_buffer = nvc0_clear_buffer;
>   }
>


More information about the mesa-dev mailing list