[Mesa-dev] [PATCH] r600g: Implement GL_ARB_texture_gather

Ilia Mirkin imirkin at alum.mit.edu
Mon Jul 14 11:33:08 PDT 2014


On Mon, Jul 14, 2014 at 2:20 PM, Glenn Kennard <glenn.kennard at gmail.com> wrote:
> Only supported on evergreen and later. Limited to
> single component textures as the hardware GATHER4
> instruction ignores texture swizzles.
>
> Piglit quick run passes on radeon 6670 with all
> applicable textureGather tests, no regressions.
>
> Signed-off-by: Glenn Kennard <glenn.kennard at gmail.com>
> ---
>  docs/GL3.txt                           |  2 +-
>  docs/relnotes/10.3.html                |  2 +-
>  src/gallium/drivers/r600/r600_pipe.c   |  5 ++--
>  src/gallium/drivers/r600/r600_shader.c | 47 +++++++++++++++++++++++++++++-----
>  4 files changed, 46 insertions(+), 10 deletions(-)
>
> diff --git a/docs/GL3.txt b/docs/GL3.txt
> index a2f438b..20e57b0 100644
> --- a/docs/GL3.txt
> +++ b/docs/GL3.txt
> @@ -118,7 +118,7 @@ GL 4.0:
>    GL_ARB_tessellation_shader                           started (Fabian)
>    GL_ARB_texture_buffer_object_rgb32                   DONE (i965, nvc0, r600, radeonsi, softpipe)
>    GL_ARB_texture_cube_map_array                        DONE (i965, nv50, nvc0, r600, radeonsi, softpipe)
> -  GL_ARB_texture_gather                                DONE (i965, nv50, nvc0, radeonsi)
> +  GL_ARB_texture_gather                                DONE (i965, nv50, nvc0, radeonsi, r600)
>    GL_ARB_texture_query_lod                             DONE (i965, nv50, nvc0, radeonsi)
>    GL_ARB_transform_feedback2                           DONE (i965, nv50, nvc0, r600, radeonsi)
>    GL_ARB_transform_feedback3                           DONE (i965, nv50, nvc0, r600, radeonsi)
> diff --git a/docs/relnotes/10.3.html b/docs/relnotes/10.3.html
> index 2e718fc..1c0fab6 100644
> --- a/docs/relnotes/10.3.html
> +++ b/docs/relnotes/10.3.html
> @@ -49,7 +49,7 @@ Note: some of the new features are only available with certain drivers.
>  <li>GL_ARB_sample_shading on radeonsi</li>
>  <li>GL_ARB_stencil_texturing on nv50, nvc0, r600, and radeonsi</li>
>  <li>GL_ARB_texture_cube_map_array on radeonsi</li>
> -<li>GL_ARB_texture_gather on radeonsi</li>
> +<li>GL_ARB_texture_gather on radeonsi, r600</li>
>  <li>GL_ARB_texture_query_levels on nv50, nvc0, llvmpipe, r600, radeonsi, softpipe</li>
>  <li>GL_ARB_texture_query_lod on radeonsi</li>
>  <li>GL_ARB_viewport_array on nvc0</li>
> diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
> index ca6399f..d967f0f 100644
> --- a/src/gallium/drivers/r600/r600_pipe.c
> +++ b/src/gallium/drivers/r600/r600_pipe.c
> @@ -303,6 +303,9 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
>         case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
>         case PIPE_CAP_CUBE_MAP_ARRAY:
>         case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
> +       case PIPE_CAP_TEXTURE_GATHER_SM5:
> +               return family >= CHIP_CEDAR ? 1 : 0;

No clue what the hardware supports, and this CAP is actually not used
by the state tracker. However I believe it is meant to imply that you
can support the ARB_gs5 texture gather, including shadow comparisons
and non-constant offsets. This is not yet turned on by core mesa, but
do the textureGather tests still pass if you add
MESA_EXTENSION_OVERRIDE=GL_ARB_gpu_shader5? (You can do a piglit-run
with -t gather.) I'm not 100% sure, but I _think_ it also implies that
you can deal with selecting any component from a 4-component
texture... the ARB_gs5 spec says:

    Since this extension requires support for gathering from multi-component
    textures, the minimum value of MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB
    is increased to 4.

My understanding is that the hardware is meant to be able to support
GL4 one way or aonther, but sounds like more work needs to be done in
order to claim the SM5 compatibility cap...

Also, have you looked at Dave Airlie's impl? Not sure what's been
going on there...
http://cgit.freedesktop.org/~airlied/mesa/log/?h=r600g-texture-gather
. He seemed to enable 4 components for >= CEDAR.

> +       case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
>                 return family >= CHIP_CEDAR ? 1 : 0;
>
>         /* Unsupported features. */
> @@ -312,8 +315,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
>         case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
>         case PIPE_CAP_VERTEX_COLOR_CLAMPED:
>         case PIPE_CAP_USER_VERTEX_BUFFERS:
> -       case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
> -       case PIPE_CAP_TEXTURE_GATHER_SM5:
>         case PIPE_CAP_TEXTURE_QUERY_LOD:
>         case PIPE_CAP_SAMPLE_SHADING:
>         case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
> diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
> index 6952e3c..db928f3 100644
> --- a/src/gallium/drivers/r600/r600_shader.c
> +++ b/src/gallium/drivers/r600/r600_shader.c
> @@ -4477,7 +4477,8 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
>
>         if (inst->Instruction.Opcode == TGSI_OPCODE_TEX2 ||
>             inst->Instruction.Opcode == TGSI_OPCODE_TXB2 ||
> -           inst->Instruction.Opcode == TGSI_OPCODE_TXL2)
> +           inst->Instruction.Opcode == TGSI_OPCODE_TXL2 ||
> +           inst->Instruction.Opcode == TGSI_OPCODE_TG4)
>                 sampler_src_reg = 2;
>
>         src_gpr = tgsi_tex_get_src_gpr(ctx, 0);
> @@ -5079,6 +5080,13 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
>                 case FETCH_OP_SAMPLE_G:
>                         opcode = FETCH_OP_SAMPLE_C_G;
>                         break;
> +               /* Texture gather variants */
> +               case FETCH_OP_GATHER4:
> +                       tex.op = FETCH_OP_GATHER4_C;
> +                       break;
> +               case FETCH_OP_GATHER4_O:
> +                       tex.op = FETCH_OP_GATHER4_C_O;
> +                       break;
>                 }
>         }
>
> @@ -5089,9 +5097,21 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
>         tex.resource_id = tex.sampler_id + R600_MAX_CONST_BUFFERS;
>         tex.src_gpr = src_gpr;
>         tex.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Dst[0].Register.Index;
> -       tex.dst_sel_x = (inst->Dst[0].Register.WriteMask & 1) ? 0 : 7;
> -       tex.dst_sel_y = (inst->Dst[0].Register.WriteMask & 2) ? 1 : 7;
> -       tex.dst_sel_z = (inst->Dst[0].Register.WriteMask & 4) ? 2 : 7;
> +
> +       if (inst->Instruction.Opcode == TGSI_OPCODE_TG4) {
> +               int8_t texture_component_select = ctx->literals[4 * inst->Src[1].Register.Index + inst->Src[1].Register.SwizzleX];
> +               tex.inst_mod = texture_component_select;
> +
> +               /* GATHER4 result order is different from TGSI TG4 */
> +               tex.dst_sel_x = (inst->Dst[0].Register.WriteMask & 2) ? 1 : 7;
> +               tex.dst_sel_y = (inst->Dst[0].Register.WriteMask & 4) ? 2 : 7;
> +               tex.dst_sel_z = (inst->Dst[0].Register.WriteMask & 1) ? 0 : 7;
> +       }
> +       else {
> +               tex.dst_sel_x = (inst->Dst[0].Register.WriteMask & 1) ? 0 : 7;
> +               tex.dst_sel_y = (inst->Dst[0].Register.WriteMask & 2) ? 1 : 7;
> +               tex.dst_sel_z = (inst->Dst[0].Register.WriteMask & 4) ? 2 : 7;
> +       }
>         tex.dst_sel_w = (inst->Dst[0].Register.WriteMask & 8) ? 3 : 7;
>
>         if (inst->Instruction.Opcode == TGSI_OPCODE_TXQ_LZ) {
> @@ -5132,7 +5152,13 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
>
>         tex.offset_x = offset_x;
>         tex.offset_y = offset_y;
> -       tex.offset_z = offset_z;
> +       if (inst->Instruction.Opcode == TGSI_OPCODE_TG4 &&
> +               inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY) {
> +               tex.offset_z = 0;
> +       }
> +       else {
> +               tex.offset_z = offset_z;
> +       }
>
>         /* Put the depth for comparison in W.
>          * TGSI_TEXTURE_SHADOW2D_ARRAY already has the depth in W.
> @@ -5166,7 +5192,7 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
>                 tex.coord_type_z = 0;
>
>         /* mask unused source components */
> -       if (opcode == FETCH_OP_SAMPLE) {
> +       if (opcode == FETCH_OP_SAMPLE || opcode == FETCH_OP_GATHER4) {
>                 switch (inst->Texture.Texture) {
>                 case TGSI_TEXTURE_2D:
>                 case TGSI_TEXTURE_RECT:
> @@ -6640,6 +6666,9 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = {
>         {TGSI_OPCODE_TEX2,      0, FETCH_OP_SAMPLE, tgsi_tex},
>         {TGSI_OPCODE_TXB2,      0, FETCH_OP_SAMPLE_LB, tgsi_tex},
>         {TGSI_OPCODE_TXL2,      0, FETCH_OP_SAMPLE_L, tgsi_tex},
> +       {TGSI_OPCODE_IMUL_HI, 0, ALU_OP0_NOP, tgsi_unsupported},
> +       {TGSI_OPCODE_UMUL_HI, 0, ALU_OP0_NOP, tgsi_unsupported},
> +       {TGSI_OPCODE_TG4,   0, FETCH_OP_GATHER4, tgsi_unsupported},
>         {TGSI_OPCODE_LAST,      0, ALU_OP0_NOP, tgsi_unsupported},
>  };
>
> @@ -6832,6 +6861,9 @@ static struct r600_shader_tgsi_instruction eg_shader_tgsi_instruction[] = {
>         {TGSI_OPCODE_TEX2,      0, FETCH_OP_SAMPLE, tgsi_tex},
>         {TGSI_OPCODE_TXB2,      0, FETCH_OP_SAMPLE_LB, tgsi_tex},
>         {TGSI_OPCODE_TXL2,      0, FETCH_OP_SAMPLE_L, tgsi_tex},
> +       {TGSI_OPCODE_IMUL_HI, 0, ALU_OP0_NOP, tgsi_unsupported},
> +       {TGSI_OPCODE_UMUL_HI, 0, ALU_OP0_NOP, tgsi_unsupported},
> +       {TGSI_OPCODE_TG4,   0, FETCH_OP_GATHER4, tgsi_tex},
>         {TGSI_OPCODE_LAST,      0, ALU_OP0_NOP, tgsi_unsupported},
>  };
>
> @@ -7025,5 +7057,8 @@ static struct r600_shader_tgsi_instruction cm_shader_tgsi_instruction[] = {
>         {TGSI_OPCODE_TEX2,      0, FETCH_OP_SAMPLE, tgsi_tex},
>         {TGSI_OPCODE_TXB2,      0, FETCH_OP_SAMPLE_LB, tgsi_tex},
>         {TGSI_OPCODE_TXL2,      0, FETCH_OP_SAMPLE_L, tgsi_tex},
> +       {TGSI_OPCODE_IMUL_HI, 0, ALU_OP0_NOP, tgsi_unsupported},
> +       {TGSI_OPCODE_UMUL_HI, 0, ALU_OP0_NOP, tgsi_unsupported},
> +       {TGSI_OPCODE_TG4,   0, FETCH_OP_GATHER4, tgsi_tex},
>         {TGSI_OPCODE_LAST,      0, ALU_OP0_NOP, tgsi_unsupported},
>  };
> --
> 1.8.3.2
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list