65
state->format = texture->format;
67
* We don't copy sampler state over unless it is actually enabled, to avoid
68
* spurious recompiles, as the sampler static state is part of the shader
71
* Ideally the state tracker or cso_cache module would make all state
72
* canonical, but until that happens it's better to be safe than sorry here.
74
* XXX: Actually there's much more than can be done here, especially
75
* regarding 1D/2D/3D/CUBE textures, wrap modes, etc.
78
state->format = view->format;
79
state->swizzle_r = view->swizzle_r;
80
state->swizzle_g = view->swizzle_g;
81
state->swizzle_b = view->swizzle_b;
82
state->swizzle_a = view->swizzle_a;
66
84
state->target = texture->target;
67
state->pot_width = util_is_pot(texture->width0);
68
state->pot_height = util_is_pot(texture->height0);
69
state->pot_depth = util_is_pot(texture->depth0);
85
state->pot_width = util_is_power_of_two(texture->width0);
86
state->pot_height = util_is_power_of_two(texture->height0);
87
state->pot_depth = util_is_power_of_two(texture->depth0);
71
89
state->wrap_s = sampler->wrap_s;
72
90
state->wrap_t = sampler->wrap_t;
73
91
state->wrap_r = sampler->wrap_r;
74
92
state->min_img_filter = sampler->min_img_filter;
75
state->min_mip_filter = sampler->min_mip_filter;
76
93
state->mag_img_filter = sampler->mag_img_filter;
94
if (view->last_level) {
95
state->min_mip_filter = sampler->min_mip_filter;
97
state->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
77
100
state->compare_mode = sampler->compare_mode;
78
state->compare_func = sampler->compare_func;
101
if (sampler->compare_mode != PIPE_TEX_COMPARE_NONE) {
102
state->compare_func = sampler->compare_func;
79
105
state->normalized_coords = sampler->normalized_coords;
80
106
state->lod_bias = sampler->lod_bias;
81
state->min_lod = sampler->min_lod;
82
state->max_lod = sampler->max_lod;
107
if (!view->last_level &&
108
sampler->min_img_filter == sampler->mag_img_filter) {
109
state->min_lod = 0.0f;
110
state->max_lod = 0.0f;
112
state->min_lod = MAX2(sampler->min_lod, 0.0f);
113
state->max_lod = sampler->max_lod;
83
115
state->border_color[0] = sampler->border_color[0];
84
116
state->border_color[1] = sampler->border_color[1];
85
117
state->border_color[2] = sampler->border_color[2];
86
118
state->border_color[3] = sampler->border_color[3];
121
* FIXME: Handle the remainder of pipe_sampler_view.
91
* Gather elements from scatter positions in memory into a single vector.
127
* Compute the partial offset of a pixel block along an arbitrary axis.
93
* @param src_width src element width
94
* @param dst_width result element width (source will be expanded to fit)
95
* @param length length of the offsets,
96
* @param base_ptr base pointer, should be a i8 pointer type.
97
* @param offsets vector with offsets
129
* @param coord coordinate in pixels
130
* @param stride number of bytes between rows of successive pixel blocks
131
* @param block_length number of pixels in a pixels block along the coordinate
133
* @param out_offset resulting relative offset of the pixel block in bytes
134
* @param out_subcoord resulting sub-block pixel coordinate
100
lp_build_gather(LLVMBuilderRef builder,
104
LLVMValueRef base_ptr,
105
LLVMValueRef offsets)
137
lp_build_sample_partial_offset(struct lp_build_context *bld,
138
unsigned block_length,
141
LLVMValueRef *out_offset,
142
LLVMValueRef *out_subcoord)
107
LLVMTypeRef src_type = LLVMIntType(src_width);
108
LLVMTypeRef src_ptr_type = LLVMPointerType(src_type, 0);
109
LLVMTypeRef dst_elem_type = LLVMIntType(dst_width);
110
LLVMTypeRef dst_vec_type = LLVMVectorType(dst_elem_type, length);
114
res = LLVMGetUndef(dst_vec_type);
115
for(i = 0; i < length; ++i) {
116
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
117
LLVMValueRef elem_offset;
118
LLVMValueRef elem_ptr;
121
elem_offset = LLVMBuildExtractElement(builder, offsets, index, "");
122
elem_ptr = LLVMBuildGEP(builder, base_ptr, &elem_offset, 1, "");
123
elem_ptr = LLVMBuildBitCast(builder, elem_ptr, src_ptr_type, "");
124
elem = LLVMBuildLoad(builder, elem_ptr, "");
126
assert(src_width <= dst_width);
127
if(src_width > dst_width)
128
elem = LLVMBuildTrunc(builder, elem, dst_elem_type, "");
129
if(src_width < dst_width)
130
elem = LLVMBuildZExt(builder, elem, dst_elem_type, "");
132
res = LLVMBuildInsertElement(builder, res, elem, index, "");
145
LLVMValueRef subcoord;
147
if (block_length == 1) {
148
subcoord = bld->zero;
152
* Pixel blocks have power of two dimensions. LLVM should convert the
153
* rem/div to bit arithmetic.
157
LLVMValueRef block_width = lp_build_const_int_vec(bld->type, block_length);
158
subcoord = LLVMBuildURem(bld->builder, coord, block_width, "");
159
coord = LLVMBuildUDiv(bld->builder, coord, block_width, "");
162
offset = lp_build_mul(bld, coord, stride);
165
assert(out_subcoord);
167
*out_offset = offset;
168
*out_subcoord = subcoord;
140
* Compute the offset of a pixel.
142
* x, y, y_stride are vectors
173
* Compute the offset of a pixel block.
175
* x, y, z, y_stride, z_stride are vectors, and they refer to pixels.
177
* Returns the relative offset and i,j sub-block coordinates
145
180
lp_build_sample_offset(struct lp_build_context *bld,
146
181
const struct util_format_description *format_desc,
149
185
LLVMValueRef y_stride,
150
LLVMValueRef data_ptr)
186
LLVMValueRef z_stride,
187
LLVMValueRef *out_offset,
152
191
LLVMValueRef x_stride;
153
192
LLVMValueRef offset;
155
x_stride = lp_build_const_scalar(bld->type, format_desc->block.bits/8);
157
if(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
158
LLVMValueRef x_lo, x_hi;
159
LLVMValueRef y_lo, y_hi;
160
LLVMValueRef x_stride_lo, x_stride_hi;
161
LLVMValueRef y_stride_lo, y_stride_hi;
162
LLVMValueRef x_offset_lo, x_offset_hi;
163
LLVMValueRef y_offset_lo, y_offset_hi;
164
LLVMValueRef offset_lo, offset_hi;
166
x_lo = LLVMBuildAnd(bld->builder, x, bld->one, "");
167
y_lo = LLVMBuildAnd(bld->builder, y, bld->one, "");
169
x_hi = LLVMBuildLShr(bld->builder, x, bld->one, "");
170
y_hi = LLVMBuildLShr(bld->builder, y, bld->one, "");
172
x_stride_lo = x_stride;
173
y_stride_lo = lp_build_const_scalar(bld->type, 2*format_desc->block.bits/8);
175
x_stride_hi = lp_build_const_scalar(bld->type, 4*format_desc->block.bits/8);
176
y_stride_hi = LLVMBuildShl(bld->builder, y_stride, bld->one, "");
178
x_offset_lo = lp_build_mul(bld, x_lo, x_stride_lo);
179
y_offset_lo = lp_build_mul(bld, y_lo, y_stride_lo);
180
offset_lo = lp_build_add(bld, x_offset_lo, y_offset_lo);
182
x_offset_hi = lp_build_mul(bld, x_hi, x_stride_hi);
183
y_offset_hi = lp_build_mul(bld, y_hi, y_stride_hi);
184
offset_hi = lp_build_add(bld, x_offset_hi, y_offset_hi);
186
offset = lp_build_add(bld, offset_hi, offset_lo);
189
LLVMValueRef x_offset;
194
x_stride = lp_build_const_vec(bld->type, format_desc->block.bits/8);
196
lp_build_sample_partial_offset(bld,
197
format_desc->block.width,
190
202
LLVMValueRef y_offset;
192
x_offset = lp_build_mul(bld, x, x_stride);
193
y_offset = lp_build_mul(bld, y, y_stride);
195
offset = lp_build_add(bld, x_offset, y_offset);
203
lp_build_sample_partial_offset(bld,
204
format_desc->block.height,
207
offset = lp_build_add(bld, offset, y_offset);
214
LLVMValueRef z_offset;
216
lp_build_sample_partial_offset(bld,
217
1, /* pixel blocks are always 2D */
220
offset = lp_build_add(bld, offset, z_offset);
223
*out_offset = offset;