freedreno/a4xx: add ARB_texture_query_lod support
authorIlia Mirkin <imirkin@alum.mit.edu>
Sun, 22 Nov 2015 21:47:25 +0000 (16:47 -0500)
committerIlia Mirkin <imirkin@alum.mit.edu>
Mon, 23 Nov 2015 16:17:15 +0000 (11:17 -0500)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/freedreno/freedreno_screen.c
src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c

index da7dbc91eb007b983f0862f046ba24ff00d456a9..5bbe4016a2aa4997151269b2097e28e4caf6c24b 100644 (file)
@@ -198,6 +198,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_CUBE_MAP_ARRAY:
        case PIPE_CAP_START_INSTANCE:
        case PIPE_CAP_SAMPLER_VIEW_TARGET:
+       case PIPE_CAP_TEXTURE_QUERY_LOD:
                return is_a4xx(screen);
 
        case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
@@ -221,7 +222,6 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
        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:
        case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
index 25e84121d0cdb0dd1357105f4c84af6acd3b5680..fc163b4997527a51aae573a414721a9457038541 100644 (file)
@@ -1547,10 +1547,10 @@ tex_info(nir_tex_instr *tex, unsigned *flagsp, unsigned *coordsp)
                unreachable("bad sampler_dim");
        }
 
-       if (tex->is_shadow)
+       if (tex->is_shadow && tex->op != nir_texop_lod)
                flags |= IR3_INSTR_S;
 
-       if (tex->is_array)
+       if (tex->is_array && tex->op != nir_texop_lod)
                flags |= IR3_INSTR_A;
 
        *flagsp = flags;
@@ -1618,9 +1618,9 @@ emit_tex(struct ir3_compile *ctx, nir_tex_instr *tex)
        case nir_texop_txl:      opc = OPC_SAML;     break;
        case nir_texop_txd:      opc = OPC_SAMGQ;    break;
        case nir_texop_txf:      opc = OPC_ISAML;    break;
+       case nir_texop_lod:      opc = OPC_GETLOD;   break;
        case nir_texop_txf_ms:
        case nir_texop_txs:
-       case nir_texop_lod:
        case nir_texop_tg4:
        case nir_texop_query_levels:
        case nir_texop_texture_samples:
@@ -1666,10 +1666,10 @@ emit_tex(struct ir3_compile *ctx, nir_tex_instr *tex)
                src0[nsrc0++] = create_immed(b, fui(0.5));
        }
 
-       if (tex->is_shadow)
+       if (tex->is_shadow && tex->op != nir_texop_lod)
                src0[nsrc0++] = compare;
 
-       if (tex->is_array)
+       if (tex->is_array && tex->op != nir_texop_lod)
                src0[nsrc0++] = coord[coords];
 
        if (has_proj) {
@@ -1726,12 +1726,26 @@ emit_tex(struct ir3_compile *ctx, nir_tex_instr *tex)
                unreachable("bad dest_type");
        }
 
+       if (opc == OPC_GETLOD)
+               type = TYPE_U32;
+
        sam = ir3_SAM(b, opc, type, TGSI_WRITEMASK_XYZW,
                        flags, tex->sampler_index, tex->sampler_index,
                        create_collect(b, src0, nsrc0),
                        create_collect(b, src1, nsrc1));
 
        split_dest(b, dst, sam, 4);
+
+       /* GETLOD returns results in 4.8 fixed point */
+       if (opc == OPC_GETLOD) {
+               struct ir3_instruction *factor = create_immed(b, fui(1.0 / 256));
+
+               compile_assert(ctx, tex->dest_type == nir_type_float);
+               for (i = 0; i < 2; i++) {
+                       dst[i] = ir3_MUL_F(b, ir3_COV(b, dst[i], TYPE_U32, TYPE_F32), 0,
+                                                          factor, 0);
+               }
+       }
 }
 
 static void