v3d: support for textureQueryLOD
authorAlejandro Piñeiro <apinheiro@igalia.com>
Thu, 16 Apr 2020 23:57:18 +0000 (01:57 +0200)
committerAlejandro Piñeiro <apinheiro@igalia.com>
Wed, 22 Apr 2020 21:43:23 +0000 (23:43 +0200)
Fixes all the ARB_texture_query_lod piglit tests, and needed to get
the Vulkan CTS textureQueryLOD passing with the ongoing Vulkan driver.

Note that LOD Query bit flag became only available on V42 of the hw,
but the v3d40_tex is using V41 as reference. In order to avoid setting
up the infrastructure to support both v41 and v42, we manually set the
bit if the device version is the correct one.

We also fix how the ARB_texture_query_lod (so EXT_texture_query_lod)
is exposed. Before this commit it was always exposed (wrongly as it
was not really supported). Now it is exposed for devinfo.ver >= 42.

v2: move _need_sampler helper to nir.h (Eric Anholt)

Reviewed-by: Eric Anholt <eric@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4677>

src/broadcom/compiler/v3d40_tex.c
src/gallium/drivers/v3d/v3d_screen.c

index c3f7d94344aca2b932d3fbf68357bcbaf2a321cf..0a02163100a7832d6a929fe49a6bb673b408db5d 100644 (file)
@@ -58,29 +58,6 @@ static const struct V3D41_TMU_CONFIG_PARAMETER_2 p2_unpacked_default = {
         .op = V3D_TMU_OP_REGULAR,
 };
 
         .op = V3D_TMU_OP_REGULAR,
 };
 
-/*
- * This method returns if the texture operation requires a sampler as
- * a general rule, see the documentation of
- * nir_tex_instr::sampler_index. Note that the specific hw would
- * require a sampler in any case, for some other reason.
- */
-static bool
-texture_instr_need_sampler(nir_tex_instr *instr)
-{
-        switch(instr->op) {
-        case nir_texop_txf:
-        case nir_texop_txf_ms:
-        case nir_texop_txs:
-        case nir_texop_lod:
-        case nir_texop_query_levels:
-        case nir_texop_texture_samples:
-        case nir_texop_samples_identical:
-                return false;
-        default:
-                return true;
-        }
-}
-
 void
 v3d40_vir_emit_tex(struct v3d_compile *c, nir_tex_instr *instr)
 {
 void
 v3d40_vir_emit_tex(struct v3d_compile *c, nir_tex_instr *instr)
 {
@@ -90,6 +67,8 @@ v3d40_vir_emit_tex(struct v3d_compile *c, nir_tex_instr *instr)
         struct V3D41_TMU_CONFIG_PARAMETER_0 p0_unpacked = {
         };
 
         struct V3D41_TMU_CONFIG_PARAMETER_0 p0_unpacked = {
         };
 
+        assert(instr->op != nir_texop_lod || c->devinfo->ver >= 42);
+
         struct V3D41_TMU_CONFIG_PARAMETER_2 p2_unpacked = {
                 .op = V3D_TMU_OP_REGULAR,
 
         struct V3D41_TMU_CONFIG_PARAMETER_2 p2_unpacked = {
                 .op = V3D_TMU_OP_REGULAR,
 
@@ -101,7 +80,11 @@ v3d40_vir_emit_tex(struct v3d_compile *c, nir_tex_instr *instr)
                 .disable_autolod = instr->op == nir_texop_tg4
         };
 
                 .disable_autolod = instr->op == nir_texop_tg4
         };
 
-        int non_array_components = instr->coord_components - instr->is_array;
+        int non_array_components =
+           instr->op != nir_texop_lod ?
+           instr->coord_components - instr->is_array :
+           instr->coord_components;
+
         struct qreg s;
 
         for (unsigned i = 0; i < instr->num_srcs; i++) {
         struct qreg s;
 
         for (unsigned i = 0; i < instr->num_srcs; i++) {
@@ -201,6 +184,13 @@ v3d40_vir_emit_tex(struct v3d_compile *c, nir_tex_instr *instr)
                                           (uint8_t *)&p2_packed,
                                           &p2_unpacked);
 
                                           (uint8_t *)&p2_packed,
                                           &p2_unpacked);
 
+        /* We manually set the LOD Query bit (see
+         * V3D42_TMU_CONFIG_PARAMETER_2) as right now is the only V42 specific
+         * feature over V41 we are using
+         */
+        if (instr->op == nir_texop_lod)
+           p2_packed |= 1UL << 24;
+
         /* Load unit number into the high bits of the texture address field,
          * which will be be used by the driver to decide which texture to put
          * in the actual address field.
         /* Load unit number into the high bits of the texture address field,
          * which will be be used by the driver to decide which texture to put
          * in the actual address field.
@@ -220,10 +210,11 @@ v3d40_vir_emit_tex(struct v3d_compile *c, nir_tex_instr *instr)
          * p1 is optional, but we can skip it only if p2 can be skipped too
          */
         bool needs_p2_config =
          * p1 is optional, but we can skip it only if p2 can be skipped too
          */
         bool needs_p2_config =
-                memcmp(&p2_unpacked, &p2_unpacked_default, sizeof(p2_unpacked)) != 0;
+                (instr->op == nir_texop_lod ||
+                 memcmp(&p2_unpacked, &p2_unpacked_default, sizeof(p2_unpacked)) != 0);
 
         if (needs_p2_config || output_type_32_bit ||
 
         if (needs_p2_config || output_type_32_bit ||
-            texture_instr_need_sampler(instr)) {
+            nir_tex_instr_need_sampler(instr)) {
                 struct V3D41_TMU_CONFIG_PARAMETER_1 p1_unpacked = {
                         .output_type_32_bit = output_type_32_bit,
 
                 struct V3D41_TMU_CONFIG_PARAMETER_1 p1_unpacked = {
                         .output_type_32_bit = output_type_32_bit,
 
index 8e2509a71c4ebcd4ff643c592cafc63970d282c2..fe0a309c583935ca292e0e05f3389d2ad93c307d 100644 (file)
@@ -123,7 +123,6 @@ v3d_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
         case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
         case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
         case PIPE_CAP_VERTEX_SHADER_SATURATE:
         case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
         case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
         case PIPE_CAP_VERTEX_SHADER_SATURATE:
-        case PIPE_CAP_TEXTURE_QUERY_LOD:
         case PIPE_CAP_PRIMITIVE_RESTART:
         case PIPE_CAP_OCCLUSION_QUERY:
         case PIPE_CAP_POINT_SPRITE:
         case PIPE_CAP_PRIMITIVE_RESTART:
         case PIPE_CAP_OCCLUSION_QUERY:
         case PIPE_CAP_POINT_SPRITE:
@@ -139,6 +138,10 @@ v3d_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
         case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
                 return 1;
 
         case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
                 return 1;
 
+        case PIPE_CAP_TEXTURE_QUERY_LOD:
+                return screen->devinfo.ver >= 42;
+                break;
+
         case PIPE_CAP_PACKED_UNIFORMS:
                 /* We can't enable this flag, because it results in load_ubo
                  * intrinsics across a 16b boundary, but v3d's TMU general
         case PIPE_CAP_PACKED_UNIFORMS:
                 /* We can't enable this flag, because it results in load_ubo
                  * intrinsics across a 16b boundary, but v3d's TMU general