gallium/radeon: implement ARB_clear_texture (v3)
authorMarek Olšák <marek.olsak@amd.com>
Thu, 4 Aug 2016 17:04:02 +0000 (19:04 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 9 Aug 2016 23:11:10 +0000 (01:11 +0200)
Some ideas copied from Jakob Sinclair's implementation, but the color
clearing is completely different.

v2: remove leftover code, disable conditional rendering
    disable render condition cleanly

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
docs/GL3.txt
docs/relnotes/12.1.0.html
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/radeon/r600_texture.c
src/gallium/drivers/radeonsi/si_pipe.c

index 0ba5a2597a1c1f4853a0fa90a8d6dd4d08b0014d..6597984323c42727fabad6753497d6230f6291a5 100644 (file)
@@ -192,7 +192,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, 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
index 120403822bd3391cd35f1b81b7bfc7719c21618c..23249720244f791312866e448baac4b577678760 100644 (file)
@@ -44,6 +44,7 @@ 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_indirect_parameters on radeonsi</li>
 <li>GL_ARB_shader_draw_parameters on radeonsi</li>
index 39a310abebb660cc827a2552d0048bfae284312e..5f69a5d1b2ffbbbf03efcb5d2d6651fb3b79e447 100644 (file)
@@ -283,6 +283,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        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:
@@ -355,7 +356,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        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:
index f7c2f80ec3c01f649da62406877548f60f178366..ddfa13503a6036e1f20be37334b98e7d4bd07e68 100644 (file)
@@ -30,6 +30,7 @@
 #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>
@@ -1696,6 +1697,71 @@ static void r600_surface_destroy(struct pipe_context *pipe,
        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}};
+       struct pipe_surface *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, false);
+       } 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, false);
+               } 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);
@@ -2332,4 +2398,5 @@ 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;
 }
index 86d7632c36971931014c93a7a459b88d576cca71..62b62db34a849ce677b05b89b73a0fbed7b04c0d 100644 (file)
@@ -386,6 +386,7 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        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:
@@ -434,7 +435,6 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        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_QUERY_BUFFER_OBJECT:
        case PIPE_CAP_CULL_DISTANCE:
        case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES: