svga: fix unnormalized->normalized texture coordinate conversion
authorNeha Bhende <bhenden@vmware.com>
Thu, 20 Jul 2017 20:59:36 +0000 (13:59 -0700)
committerBrian Paul <brianp@vmware.com>
Sat, 22 Jul 2017 19:18:56 +0000 (13:18 -0600)
Sometimes, converting unnormalized coordinates to normalized
coordinates requires an epsilon value to produce the right texels with
nearest filtering.  Adding 0.0001 to the coordinates when the min/mag
filter is nearest fixes the issue.
Fixes piglit test fbo-blit-scaled-linear

Tested with mtt-piglit, mtt-glretrace

Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Charmaine Lee <charmainel@vmware.com>
src/gallium/drivers/svga/svga_shader.c
src/gallium/drivers/svga/svga_shader.h
src/gallium/drivers/svga/svga_tgsi_vgpu10.c

index 74c829eefc1737cbdbea9f83d49348d03e491df2..9e2b65771cd2dfefa790f7d273ba231061617a2f 100644 (file)
@@ -246,6 +246,11 @@ svga_init_shader_key_common(const struct svga_context *svga,
             key->tex[i].width_height_idx = idx++;
             key->tex[i].unnormalized = TRUE;
             ++key->num_unnormalized_coords;
+
+            if (sampler->magfilter == SVGA3D_TEX_FILTER_NEAREST ||
+                sampler->minfilter == SVGA3D_TEX_FILTER_NEAREST) {
+                key->tex[i].texel_bias = TRUE;
+            }
          }
       }
    }
index ec116c031d52d70b0ab9a344633cfcf896eb0a74..a594d120f84c265b20fb7ad592f4fb0adb9df4e2 100644 (file)
@@ -97,6 +97,7 @@ struct svga_compile_key
       unsigned compare_mode:1;
       unsigned compare_func:3;
       unsigned unnormalized:1;
+      unsigned texel_bias:1;
       unsigned width_height_idx:5; /**< texture unit */
       unsigned is_array:1;
       unsigned sprite_texgen:1;
index c7a1336d073dc12e1866679d51c867eb043c6644..93a76ef49f1dcc07b0715f31730446e2c7a1219d 100644 (file)
@@ -4854,9 +4854,24 @@ setup_texcoord(struct svga_shader_emitter_v10 *emit,
       struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
       struct tgsi_full_src_register scale_src = make_src_const_reg(scale_index);
 
-      /* MUL tmp, coord, const[] */
-      emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp_dst,
-                           coord, &scale_src, FALSE);
+      if (emit->key.tex[unit].texel_bias) {
+         /* to fix texture coordinate rounding issue, 0.0001 offset is
+          * been added. This fixes piglit test fbo-blit-scaled-linear. */
+         struct tgsi_full_src_register offset =
+            make_immediate_reg_float(emit, 0.0001f);
+
+         /* ADD tmp, coord, offset */
+         emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &tmp_dst,
+                              coord, &offset, FALSE);
+         /* MUL tmp, tmp, scale */
+         emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp_dst,
+                              &tmp_src, &scale_src, FALSE);
+      }
+      else {
+         /* MUL tmp, coord, const[] */
+         emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp_dst,
+                              coord, &scale_src, FALSE);
+      }
       return tmp_src;
    }
    else {
@@ -6287,6 +6302,17 @@ alloc_common_immediates(struct svga_shader_emitter_v10 *emit)
          alloc_immediate_int4(emit, 22, 30, 0, 0);
    }
 
+   unsigned i;
+
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+      if (emit->key.tex[i].texel_bias) {
+         /* Replace 0.0f if more immediate float value is needed */
+         emit->common_immediate_pos[n++] =
+            alloc_immediate_float4(emit, 0.0001f, 0.0f, 0.0f, 0.0f);
+         break;
+      }
+   }
+
    assert(n <= ARRAY_SIZE(emit->common_immediate_pos));
    emit->num_common_immediates = n;
 }