Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

i965/fs: Implement GL_CLAMP behavior on texture rectangles on gen6+.

We were doing saturate-based clamping on the [0,width] or [0,height]
coordinate, which meant only the first pixel was addressable.

Fixes piglit ARB_texture_rectangle/texwrap-RECT-bordercolor

NOTE: This is a candidate for the 8.0 release branch.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
  • Loading branch information...
commit 7c857a6b159debf76d4661f494fd2c97d205b5b1 1 parent 07e621c
Eric Anholt authored February 04, 2012
54  src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -1079,12 +1079,18 @@ fs_visitor::visit(ir_texture *ir)
1079 1079
    /* Should be lowered by do_lower_texture_projection */
1080 1080
    assert(!ir->projector);
1081 1081
 
  1082
+   bool needs_gl_clamp = true;
  1083
+
  1084
+   fs_reg scale_x, scale_y;
  1085
+
1082 1086
    /* The 965 requires the EU to do the normalization of GL rectangle
1083 1087
     * texture coordinates.  We use the program parameter state
1084 1088
     * tracking to get the scaling factor.
1085 1089
     */
1086  
-   if (intel->gen < 6 &&
1087  
-       ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT) {
  1090
+   if (ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT &&
  1091
+       (intel->gen < 6 ||
  1092
+	(intel->gen >= 6 && (c->key.tex.gl_clamp_mask[0] & (1 << sampler) ||
  1093
+			     c->key.tex.gl_clamp_mask[1] & (1 << sampler))))) {
1088 1094
       struct gl_program_parameter_list *params = c->fp->program.Base.Parameters;
1089 1095
       int tokens[STATE_LENGTH] = {
1090 1096
 	 STATE_INTERNAL,
@@ -1105,8 +1111,9 @@ fs_visitor::visit(ir_texture *ir)
1105 1111
       c->prog_data.param_convert[c->prog_data.nr_params + 1] =
1106 1112
 	 PARAM_NO_CONVERT;
1107 1113
 
1108  
-      fs_reg scale_x = fs_reg(UNIFORM, c->prog_data.nr_params);
1109  
-      fs_reg scale_y = fs_reg(UNIFORM, c->prog_data.nr_params + 1);
  1114
+      scale_x = fs_reg(UNIFORM, c->prog_data.nr_params);
  1115
+      scale_y = fs_reg(UNIFORM, c->prog_data.nr_params + 1);
  1116
+
1110 1117
       GLuint index = _mesa_add_state_reference(params,
1111 1118
 					       (gl_state_index *)tokens);
1112 1119
 
@@ -1116,7 +1123,14 @@ fs_visitor::visit(ir_texture *ir)
1116 1123
       this->param_index[c->prog_data.nr_params] = index;
1117 1124
       this->param_offset[c->prog_data.nr_params] = 1;
1118 1125
       c->prog_data.nr_params++;
  1126
+   }
1119 1127
 
  1128
+   /* The 965 requires the EU to do the normalization of GL rectangle
  1129
+    * texture coordinates.  We use the program parameter state
  1130
+    * tracking to get the scaling factor.
  1131
+    */
  1132
+   if (intel->gen < 6 &&
  1133
+       ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT) {
1120 1134
       fs_reg dst = fs_reg(this, ir->coordinate->type);
1121 1135
       fs_reg src = coordinate;
1122 1136
       coordinate = dst;
@@ -1125,9 +1139,39 @@ fs_visitor::visit(ir_texture *ir)
1125 1139
       dst.reg_offset++;
1126 1140
       src.reg_offset++;
1127 1141
       emit(BRW_OPCODE_MUL, dst, src, scale_y);
  1142
+   } else if (ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT) {
  1143
+      /* On gen6+, the sampler handles the rectangle coordinates
  1144
+       * natively, without needing rescaling.  But that means we have
  1145
+       * to do GL_CLAMP clamping at the [0, width], [0, height] scale,
  1146
+       * not [0, 1] like the default case below.
  1147
+       */
  1148
+      needs_gl_clamp = false;
  1149
+
  1150
+      for (int i = 0; i < 2; i++) {
  1151
+	 if (c->key.tex.gl_clamp_mask[i] & (1 << sampler)) {
  1152
+	    fs_reg chan = coordinate;
  1153
+	    chan.reg_offset += i;
  1154
+
  1155
+	    inst = emit(BRW_OPCODE_SEL, chan, chan, brw_imm_f(0.0));
  1156
+	    inst->conditional_mod = BRW_CONDITIONAL_G;
  1157
+
  1158
+	    /* Our parameter comes in as 1.0/width or 1.0/height,
  1159
+	     * because that's what people normally want for doing
  1160
+	     * texture rectangle handling.  We need width or height
  1161
+	     * for clamping, but we don't care enough to make a new
  1162
+	     * parameter type, so just invert back.
  1163
+	     */
  1164
+	    fs_reg limit = fs_reg(this, glsl_type::float_type);
  1165
+	    emit(BRW_OPCODE_MOV, limit, i == 0 ? scale_x : scale_y);
  1166
+	    emit(SHADER_OPCODE_RCP, limit, limit);
  1167
+
  1168
+	    inst = emit(BRW_OPCODE_SEL, chan, chan, limit);
  1169
+	    inst->conditional_mod = BRW_CONDITIONAL_L;
  1170
+	 }
  1171
+      }
1128 1172
    }
1129 1173
 
1130  
-   if (ir->coordinate) {
  1174
+   if (ir->coordinate && needs_gl_clamp) {
1131 1175
       for (int i = 0; i < MIN2(ir->coordinate->type->vector_elements, 3); i++) {
1132 1176
 	 if (c->key.tex.gl_clamp_mask[i] & (1 << sampler)) {
1133 1177
 	    fs_reg chan = coordinate;

0 notes on commit 7c857a6

Please sign in to comment.
Something went wrong with that request. Please try again.