radeonsi: implement ARB_texture_query_lod
authorMarek Olšák <marek.olsak@amd.com>
Mon, 16 Jun 2014 14:53:42 +0000 (16:53 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 18 Jun 2014 22:18:17 +0000 (00:18 +0200)
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
docs/GL3.txt
docs/relnotes/10.3.html
src/gallium/drivers/radeonsi/si_pipe.c
src/gallium/drivers/radeonsi/si_shader.c

index 375b3b58bdbafd148849ff54fc3c5405b4d79fc7..47165fe1e9fc92d51311d47023e865c450e90298 100644 (file)
@@ -97,7 +97,6 @@ GL 3.3 --- all DONE: i965, nv50, nvc0, r600, radeonsi
 GL 4.0:
 
   GLSL 4.0                                             not started
-  GL_ARB_texture_query_lod                             DONE (i965, nv50, nvc0)
   GL_ARB_draw_buffers_blend                            DONE (i965, nv50, nvc0, r600, radeonsi, softpipe)
   GL_ARB_draw_indirect                                 DONE (i965)
   GL_ARB_gpu_shader5                                   started
@@ -120,6 +119,7 @@ GL 4.0:
   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_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)
 
index 99393014c8bba89c1cc66f5e17b47ed1d4987c47..ecc8580f42b3a08b6ee303305c787a24e384254a 100644 (file)
@@ -51,6 +51,7 @@ Note: some of the new features are only available with certain drivers.
 <li>GL_ARB_texture_cube_map_array on radeonsi</li>
 <li>GL_ARB_texture_gather on radeonsi</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>
 </ul>
 
index a3e18468d38ce82520c1d40337f4328f46ef2d3f..07f429164d73574c1daec34b067e6091621d18dc 100644 (file)
@@ -234,6 +234,7 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
                return MIN2(sscreen->b.info.vram_size, 0xFFFFFFFF);
 
+       case PIPE_CAP_TEXTURE_QUERY_LOD:
        case PIPE_CAP_TEXTURE_GATHER_SM5:
                return HAVE_LLVM >= 0x0305;
        case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
@@ -249,7 +250,6 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_USER_VERTEX_BUFFERS:
        case PIPE_CAP_TGSI_TEXCOORD:
        case PIPE_CAP_FAKE_SW_MSAA:
-       case PIPE_CAP_TEXTURE_QUERY_LOD:
        case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
        case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
                return 0;
index 4c23090e2a0cbb57a52a7f6d482fd2c6d7d1eba0..f0650f4fe9ddfafb6b5d9a01e2d5a1d187a753b8 100644 (file)
@@ -1641,7 +1641,7 @@ static void tex_fetch_args(
                radeon_llvm_emit_prepare_cube_coords(bld_base, emit_data, coords);
 
        /* Pack depth comparison value */
-       if (tgsi_is_shadow_sampler(target)) {
+       if (tgsi_is_shadow_sampler(target) && opcode != TGSI_OPCODE_LODQ) {
                if (target == TGSI_TEXTURE_SHADOWCUBE_ARRAY) {
                        address[count++] = lp_build_emit_fetch(bld_base, inst, 1, 0);
                } else {
@@ -1816,7 +1816,8 @@ static void tex_fetch_args(
                emit_data->dst_type = LLVMVectorType(
                        LLVMInt32TypeInContext(gallivm->context),
                        4);
-       } else if (opcode == TGSI_OPCODE_TG4) {
+       } else if (opcode == TGSI_OPCODE_TG4 ||
+                  opcode == TGSI_OPCODE_LODQ) {
                unsigned is_array = target == TGSI_TEXTURE_1D_ARRAY ||
                                    target == TGSI_TEXTURE_SHADOW1D_ARRAY ||
                                    target == TGSI_TEXTURE_2D_ARRAY ||
@@ -1824,31 +1825,37 @@ static void tex_fetch_args(
                                    target == TGSI_TEXTURE_CUBE_ARRAY ||
                                    target == TGSI_TEXTURE_SHADOWCUBE_ARRAY;
                unsigned is_rect = target == TGSI_TEXTURE_RECT;
-               unsigned gather_comp = 0;
-
-               /* DMASK was repurposed for GATHER4. 4 components are always
-                * returned and DMASK works like a swizzle - it selects
-                * the component to fetch. The only valid DMASK values are
-                * 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
-                * (red,red,red,red) etc.) The ISA document doesn't mention
-                * this.
-                */
+               unsigned dmask = 0xf;
+
+               if (opcode == TGSI_OPCODE_TG4) {
+                       unsigned gather_comp = 0;
+
+                       /* DMASK was repurposed for GATHER4. 4 components are always
+                        * returned and DMASK works like a swizzle - it selects
+                        * the component to fetch. The only valid DMASK values are
+                        * 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
+                        * (red,red,red,red) etc.) The ISA document doesn't mention
+                        * this.
+                        */
+
+                       /* Get the component index from src1.x for Gather4. */
+                       if (!tgsi_is_shadow_sampler(target)) {
+                               LLVMValueRef (*imms)[4] = lp_soa_context(bld_base)->immediates;
+                               LLVMValueRef comp_imm;
+                               struct tgsi_src_register src1 = inst->Src[1].Register;
 
-               /* Get the component index from src1.x for Gather4. */
-               if (!tgsi_is_shadow_sampler(target)) {
-                       LLVMValueRef (*imms)[4] = lp_soa_context(bld_base)->immediates;
-                       LLVMValueRef comp_imm;
-                       struct tgsi_src_register src1 = inst->Src[1].Register;
+                               assert(src1.File == TGSI_FILE_IMMEDIATE);
 
-                       assert(src1.File == TGSI_FILE_IMMEDIATE);
+                               comp_imm = imms[src1.Index][src1.SwizzleX];
+                               gather_comp = LLVMConstIntGetZExtValue(comp_imm);
+                               gather_comp = CLAMP(gather_comp, 0, 3);
+                       }
 
-                       comp_imm = imms[src1.Index][src1.SwizzleX];
-                       gather_comp = LLVMConstIntGetZExtValue(comp_imm);
-                       gather_comp = CLAMP(gather_comp, 0, 3);
+                       dmask = 1 << gather_comp;
                }
 
                emit_data->args[2] = si_shader_ctx->samplers[sampler_index];
-               emit_data->args[3] = lp_build_const_int32(gallivm, 1 << gather_comp); /* dmask */
+               emit_data->args[3] = lp_build_const_int32(gallivm, dmask);
                emit_data->args[4] = lp_build_const_int32(gallivm, is_rect); /* unorm */
                emit_data->args[5] = lp_build_const_int32(gallivm, 0); /* r128 */
                emit_data->args[6] = lp_build_const_int32(gallivm, is_array); /* da */
@@ -1918,7 +1925,8 @@ static void build_new_tex_intrinsic(const struct lp_build_tgsi_action * action,
        struct lp_build_context * base = &bld_base->base;
        char intr_name[127];
        unsigned target = emit_data->inst->Texture.Texture;
-       bool is_shadow = tgsi_is_shadow_sampler(target);
+       bool is_shadow = tgsi_is_shadow_sampler(target) &&
+                        emit_data->inst->Instruction.Opcode != TGSI_OPCODE_LODQ;
 
        /* Add the type and suffixes .c, .o if needed. */
        sprintf(intr_name, "%s%s%s.v%ui32",
@@ -2227,12 +2235,18 @@ static const struct lp_build_tgsi_action txq_action = {
        .intr_name = "llvm.SI.resinfo"
 };
 
-static const struct lp_build_tgsi_action new_tex_action = {
+static const struct lp_build_tgsi_action tg4_action = {
        .fetch_args = tex_fetch_args,
        .emit = build_new_tex_intrinsic,
        .intr_name = "llvm.SI.gather4"
 };
 
+static const struct lp_build_tgsi_action lodq_action = {
+       .fetch_args = tex_fetch_args,
+       .emit = build_new_tex_intrinsic,
+       .intr_name = "llvm.SI.getlod"
+};
+
 static void create_meta_data(struct si_shader_context *si_shader_ctx)
 {
        struct gallivm_state *gallivm = si_shader_ctx->radeon_bld.soa.bld_base.base.gallivm;
@@ -2697,7 +2711,8 @@ int si_pipe_shader_create(
        bld_base->op_actions[TGSI_OPCODE_TXL2] = txl_action;
        bld_base->op_actions[TGSI_OPCODE_TXP] = tex_action;
        bld_base->op_actions[TGSI_OPCODE_TXQ] = txq_action;
-       bld_base->op_actions[TGSI_OPCODE_TG4] = new_tex_action;
+       bld_base->op_actions[TGSI_OPCODE_TG4] = tg4_action;
+       bld_base->op_actions[TGSI_OPCODE_LODQ] = lodq_action;
 
 #if HAVE_LLVM >= 0x0304
        bld_base->op_actions[TGSI_OPCODE_DDX].emit = si_llvm_emit_ddxy;