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

Ilia Mirkin imirkin at alum.mit.edu
Wed Jul 16 06:57:58 PDT 2014


On Wed, Jul 16, 2014 at 9:53 AM, Glenn Kennard <glenn.kennard at gmail.com> wrote:
> Only supported on evergreen and later. Currently 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>
> ---
> Changes from v1:
>  Removed PIPE_CAP_TEXTURE_GATHER_SM5 cap
>
> This patch should be equivalent to the ARB_texture_gather only
> portions of David Airlie's work in progress gather implementation
> http://cgit.freedesktop.org/~airlied/mesa/log/?h=r600g-texture-gather
>
> Further work is needed to enable the GL_ARB_gpu_shader5 enhancements
> to texture gather, in particular keying sampler swizzle state to
> shader variants with the appropriate component selects.
>
>  docs/GL3.txt                           |  2 +-
>  docs/relnotes/10.3.html                |  2 +-
>  src/gallium/drivers/r600/r600_pipe.c   |  3 ++-
>  src/gallium/drivers/r600/r600_shader.c | 47 +++++++++++++++++++++++++++++-----
>  4 files changed, 45 insertions(+), 9 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..a762b00 100644
> --- a/src/gallium/drivers/r600/r600_pipe.c
> +++ b/src/gallium/drivers/r600/r600_pipe.c
> @@ -303,6 +303,8 @@ 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:
> +               return 0;

oops?

> +       case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
>                 return family >= CHIP_CEDAR ? 1 : 0;
>
>         /* Unsupported features. */
> @@ -312,7 +314,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:
> 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