[Mesa-dev] [PATCH] gallium/radeon: implement ARB_clear_texture (v2)

Nicolai Hähnle nhaehnle at gmail.com
Sat Aug 6 11:14:59 UTC 2016


On 05.08.2016 14:20, Marek Olšák wrote:
> On Aug 5, 2016 10:54 AM, "Nicolai Hähnle" <nhaehnle at gmail.com
> <mailto:nhaehnle at gmail.com>> wrote:
>>
>>
>>
>> On 04.08.2016 21:42, Marek Olšák wrote:
>>>
>>> From: Marek Olšák <marek.olsak at amd.com <mailto:marek.olsak at amd.com>>
>>>
>>> Some ideas copied from Jakob Sinclair's implementation, but the color
>>> clearing is completely different.
>>>
>>> v2: remove leftover code, disable conditional rendering
>>> ---
>>>  docs/GL3.txt                              |  2 +-
>>>  docs/relnotes/12.1.0.html                 |  1 +
>>>  src/gallium/drivers/r600/r600_blit.c      |  6 ++-
>>>  src/gallium/drivers/r600/r600_pipe.c      |  2 +-
>>>  src/gallium/drivers/radeon/r600_texture.c | 66
> +++++++++++++++++++++++++++++++
>>>  src/gallium/drivers/radeonsi/si_blit.c    |  6 ++-
>>>  src/gallium/drivers/radeonsi/si_pipe.c    |  2 +-
>>>  7 files changed, 80 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/docs/GL3.txt b/docs/GL3.txt
>>> index c185c69..5dcfc31 100644
>>> --- a/docs/GL3.txt
>>> +++ b/docs/GL3.txt
>>> @@ -185,21 +185,21 @@ GL 4.3, GLSL 4.30 -- all DONE: nvc0, radeonsi
>>>    GL_ARB_texture_query_levels                           DONE (all
> drivers that support GLSL 1.30)
>>>    GL_ARB_texture_storage_multisample                    DONE (all
> drivers that support GL_ARB_texture_multisample)
>>>    GL_ARB_texture_view                                   DONE (i965,
> nv50, r600, llvmpipe, softpipe, swr)
>>>    GL_ARB_vertex_attrib_binding                          DONE (all
> drivers)
>>>
>>>
>>>  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,
> nv50, nvc0)
>>> +  GL_ARB_clear_texture                                  DONE (i965,
> nv50, nvc0, r600, radeonsi)
>>>    GL_ARB_enhanced_layouts                               DONE (i965)
>>>    - compile-time constant expressions                   DONE
>>>    - explicit byte offsets for blocks                    DONE
>>>    - forced alignment within blocks                      DONE
>>>    - specified vec4-slot component numbers               DONE (i965)
>>>    - specified transform/feedback layout                 DONE
>>>    - input/output block locations                        DONE
>>>    GL_ARB_multi_bind                                     DONE (all
> drivers)
>>>    GL_ARB_query_buffer_object                            DONE
> (i965/hsw+, nvc0)
>>>    GL_ARB_texture_mirror_clamp_to_edge                   DONE (i965,
> nv50, nvc0, r600, radeonsi, llvmpipe, softpipe, swr)
>>> diff --git a/docs/relnotes/12.1.0.html b/docs/relnotes/12.1.0.html
>>> index 3935bb0..ed98d13 100644
>>> --- a/docs/relnotes/12.1.0.html
>>> +++ b/docs/relnotes/12.1.0.html
>>> @@ -37,20 +37,21 @@ TBD.
>>>  </pre>
>>>
>>>
>>>  <h2>New features</h2>
>>>
>>>  <p>
>>>  Note: some of the new features are only available with certain drivers.
>>>  </p>
>>>
>>>  <ul>
>>> +<li>GL_ARB_clear_texture on r600, radeonsi</li>
>>>  <li>GL_ARB_enhanced_layouts on i965</li>
>>>  <li>GL_ARB_shader_group_vote on nvc0</li>
>>>  <li>GL_ARB_ES3_1_compatibility on i965</li>
>>>  <li>GL_EXT_window_rectangles on nv50, nvc0</li>
>>>  <li>GL_KHR_texture_compression_astc_sliced_3d on i965</li>
>>>  </ul>
>>>
>>>  <h2>Bug fixes</h2>
>>>
>>>  TBD.
>>> diff --git a/src/gallium/drivers/r600/r600_blit.c
> b/src/gallium/drivers/r600/r600_blit.c
>>> index a6c5b44..8f2e2a6 100644
>>> --- a/src/gallium/drivers/r600/r600_blit.c
>>> +++ b/src/gallium/drivers/r600/r600_blit.c
>>> @@ -29,21 +29,25 @@
>>>
>>>  enum r600_blitter_op /* bitmask */
>>>  {
>>>         R600_SAVE_FRAGMENT_STATE = 1,
>>>         R600_SAVE_TEXTURES       = 2,
>>>         R600_SAVE_FRAMEBUFFER    = 4,
>>>         R600_DISABLE_RENDER_COND = 8,
>>>
>>>         R600_CLEAR         = R600_SAVE_FRAGMENT_STATE,
>>>
>>> -       R600_CLEAR_SURFACE = R600_SAVE_FRAGMENT_STATE |
> R600_SAVE_FRAMEBUFFER,
>>> +       /* GL_ARB_clear_texture should ignore the render condition, but
>>> +        * Gallium shouldn't. Follow OpenGL.
>>> +        */
>>> +       R600_CLEAR_SURFACE = R600_SAVE_FRAGMENT_STATE |
> R600_SAVE_FRAMEBUFFER |
>>> +                            R600_DISABLE_RENDER_COND,
>>
>>
>> It's annoying, but doesn't this break conditional rendering of glClear?
>
> glClear doesn't use these clear functions.

I see. It uses clear but not clear_depth_stencil or clear_render_target.

Is there anything using clear_depth_stencil / clear_render_target that 
wants conditional render? Maybe the "definition" of the Gallium 
interface should be changed here. At least there's a certain logic in 
that those two functions take a destination surface as parameter while 
clear doesn't.

Nicolai

> Marek
>
>>
>> Nicolai
>>
>>
>>>
>>>         R600_COPY_BUFFER   = R600_DISABLE_RENDER_COND,
>>>
>>>         R600_COPY_TEXTURE  = R600_SAVE_FRAGMENT_STATE |
> R600_SAVE_FRAMEBUFFER | R600_SAVE_TEXTURES |
>>>                              R600_DISABLE_RENDER_COND,
>>>
>>>         R600_BLIT          = R600_SAVE_FRAGMENT_STATE |
> R600_SAVE_FRAMEBUFFER | R600_SAVE_TEXTURES,
>>>
>>>         R600_DECOMPRESS    = R600_SAVE_FRAGMENT_STATE |
> R600_SAVE_FRAMEBUFFER | R600_DISABLE_RENDER_COND,
>>>
>>> diff --git a/src/gallium/drivers/r600/r600_pipe.c
> b/src/gallium/drivers/r600/r600_pipe.c
>>> index 39a310a..5f69a5d 100644
>>> --- a/src/gallium/drivers/r600/r600_pipe.c
>>> +++ b/src/gallium/drivers/r600/r600_pipe.c
>>> @@ -276,20 +276,21 @@ static int r600_get_param(struct pipe_screen*
> pscreen, enum pipe_cap param)
>>>         case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
>>>         case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
>>>         case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
>>>         case PIPE_CAP_TGSI_TXQS:
>>>         case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
>>>         case PIPE_CAP_INVALIDATE_BUFFER:
>>>         case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
>>>         case PIPE_CAP_QUERY_MEMORY_INFO:
>>>         case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
>>>         case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
>>> +       case PIPE_CAP_CLEAR_TEXTURE:
>>>                 return 1;
>>>
>>>         case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
>>>                 return rscreen->b.info.drm_major == 2 &&
> rscreen->b.info.drm_minor >= 43;
>>>
>>>         case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
>>>                 return !R600_BIG_ENDIAN && rscreen->b.info.has_userptr;
>>>
>>>         case PIPE_CAP_COMPUTE:
>>>                 return rscreen->b.chip_class > R700;
>>> @@ -348,21 +349,20 @@ static int r600_get_param(struct pipe_screen*
> pscreen, enum pipe_cap param)
>>>         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
>>>         case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
>>>         case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
>>>         case PIPE_CAP_VERTEX_COLOR_CLAMPED:
>>>         case PIPE_CAP_USER_VERTEX_BUFFERS:
>>>         case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
>>>         case PIPE_CAP_VERTEXID_NOBASE:
>>>         case PIPE_CAP_DEPTH_BOUNDS_TEST:
>>>         case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
>>>         case PIPE_CAP_SHAREABLE_SHADERS:
>>> -       case PIPE_CAP_CLEAR_TEXTURE:
>>>         case PIPE_CAP_DRAW_PARAMETERS:
>>>         case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
>>>         case PIPE_CAP_MULTI_DRAW_INDIRECT:
>>>         case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
>>>         case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
>>>         case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
>>>         case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
>>>         case PIPE_CAP_GENERATE_MIPMAP:
>>>         case PIPE_CAP_STRING_MARKER:
>>>         case PIPE_CAP_QUERY_BUFFER_OBJECT:
>>> diff --git a/src/gallium/drivers/radeon/r600_texture.c
> b/src/gallium/drivers/radeon/r600_texture.c
>>> index f7c2f80..0b13f36 100644
>>> --- a/src/gallium/drivers/radeon/r600_texture.c
>>> +++ b/src/gallium/drivers/radeon/r600_texture.c
>>> @@ -23,20 +23,21 @@
>>>   * Authors:
>>>   *      Jerome Glisse
>>>   *      Corbin Simpson
>>>   */
>>>  #include "r600_pipe_common.h"
>>>  #include "r600_cs.h"
>>>  #include "r600_query.h"
>>>  #include "util/u_format.h"
>>>  #include "util/u_memory.h"
>>>  #include "util/u_pack_color.h"
>>> +#include "util/u_surface.h"
>>>  #include "os/os_time.h"
>>>  #include <errno.h>
>>>  #include <inttypes.h>
>>>
>>>  static void r600_texture_discard_cmask(struct r600_common_screen
> *rscreen,
>>>                                        struct r600_texture *rtex);
>>>  static unsigned r600_choose_tiling(struct r600_common_screen *rscreen,
>>>                                    const struct pipe_resource *templ);
>>>
>>>
>>> @@ -1689,20 +1690,84 @@ static struct pipe_surface
> *r600_create_surface(struct pipe_context *pipe,
>>>  static void r600_surface_destroy(struct pipe_context *pipe,
>>>                                  struct pipe_surface *surface)
>>>  {
>>>         struct r600_surface *surf = (struct r600_surface*)surface;
>>>         r600_resource_reference(&surf->cb_buffer_fmask, NULL);
>>>         r600_resource_reference(&surf->cb_buffer_cmask, NULL);
>>>         pipe_resource_reference(&surface->texture, NULL);
>>>         FREE(surface);
>>>  }
>>>
>>> +static void r600_clear_texture(struct pipe_context *pipe,
>>> +                              struct pipe_resource *tex,
>>> +                              unsigned level,
>>> +                              const struct pipe_box *box,
>>> +                              const void *data)
>>> +{
>>> +       struct pipe_screen *screen = pipe->screen;
>>> +       struct r600_texture *rtex = (struct r600_texture*)tex;
>>> +       struct pipe_surface tmpl = {{0}}, *sf;
>>> +       const struct util_format_description *desc =
>>> +               util_format_description(tex->format);
>>> +
>>> +       tmpl.format = tex->format;
>>> +       tmpl.u.tex.first_layer = box->z;
>>> +       tmpl.u.tex.last_layer = box->z + box->depth - 1;
>>> +       tmpl.u.tex.level = level;
>>> +       sf = pipe->create_surface(pipe, tex, &tmpl);
>>> +       if (!sf)
>>> +               return;
>>> +
>>> +       if (rtex->is_depth) {
>>> +               unsigned clear;
>>> +               float depth;
>>> +               uint8_t stencil = 0;
>>> +
>>> +               /* Depth is always present. */
>>> +               clear = PIPE_CLEAR_DEPTH;
>>> +               desc->unpack_z_float(&depth, 0, data, 0, 1, 1);
>>> +
>>> +               if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
>>> +                       clear |= PIPE_CLEAR_STENCIL;
>>> +                       desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1);
>>> +               }
>>> +
>>> +               pipe->clear_depth_stencil(pipe, sf, clear, depth,
> stencil,
>>> +                                         box->x, box->y,
>>> +                                         box->width, box->height);
>>> +       } else {
>>> +               union pipe_color_union color;
>>> +
>>> +               /* pipe_color_union requires the full vec4
> representation. */
>>> +               if (util_format_is_pure_uint(tex->format))
>>> +                       desc->unpack_rgba_uint(color.ui, 0, data, 0,
> 1, 1);
>>> +               else if (util_format_is_pure_sint(tex->format))
>>> +                       desc->unpack_rgba_sint(color.i, 0, data, 0,
> 1, 1);
>>> +               else
>>> +                       desc->unpack_rgba_float(color.f, 0, data, 0,
> 1, 1);
>>> +
>>> +               if (screen->is_format_supported(screen, tex->format,
>>> +                                               tex->target, 0,
>>> +
>  PIPE_BIND_RENDER_TARGET)) {
>>> +                       pipe->clear_render_target(pipe, sf, &color,
>>> +                                                 box->x, box->y,
>>> +                                                 box->width,
> box->height);
>>> +               } else {
>>> +                       /* Software fallback - just for R9G9B9E5_FLOAT */
>>> +                       util_clear_render_target(pipe, sf, &color,
>>> +                                                box->x, box->y,
>>> +                                                box->width,
> box->height);
>>> +               }
>>> +       }
>>> +       pipe_surface_reference(&sf, NULL);
>>> +}
>>> +
>>>  unsigned r600_translate_colorswap(enum pipe_format format, bool
> do_endian_swap)
>>>  {
>>>         const struct util_format_description *desc =
> util_format_description(format);
>>>
>>>  #define HAS_SWIZZLE(chan,swz) (desc->swizzle[chan] ==
> PIPE_SWIZZLE_##swz)
>>>
>>>         if (format == PIPE_FORMAT_R11G11B10_FLOAT) /* isn't plain */
>>>                 return V_0280A0_SWAP_STD;
>>>
>>>         if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
>>> @@ -2325,11 +2390,12 @@ void evergreen_do_fast_color_clear(struct
> r600_common_context *rctx,
>>>  void r600_init_screen_texture_functions(struct r600_common_screen
> *rscreen)
>>>  {
>>>         rscreen->b.resource_from_handle = r600_texture_from_handle;
>>>         rscreen->b.resource_get_handle = r600_texture_get_handle;
>>>  }
>>>
>>>  void r600_init_context_texture_functions(struct r600_common_context
> *rctx)
>>>  {
>>>         rctx->b.create_surface = r600_create_surface;
>>>         rctx->b.surface_destroy = r600_surface_destroy;
>>> +       rctx->b.clear_texture = r600_clear_texture;
>>>  }
>>> diff --git a/src/gallium/drivers/radeonsi/si_blit.c
> b/src/gallium/drivers/radeonsi/si_blit.c
>>> index 38a19d5..6fcf0f0 100644
>>> --- a/src/gallium/drivers/radeonsi/si_blit.c
>>> +++ b/src/gallium/drivers/radeonsi/si_blit.c
>>> @@ -28,21 +28,25 @@
>>>
>>>  enum si_blitter_op /* bitmask */
>>>  {
>>>         SI_SAVE_TEXTURES      = 1,
>>>         SI_SAVE_FRAMEBUFFER   = 2,
>>>         SI_SAVE_FRAGMENT_STATE = 4,
>>>         SI_DISABLE_RENDER_COND = 8,
>>>
>>>         SI_CLEAR         = SI_SAVE_FRAGMENT_STATE,
>>>
>>> -       SI_CLEAR_SURFACE = SI_SAVE_FRAMEBUFFER | SI_SAVE_FRAGMENT_STATE,
>>> +       /* GL_ARB_clear_texture should ignore the render condition, but
>>> +        * Gallium shouldn't. Follow OpenGL.
>>> +        */
>>> +       SI_CLEAR_SURFACE = SI_SAVE_FRAMEBUFFER | SI_SAVE_FRAGMENT_STATE |
>>> +                          SI_DISABLE_RENDER_COND,
>>>
>>>         SI_COPY          = SI_SAVE_FRAMEBUFFER | SI_SAVE_TEXTURES |
>>>                            SI_SAVE_FRAGMENT_STATE |
> SI_DISABLE_RENDER_COND,
>>>
>>>         SI_BLIT          = SI_SAVE_FRAMEBUFFER | SI_SAVE_TEXTURES |
>>>                            SI_SAVE_FRAGMENT_STATE,
>>>
>>>         SI_DECOMPRESS    = SI_SAVE_FRAMEBUFFER | SI_SAVE_FRAGMENT_STATE |
>>>                            SI_DISABLE_RENDER_COND,
>>>
>>> diff --git a/src/gallium/drivers/radeonsi/si_pipe.c
> b/src/gallium/drivers/radeonsi/si_pipe.c
>>> index e33823d..c1c2a9a 100644
>>> --- a/src/gallium/drivers/radeonsi/si_pipe.c
>>> +++ b/src/gallium/drivers/radeonsi/si_pipe.c
>>> @@ -379,20 +379,21 @@ static int si_get_param(struct pipe_screen*
> pscreen, enum pipe_cap param)
>>>         case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
>>>         case PIPE_CAP_INVALIDATE_BUFFER:
>>>         case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
>>>         case PIPE_CAP_QUERY_MEMORY_INFO:
>>>         case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
>>>         case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
>>>         case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
>>>         case PIPE_CAP_GENERATE_MIPMAP:
>>>         case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
>>>         case PIPE_CAP_STRING_MARKER:
>>> +       case PIPE_CAP_CLEAR_TEXTURE:
>>>                 return 1;
>>>
>>>         case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
>>>                 return !SI_BIG_ENDIAN && sscreen->b.info.has_userptr;
>>>
>>>         case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
>>>                 return (sscreen->b.info.drm_major == 2 &&
>>>                         sscreen->b.info.drm_minor >= 43) ||
>>>                        sscreen->b.info.drm_major == 3;
>>>
>>> @@ -427,21 +428,20 @@ static int si_get_param(struct pipe_screen*
> pscreen, enum pipe_cap param)
>>>         case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
>>>                 return 0;
>>>
>>>         /* Unsupported features. */
>>>         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
>>>         case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
>>>         case PIPE_CAP_USER_VERTEX_BUFFERS:
>>>         case PIPE_CAP_FAKE_SW_MSAA:
>>>         case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
>>>         case PIPE_CAP_VERTEXID_NOBASE:
>>> -       case PIPE_CAP_CLEAR_TEXTURE:
>>>         case PIPE_CAP_DRAW_PARAMETERS:
>>>         case PIPE_CAP_MULTI_DRAW_INDIRECT:
>>>         case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
>>>         case PIPE_CAP_QUERY_BUFFER_OBJECT:
>>>         case PIPE_CAP_CULL_DISTANCE:
>>>         case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
>>>         case PIPE_CAP_TGSI_VOTE:
>>>         case PIPE_CAP_MAX_WINDOW_RECTANGLES:
>>>                 return 0;
>>>
>>>
>


More information about the mesa-dev mailing list