15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**************************************************************************
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2009 VMware, Inc.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All Rights Reserved.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copy of this software and associated documentation files (the
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "Software"), to deal in the Software without restriction, including
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * without limitation the rights to use, copy, modify, merge, publish,
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distribute, sub license, and/or sell copies of the Software, and to
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * permit persons to whom the Software is furnished to do so, subject to
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the following conditions:
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The above copyright notice and this permission notice (including the
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * next paragraph) shall be included in all copies or substantial portions
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of the Software.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) **************************************************************************/
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @file
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Texture sampling -- SoA.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @author Jose Fonseca <jfonseca@vmware.com>
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @author Brian Paul <brianp@vmware.com>
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pipe/p_defines.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pipe/p_state.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pipe/p_shader_tokens.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/u_debug.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/u_dump.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/u_memory.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/u_math.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/u_format.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/u_cpu_detect.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_debug.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_type.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_const.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_conv.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_arit.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_bitarit.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_logic.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_printf.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_swizzle.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_flow.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_gather.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_format.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_sample.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_sample_aos.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_struct.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_quad.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lp_bld_pack.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Generate code to fetch a texel from a texture at int coords (x, y, z).
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The computation depends on whether the texture is 1D, 2D or 3D.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The result, texel, will be float vectors:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   texel[0] = red values
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   texel[1] = green values
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   texel[2] = blue values
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   texel[3] = alpha values
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          unsigned unit,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          LLVMValueRef width,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          LLVMValueRef height,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          LLVMValueRef depth,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          LLVMValueRef x,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          LLVMValueRef y,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          LLVMValueRef z,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          LLVMValueRef y_stride,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          LLVMValueRef z_stride,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          LLVMValueRef data_ptr,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          LLVMValueRef texel_out[4])
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   const struct lp_sampler_static_state *static_state = bld->static_state;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   const unsigned dims = bld->dims;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMBuilderRef builder = bld->gallivm->builder;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef offset;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef i, j;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef use_border = NULL;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* use_border = x < 0 || x >= width || y < 0 || y >= height */
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (lp_sampler_wrap_mode_uses_border_color(static_state->wrap_s,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              static_state->min_img_filter,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              static_state->mag_img_filter)) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LLVMValueRef b1, b2;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      b1 = lp_build_cmp(int_coord_bld, PIPE_FUNC_LESS, x, int_coord_bld->zero);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      b2 = lp_build_cmp(int_coord_bld, PIPE_FUNC_GEQUAL, x, width);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      use_border = LLVMBuildOr(builder, b1, b2, "b1_or_b2");
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (dims >= 2 &&
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       lp_sampler_wrap_mode_uses_border_color(static_state->wrap_t,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              static_state->min_img_filter,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              static_state->mag_img_filter)) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LLVMValueRef b1, b2;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      b1 = lp_build_cmp(int_coord_bld, PIPE_FUNC_LESS, y, int_coord_bld->zero);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      b2 = lp_build_cmp(int_coord_bld, PIPE_FUNC_GEQUAL, y, height);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (use_border) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         use_border = LLVMBuildOr(builder, use_border, b1, "ub_or_b1");
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         use_border = LLVMBuildOr(builder, use_border, b2, "ub_or_b2");
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         use_border = LLVMBuildOr(builder, b1, b2, "b1_or_b2");
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (dims == 3 &&
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       lp_sampler_wrap_mode_uses_border_color(static_state->wrap_r,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              static_state->min_img_filter,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              static_state->mag_img_filter)) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LLVMValueRef b1, b2;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      b1 = lp_build_cmp(int_coord_bld, PIPE_FUNC_LESS, z, int_coord_bld->zero);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      b2 = lp_build_cmp(int_coord_bld, PIPE_FUNC_GEQUAL, z, depth);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (use_border) {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         use_border = LLVMBuildOr(builder, use_border, b1, "ub_or_b1");
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         use_border = LLVMBuildOr(builder, use_border, b2, "ub_or_b2");
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         use_border = LLVMBuildOr(builder, b1, b2, "b1_or_b2");
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* convert x,y,z coords to linear offset from start of texture, in bytes */
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_sample_offset(&bld->int_coord_bld,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          bld->format_desc,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          x, y, z, y_stride, z_stride,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          &offset, &i, &j);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (use_border) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* If we can sample the border color, it means that texcoords may
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       * lie outside the bounds of the texture image.  We need to do
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       * something to prevent reading out of bounds and causing a segfault.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       *
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       * Simply AND the texture coords with !use_border.  This will cause
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       * coords which are out of bounds to become zero.  Zero's guaranteed
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       * to be inside the texture image.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       */
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      offset = lp_build_andnot(&bld->int_coord_bld, offset, use_border);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_fetch_rgba_soa(bld->gallivm,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           bld->format_desc,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           bld->texel_type,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           data_ptr, offset,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           i, j,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           texel_out);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /*
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * Note: if we find an app which frequently samples the texture border
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * we might want to implement a true conditional here to avoid sampling
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * the texture whenever possible (since that's quite a bit of code).
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * Ex:
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *   if (use_border) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *      texel = border_color;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *   }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *   else {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *      texel = sample_texture(coord);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *   }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * As it is now, we always sample the texture, then selectively replace
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * the texel color results with the border color.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (use_border) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* select texel color or border color depending on use_border */
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LLVMValueRef border_color_ptr =
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         bld->dynamic_state->border_color(bld->dynamic_state,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          bld->gallivm, unit);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int chan;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (chan = 0; chan < 4; chan++) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         LLVMValueRef border_chan =
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_array_get(bld->gallivm, border_color_ptr,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               lp_build_const_int32(bld->gallivm, chan));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         LLVMValueRef border_chan_vec =
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_broadcast_scalar(&bld->float_vec_bld, border_chan);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         texel_out[chan] = lp_build_select(&bld->texel_bld, use_border,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           border_chan_vec, texel_out[chan]);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Helper to compute the mirror function for the PIPE_WRAP_MIRROR modes.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static LLVMValueRef
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_coord_mirror(struct lp_build_sample_context *bld,
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      LLVMValueRef coord)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct lp_build_context *coord_bld = &bld->coord_bld;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef fract, flr, isOdd;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_ifloor_fract(coord_bld, coord, &flr, &fract);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* isOdd = flr & 1 */
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   isOdd = LLVMBuildAnd(bld->gallivm->builder, flr, int_coord_bld->one, "");
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* make coord positive or negative depending on isOdd */
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   coord = lp_build_set_sign(coord_bld, fract, isOdd);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* convert isOdd to float */
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   isOdd = lp_build_int_to_float(coord_bld, isOdd);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* add isOdd to coord */
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   coord = lp_build_add(coord_bld, coord, isOdd);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   return coord;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Helper to compute the first coord and the weight for
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * linear wrap repeat npot textures
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_coord_repeat_npot_linear(struct lp_build_sample_context *bld,
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  LLVMValueRef coord_f,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  LLVMValueRef length_i,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  LLVMValueRef length_f,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  LLVMValueRef *coord0_i,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  LLVMValueRef *weight_f)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct lp_build_context *coord_bld = &bld->coord_bld;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef half = lp_build_const_vec(bld->gallivm, coord_bld->type, 0.5);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef length_minus_one = lp_build_sub(int_coord_bld, length_i,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                int_coord_bld->one);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef mask;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* wrap with normalized floats is just fract */
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   coord_f = lp_build_fract(coord_bld, coord_f);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* mul by size and subtract 0.5 */
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   coord_f = lp_build_mul(coord_bld, coord_f, length_f);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   coord_f = lp_build_sub(coord_bld, coord_f, half);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /*
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * we avoided the 0.5/length division before the repeat wrap,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * now need to fix up edge cases with selects
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* convert to int, compute lerp weight */
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_ifloor_fract(coord_bld, coord_f, coord0_i, weight_f);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   mask = lp_build_compare(int_coord_bld->gallivm, int_coord_bld->type,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           PIPE_FUNC_LESS, *coord0_i, int_coord_bld->zero);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *coord0_i = lp_build_select(int_coord_bld, mask, length_minus_one, *coord0_i);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Build LLVM code for texture wrap mode for linear filtering.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param x0_out  returns first integer texcoord
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param x1_out  returns second integer texcoord
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param weight_out  returns linear interpolation weight
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            LLVMValueRef coord,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            LLVMValueRef length,
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            LLVMValueRef length_f,
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            boolean is_pot,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            unsigned wrap_mode,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            LLVMValueRef *x0_out,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            LLVMValueRef *x1_out,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            LLVMValueRef *weight_out)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct lp_build_context *coord_bld = &bld->coord_bld;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMBuilderRef builder = bld->gallivm->builder;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef half = lp_build_const_vec(bld->gallivm, coord_bld->type, 0.5);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef length_minus_one = lp_build_sub(int_coord_bld, length, int_coord_bld->one);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef coord0, coord1, weight;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   switch(wrap_mode) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_REPEAT:
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_pot) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* mul by size and subtract 0.5 */
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_mul(coord_bld, coord, length_f);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_sub(coord_bld, coord, half);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* convert to int, compute lerp weight */
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_ifloor_fract(coord_bld, coord, &coord0, &weight);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* repeat wrap */
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord0 = LLVMBuildAnd(builder, coord0, length_minus_one, "");
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord1 = LLVMBuildAnd(builder, coord1, length_minus_one, "");
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         LLVMValueRef mask;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_coord_repeat_npot_linear(bld, coord,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           length, length_f,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &coord0, &weight);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         mask = lp_build_compare(int_coord_bld->gallivm, int_coord_bld->type,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 PIPE_FUNC_NOTEQUAL, coord0, length_minus_one);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord1 = LLVMBuildAnd(builder,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               lp_build_add(int_coord_bld, coord0, int_coord_bld->one),
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               mask, "");
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_CLAMP:
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (bld->static_state->normalized_coords) {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* scale coord to length */
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_mul(coord_bld, coord, length_f);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* clamp to [0, length] */
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord = lp_build_clamp(coord_bld, coord, coord_bld->zero, length_f);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord = lp_build_sub(coord_bld, coord, half);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* convert to int, compute lerp weight */
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_ifloor_fract(coord_bld, coord, &coord0, &weight);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         struct lp_build_context abs_coord_bld = bld->coord_bld;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         abs_coord_bld.type.sign = FALSE;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         if (bld->static_state->normalized_coords) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* mul by tex size */
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            coord = lp_build_mul(coord_bld, coord, length_f);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* clamp to length max */
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_min(coord_bld, coord, length_f);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* subtract 0.5 */
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_sub(coord_bld, coord, half);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* clamp to [0, length - 0.5] */
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_max(coord_bld, coord, coord_bld->zero);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* convert to int, compute lerp weight */
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_ifloor_fract(&abs_coord_bld, coord, &coord0, &weight);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* coord1 = min(coord1, length-1) */
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord1 = lp_build_min(int_coord_bld, coord1, length_minus_one);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         break;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         LLVMValueRef min;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         if (bld->static_state->normalized_coords) {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* scale coord to length */
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            coord = lp_build_mul(coord_bld, coord, length_f);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* was: clamp to [-0.5, length + 0.5], then sub 0.5 */
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_sub(coord_bld, coord, half);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         min = lp_build_const_vec(bld->gallivm, coord_bld->type, -1.0F);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_clamp(coord_bld, coord, min, length_f);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* convert to int, compute lerp weight */
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_ifloor_fract(coord_bld, coord, &coord0, &weight);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_MIRROR_REPEAT:
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* compute mirror function */
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord = lp_build_coord_mirror(bld, coord);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* scale coord to length */
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord = lp_build_mul(coord_bld, coord, length_f);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord = lp_build_sub(coord_bld, coord, half);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* convert to int, compute lerp weight */
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_ifloor_fract(coord_bld, coord, &coord0, &weight);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* coord0 = max(coord0, 0) */
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord0 = lp_build_max(int_coord_bld, coord0, int_coord_bld->zero);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* coord1 = min(coord1, length-1) */
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord1 = lp_build_min(int_coord_bld, coord1, length_minus_one);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_MIRROR_CLAMP:
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord = lp_build_abs(coord_bld, coord);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (bld->static_state->normalized_coords) {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* scale coord to length */
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_mul(coord_bld, coord, length_f);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* clamp to [0, length] */
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord = lp_build_min(coord_bld, coord, length_f);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord = lp_build_sub(coord_bld, coord, half);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* convert to int, compute lerp weight */
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_ifloor_fract(coord_bld, coord, &coord0, &weight);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      {
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         LLVMValueRef min, max;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         struct lp_build_context abs_coord_bld = bld->coord_bld;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         abs_coord_bld.type.sign = FALSE;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_abs(coord_bld, coord);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         if (bld->static_state->normalized_coords) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* scale coord to length */
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            coord = lp_build_mul(coord_bld, coord, length_f);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* clamp to [0.5, length - 0.5] */
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         min = half;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         max = lp_build_sub(coord_bld, length_f, min);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_clamp(coord_bld, coord, min, max);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_sub(coord_bld, coord, half);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* convert to int, compute lerp weight */
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_ifloor_fract(&abs_coord_bld, coord, &coord0, &weight);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      {
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_abs(coord_bld, coord);
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         if (bld->static_state->normalized_coords) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* scale coord to length */
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            coord = lp_build_mul(coord_bld, coord, length_f);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* was: clamp to [-0.5, length + 0.5] then sub 0.5 */
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* skip -0.5 clamp (always positive), do sub first */
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_sub(coord_bld, coord, half);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_min(coord_bld, coord, length_f);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* convert to int, compute lerp weight */
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_ifloor_fract(coord_bld, coord, &coord0, &weight);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   default:
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert(0);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord0 = NULL;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord1 = NULL;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      weight = NULL;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *x0_out = coord0;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *x1_out = coord1;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *weight_out = weight;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Build LLVM code for texture wrap mode for nearest filtering.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param coord  the incoming texcoord (nominally in [0,1])
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param length  the texture size along one dimension, as int vector
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param is_pot  if TRUE, length is a power of two
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param wrap_mode  one of PIPE_TEX_WRAP_x
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static LLVMValueRef
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             LLVMValueRef coord,
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             LLVMValueRef length,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             LLVMValueRef length_f,
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             boolean is_pot,
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             unsigned wrap_mode)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct lp_build_context *coord_bld = &bld->coord_bld;
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMBuilderRef builder = bld->gallivm->builder;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef length_minus_one = lp_build_sub(int_coord_bld, length, int_coord_bld->one);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef icoord;
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   switch(wrap_mode) {
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_REPEAT:
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_pot) {
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_mul(coord_bld, coord, length_f);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         icoord = lp_build_ifloor(coord_bld, coord);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         icoord = LLVMBuildAnd(builder, icoord, length_minus_one, "");
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          /* take fraction, unnormalize */
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          coord = lp_build_fract_safe(coord_bld, coord);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          coord = lp_build_mul(coord_bld, coord, length_f);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          icoord = lp_build_itrunc(coord_bld, coord);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_CLAMP:
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (bld->static_state->normalized_coords) {
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* scale coord to length */
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_mul(coord_bld, coord, length_f);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* floor */
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* use itrunc instead since we clamp to 0 anyway */
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icoord = lp_build_itrunc(coord_bld, coord);
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* clamp to [0, length - 1]. */
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icoord = lp_build_clamp(int_coord_bld, icoord, int_coord_bld->zero,
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              length_minus_one);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* Note: this is the same as CLAMP_TO_EDGE, except min = -1 */
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      {
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         LLVMValueRef min, max;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         if (bld->static_state->normalized_coords) {
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* scale coord to length */
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            coord = lp_build_mul(coord_bld, coord, length_f);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         icoord = lp_build_ifloor(coord_bld, coord);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* clamp to [-1, length] */
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         min = lp_build_negate(int_coord_bld, int_coord_bld->one);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         max = length;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         icoord = lp_build_clamp(int_coord_bld, icoord, min, max);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_MIRROR_REPEAT:
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* compute mirror function */
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord = lp_build_coord_mirror(bld, coord);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* scale coord to length */
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert(bld->static_state->normalized_coords);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord = lp_build_mul(coord_bld, coord, length_f);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* itrunc == ifloor here */
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icoord = lp_build_itrunc(coord_bld, coord);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* clamp to [0, length - 1] */
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icoord = lp_build_min(int_coord_bld, icoord, length_minus_one);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_MIRROR_CLAMP:
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord = lp_build_abs(coord_bld, coord);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (bld->static_state->normalized_coords) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* scale coord to length */
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_mul(coord_bld, coord, length_f);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* itrunc == ifloor here */
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icoord = lp_build_itrunc(coord_bld, coord);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* clamp to [0, length - 1] */
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icoord = lp_build_min(int_coord_bld, icoord, length_minus_one);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      coord = lp_build_abs(coord_bld, coord);
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (bld->static_state->normalized_coords) {
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* scale coord to length */
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         coord = lp_build_mul(coord_bld, coord, length_f);
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* itrunc == ifloor here */
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icoord = lp_build_itrunc(coord_bld, coord);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* clamp to [0, length] */
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icoord = lp_build_min(int_coord_bld, icoord, length);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   default:
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert(0);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icoord = NULL;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   return icoord;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Generate code to sample a mipmap level with nearest filtering.
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If sampling a cube texture, r = cube face in [0,5].
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              unsigned unit,
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              LLVMValueRef size,
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              LLVMValueRef row_stride_vec,
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              LLVMValueRef img_stride_vec,
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              LLVMValueRef data_ptr,
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              LLVMValueRef s,
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              LLVMValueRef t,
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              LLVMValueRef r,
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              LLVMValueRef colors_out[4])
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   const unsigned dims = bld->dims;
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef width_vec;
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef height_vec;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef depth_vec;
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef flt_size;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef flt_width_vec;
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef flt_height_vec;
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef flt_depth_vec;
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef x, y, z;
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_extract_image_sizes(bld,
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                bld->int_size_type,
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                bld->int_coord_type,
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                size,
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                &width_vec, &height_vec, &depth_vec);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   flt_size = lp_build_int_to_float(&bld->float_size_bld, size);
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_extract_image_sizes(bld,
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                bld->float_size_type,
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                bld->coord_type,
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                flt_size,
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                &flt_width_vec, &flt_height_vec, &flt_depth_vec);
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /*
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * Compute integer texcoords.
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   x = lp_build_sample_wrap_nearest(bld, s, width_vec, flt_width_vec,
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bld->static_state->pot_width,
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bld->static_state->wrap_s);
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_name(x, "tex.x.wrapped");
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (dims >= 2) {
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y = lp_build_sample_wrap_nearest(bld, t, height_vec, flt_height_vec,
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       bld->static_state->pot_height,
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       bld->static_state->wrap_t);
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_name(y, "tex.y.wrapped");
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (dims == 3) {
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         z = lp_build_sample_wrap_nearest(bld, r, depth_vec, flt_depth_vec,
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          bld->static_state->pot_depth,
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          bld->static_state->wrap_r);
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_name(z, "tex.z.wrapped");
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         z = r;
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else {
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         z = NULL;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   else {
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y = z = NULL;
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /*
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * Get texture colors.
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_sample_texel_soa(bld, unit,
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             width_vec, height_vec, depth_vec,
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             x, y, z,
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             row_stride_vec, img_stride_vec,
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             data_ptr, colors_out);
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Generate code to sample a mipmap level with linear filtering.
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If sampling a cube texture, r = cube face in [0,5].
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_sample_image_linear(struct lp_build_sample_context *bld,
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             unsigned unit,
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             LLVMValueRef size,
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             LLVMValueRef row_stride_vec,
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             LLVMValueRef img_stride_vec,
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             LLVMValueRef data_ptr,
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             LLVMValueRef s,
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             LLVMValueRef t,
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             LLVMValueRef r,
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             LLVMValueRef colors_out[4])
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   const unsigned dims = bld->dims;
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef width_vec;
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef height_vec;
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef depth_vec;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef flt_size;
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef flt_width_vec;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef flt_height_vec;
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef flt_depth_vec;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef x0, y0, z0, x1, y1, z1;
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef s_fpart, t_fpart, r_fpart;
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef neighbors[2][2][4];
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   int chan;
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_extract_image_sizes(bld,
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                bld->int_size_type,
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                bld->int_coord_type,
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                size,
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                &width_vec, &height_vec, &depth_vec);
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   flt_size = lp_build_int_to_float(&bld->float_size_bld, size);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_extract_image_sizes(bld,
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                bld->float_size_type,
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                bld->coord_type,
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                flt_size,
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                &flt_width_vec, &flt_height_vec, &flt_depth_vec);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /*
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * Compute integer texcoords.
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_sample_wrap_linear(bld, s, width_vec, flt_width_vec,
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               bld->static_state->pot_width,
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               bld->static_state->wrap_s,
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &x0, &x1, &s_fpart);
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_name(x0, "tex.x0.wrapped");
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_name(x1, "tex.x1.wrapped");
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (dims >= 2) {
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_sample_wrap_linear(bld, t, height_vec, flt_height_vec,
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  bld->static_state->pot_height,
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  bld->static_state->wrap_t,
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  &y0, &y1, &t_fpart);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_name(y0, "tex.y0.wrapped");
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_name(y1, "tex.y1.wrapped");
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (dims == 3) {
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_sample_wrap_linear(bld, r, depth_vec, flt_depth_vec,
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     bld->static_state->pot_depth,
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     bld->static_state->wrap_r,
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     &z0, &z1, &r_fpart);
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_name(z0, "tex.z0.wrapped");
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_name(z1, "tex.z1.wrapped");
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         z0 = z1 = r;  /* cube face */
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         r_fpart = NULL;
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else {
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         z0 = z1 = NULL;
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         r_fpart = NULL;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   else {
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y0 = y1 = t_fpart = NULL;
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      z0 = z1 = r_fpart = NULL;
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /*
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * Get texture colors.
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* get x0/x1 texels */
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_sample_texel_soa(bld, unit,
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             width_vec, height_vec, depth_vec,
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             x0, y0, z0,
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             row_stride_vec, img_stride_vec,
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             data_ptr, neighbors[0][0]);
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_sample_texel_soa(bld, unit,
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             width_vec, height_vec, depth_vec,
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             x1, y0, z0,
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             row_stride_vec, img_stride_vec,
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             data_ptr, neighbors[0][1]);
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (dims == 1) {
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* Interpolate two samples from 1D image to produce one color */
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (chan = 0; chan < 4; chan++) {
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         colors_out[chan] = lp_build_lerp(&bld->texel_bld, s_fpart,
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          neighbors[0][0][chan],
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          neighbors[0][1][chan]);
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   else {
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* 2D/3D texture */
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LLVMValueRef colors0[4];
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* get x0/x1 texels at y1 */
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_sample_texel_soa(bld, unit,
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                width_vec, height_vec, depth_vec,
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                x0, y1, z0,
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                row_stride_vec, img_stride_vec,
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_ptr, neighbors[1][0]);
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_sample_texel_soa(bld, unit,
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                width_vec, height_vec, depth_vec,
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                x1, y1, z0,
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                row_stride_vec, img_stride_vec,
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_ptr, neighbors[1][1]);
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* Bilinear interpolate the four samples from the 2D image / 3D slice */
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (chan = 0; chan < 4; chan++) {
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         colors0[chan] = lp_build_lerp_2d(&bld->texel_bld,
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          s_fpart, t_fpart,
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          neighbors[0][0][chan],
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          neighbors[0][1][chan],
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          neighbors[1][0][chan],
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          neighbors[1][1][chan]);
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (dims == 3) {
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         LLVMValueRef neighbors1[2][2][4];
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         LLVMValueRef colors1[4];
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* get x0/x1/y0/y1 texels at z1 */
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_sample_texel_soa(bld, unit,
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   width_vec, height_vec, depth_vec,
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   x0, y0, z1,
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   row_stride_vec, img_stride_vec,
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_ptr, neighbors1[0][0]);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_sample_texel_soa(bld, unit,
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   width_vec, height_vec, depth_vec,
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   x1, y0, z1,
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   row_stride_vec, img_stride_vec,
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_ptr, neighbors1[0][1]);
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_sample_texel_soa(bld, unit,
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   width_vec, height_vec, depth_vec,
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   x0, y1, z1,
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   row_stride_vec, img_stride_vec,
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_ptr, neighbors1[1][0]);
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_sample_texel_soa(bld, unit,
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   width_vec, height_vec, depth_vec,
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   x1, y1, z1,
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   row_stride_vec, img_stride_vec,
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_ptr, neighbors1[1][1]);
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* Bilinear interpolate the four samples from the second Z slice */
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         for (chan = 0; chan < 4; chan++) {
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            colors1[chan] = lp_build_lerp_2d(&bld->texel_bld,
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             s_fpart, t_fpart,
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             neighbors1[0][0][chan],
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             neighbors1[0][1][chan],
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             neighbors1[1][0][chan],
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             neighbors1[1][1][chan]);
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* Linearly interpolate the two samples from the two 3D slices */
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         for (chan = 0; chan < 4; chan++) {
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            colors_out[chan] = lp_build_lerp(&bld->texel_bld,
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             r_fpart,
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             colors0[chan], colors1[chan]);
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else {
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* 2D tex */
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         for (chan = 0; chan < 4; chan++) {
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            colors_out[chan] = colors0[chan];
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Sample the texture/mipmap using given image filter and mip filter.
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * data0_ptr and data1_ptr point to the two mipmap levels to sample
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * from.  width0/1_vec, height0/1_vec, depth0/1_vec indicate their sizes.
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If we're using nearest miplevel sampling the '1' values will be null/unused.
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_sample_mipmap(struct lp_build_sample_context *bld,
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       unsigned unit,
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       unsigned img_filter,
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       unsigned mip_filter,
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef s,
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef t,
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef r,
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef ilevel0,
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef ilevel1,
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef lod_fpart,
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef *colors_out)
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMBuilderRef builder = bld->gallivm->builder;
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef size0 = NULL;
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef size1 = NULL;
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef row_stride0_vec = NULL;
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef row_stride1_vec = NULL;
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef img_stride0_vec = NULL;
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef img_stride1_vec = NULL;
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef data_ptr0 = NULL;
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef data_ptr1 = NULL;
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef colors0[4], colors1[4];
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   unsigned chan;
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* sample the first mipmap level */
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_mipmap_level_sizes(bld, ilevel0,
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &size0,
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &row_stride0_vec, &img_stride0_vec);
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   data_ptr0 = lp_build_get_mipmap_level(bld, ilevel0);
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (img_filter == PIPE_TEX_FILTER_NEAREST) {
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_sample_image_nearest(bld, unit,
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    size0,
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    row_stride0_vec, img_stride0_vec,
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    data_ptr0, s, t, r,
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    colors0);
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   else {
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert(img_filter == PIPE_TEX_FILTER_LINEAR);
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_sample_image_linear(bld, unit,
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   size0,
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   row_stride0_vec, img_stride0_vec,
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_ptr0, s, t, r,
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   colors0);
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* Store the first level's colors in the output variables */
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   for (chan = 0; chan < 4; chan++) {
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       LLVMBuildStore(builder, colors0[chan], colors_out[chan]);
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      struct lp_build_if_state if_ctx;
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LLVMValueRef need_lerp;
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned num_quads = bld->coord_bld.type.length / 4;
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* need_lerp = lod_fpart > 0 */
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (num_quads == 1) {
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         need_lerp = LLVMBuildFCmp(builder, LLVMRealUGT,
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   lod_fpart, bld->perquadf_bld.zero,
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   "need_lerp");
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else {
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /*
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          * We'll do mip filtering if any of the quads need it.
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          * It might be better to split the vectors here and only fetch/filter
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          * quads which need it.
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          */
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /*
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          * We unfortunately need to clamp lod_fpart here since we can get
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          * negative values which would screw up filtering if not all
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          * lod_fpart values have same sign.
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          */
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lod_fpart = lp_build_max(&bld->perquadf_bld, lod_fpart,
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  bld->perquadf_bld.zero);
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         need_lerp = lp_build_compare(bld->gallivm, bld->perquadf_bld.type,
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      PIPE_FUNC_GREATER,
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      lod_fpart, bld->perquadf_bld.zero);
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         need_lerp = lp_build_any_true_range(&bld->perquadi_bld, num_quads, need_lerp);
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     }
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_if(&if_ctx, bld->gallivm, need_lerp);
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      {
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* sample the second mipmap level */
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_mipmap_level_sizes(bld, ilevel1,
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     &size1,
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     &row_stride1_vec, &img_stride1_vec);
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         data_ptr1 = lp_build_get_mipmap_level(bld, ilevel1);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         if (img_filter == PIPE_TEX_FILTER_NEAREST) {
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_sample_image_nearest(bld, unit,
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          size1,
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          row_stride1_vec, img_stride1_vec,
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          data_ptr1, s, t, r,
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          colors1);
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         else {
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_sample_image_linear(bld, unit,
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         size1,
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         row_stride1_vec, img_stride1_vec,
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         data_ptr1, s, t, r,
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         colors1);
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* interpolate samples from the two mipmap levels */
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lod_fpart = lp_build_unpack_broadcast_aos_scalars(bld->gallivm,
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                           bld->perquadf_bld.type,
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                           bld->texel_bld.type,
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                           lod_fpart);
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         for (chan = 0; chan < 4; chan++) {
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            colors0[chan] = lp_build_lerp(&bld->texel_bld, lod_fpart,
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          colors0[chan], colors1[chan]);
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            LLVMBuildStore(builder, colors0[chan], colors_out[chan]);
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_endif(&if_ctx);
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Calculate cube face, lod, mip levels.
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_sample_common(struct lp_build_sample_context *bld,
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       unsigned unit,
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef *s,
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef *t,
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef *r,
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const struct lp_derivatives *derivs,
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef lod_bias, /* optional */
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef explicit_lod, /* optional */
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef *lod_ipart,
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef *lod_fpart,
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef *ilevel0,
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LLVMValueRef *ilevel1)
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   const unsigned mip_filter = bld->static_state->min_mip_filter;
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   const unsigned min_filter = bld->static_state->min_img_filter;
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   const unsigned mag_filter = bld->static_state->mag_img_filter;
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef first_level;
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct lp_derivatives face_derivs;
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /*
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   printf("%s mip %d  min %d  mag %d\n", __FUNCTION__,
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          mip_filter, min_filter, mag_filter);
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /*
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * Choose cube face, recompute texcoords and derivatives for the chosen face.
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LLVMValueRef face, face_s, face_t;
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_cube_lookup(bld, *s, *t, *r, &face, &face_s, &face_t);
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *s = face_s; /* vec */
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *t = face_t; /* vec */
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* use 'r' to indicate cube face */
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *r = face; /* vec */
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* recompute ddx, ddy using the new (s,t) face texcoords */
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      face_derivs.ddx_ddy[0] = lp_build_packed_ddx_ddy_twocoord(&bld->coord_bld, *s, *t);
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      face_derivs.ddx_ddy[1] = NULL;
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      derivs = &face_derivs;
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /*
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * Compute the level of detail (float).
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (min_filter != mag_filter ||
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       mip_filter != PIPE_TEX_MIPFILTER_NONE) {
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* Need to compute lod either to choose mipmap levels or to
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       * distinguish between minification/magnification with one mipmap level.
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       */
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_lod_selector(bld, unit, derivs,
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            lod_bias, explicit_lod,
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            mip_filter,
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            lod_ipart, lod_fpart);
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   } else {
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *lod_ipart = bld->perquadi_bld.zero;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /*
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * Compute integer mipmap level(s) to fetch texels from: ilevel0, ilevel1
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   switch (mip_filter) {
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   default:
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert(0 && "bad mip_filter value in lp_build_sample_soa()");
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* fall-through */
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_MIPFILTER_NONE:
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* always use mip level 0 */
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* XXX this is a work-around for an apparent bug in LLVM 2.7.
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          * We should be able to set ilevel0 = const(0) but that causes
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          * bad x86 code to be emitted.
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          * XXX should probably disable that on other llvm versions.
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          */
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         assert(*lod_ipart);
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_nearest_mip_level(bld, unit, *lod_ipart, ilevel0);
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else {
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         first_level = bld->dynamic_state->first_level(bld->dynamic_state,
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       bld->gallivm, unit);
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         first_level = lp_build_broadcast_scalar(&bld->perquadi_bld, first_level);
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *ilevel0 = first_level;
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_MIPFILTER_NEAREST:
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert(*lod_ipart);
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_nearest_mip_level(bld, unit, *lod_ipart, ilevel0);
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEX_MIPFILTER_LINEAR:
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert(*lod_ipart);
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert(*lod_fpart);
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_linear_mip_levels(bld, unit,
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 *lod_ipart, lod_fpart,
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 ilevel0, ilevel1);
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * General texture sampling codegen.
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function handles texture sampling for all texture targets (1D,
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2D, 3D, cube) and all filtering modes.
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_sample_general(struct lp_build_sample_context *bld,
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        unsigned unit,
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        LLVMValueRef s,
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        LLVMValueRef t,
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        LLVMValueRef r,
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        LLVMValueRef lod_ipart,
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        LLVMValueRef lod_fpart,
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        LLVMValueRef ilevel0,
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        LLVMValueRef ilevel1,
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        LLVMValueRef *colors_out)
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct lp_build_context *int_bld = &bld->int_bld;
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMBuilderRef builder = bld->gallivm->builder;
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   const unsigned mip_filter = bld->static_state->min_mip_filter;
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   const unsigned min_filter = bld->static_state->min_img_filter;
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   const unsigned mag_filter = bld->static_state->mag_img_filter;
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef texels[4];
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   unsigned chan;
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /*
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * Get/interpolate texture colors.
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   for (chan = 0; chan < 4; ++chan) {
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     texels[chan] = lp_build_alloca(bld->gallivm, bld->texel_bld.vec_type, "");
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     lp_build_name(texels[chan], "sampler%u_texel_%c_var", unit, "xyzw"[chan]);
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (min_filter == mag_filter) {
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* no need to distinguish between minification and magnification */
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_sample_mipmap(bld, unit,
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             min_filter, mip_filter,
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             s, t, r,
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ilevel0, ilevel1, lod_fpart,
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             texels);
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   else {
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* Emit conditional to choose min image filter or mag image filter
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       * depending on the lod being > 0 or <= 0, respectively.
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       */
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      struct lp_build_if_state if_ctx;
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LLVMValueRef minify;
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* minify = lod >= 0.0 */
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      minify = LLVMBuildICmp(builder, LLVMIntSGE,
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             lod_ipart, int_bld->zero, "");
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_if(&if_ctx, bld->gallivm, minify);
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      {
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* Use the minification filter */
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_sample_mipmap(bld, unit,
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                min_filter, mip_filter,
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                s, t, r,
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                ilevel0, ilevel1, lod_fpart,
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                texels);
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_else(&if_ctx);
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      {
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* Use the magnification filter */
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         lp_build_sample_mipmap(bld, unit,
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                mag_filter, PIPE_TEX_MIPFILTER_NONE,
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                s, t, r,
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                ilevel0, NULL, NULL,
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                texels);
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_endif(&if_ctx);
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   for (chan = 0; chan < 4; ++chan) {
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     colors_out[chan] = LLVMBuildLoad(builder, texels[chan], "");
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     lp_build_name(colors_out[chan], "sampler%u_texel_%c", unit, "xyzw"[chan]);
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Do shadow test/comparison.
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param p  the texcoord Z (aka R, aka P) component
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param texel  the texel to compare against (use the X channel)
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_sample_compare(struct lp_build_sample_context *bld,
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        LLVMValueRef p,
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        LLVMValueRef texel[4])
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct lp_build_context *texel_bld = &bld->texel_bld;
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMBuilderRef builder = bld->gallivm->builder;
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef res;
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   const unsigned chan = 0;
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (bld->static_state->compare_mode == PIPE_TEX_COMPARE_NONE)
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* debug code */
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (0) {
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LLVMValueRef indx = lp_build_const_int32(bld->gallivm, 0);
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LLVMValueRef coord = LLVMBuildExtractElement(builder, p, indx, "");
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LLVMValueRef tex = LLVMBuildExtractElement(builder, texel[chan], indx, "");
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_printf(bld->gallivm, "shadow compare coord %f to texture %f\n",
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      coord, tex);
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* Clamp p coords to [0,1] */
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   p = lp_build_clamp(&bld->coord_bld, p,
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      bld->coord_bld.zero,
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      bld->coord_bld.one);
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* result = (p FUNC texel) ? 1 : 0 */
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   res = lp_build_cmp(texel_bld, bld->static_state->compare_func,
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      p, texel[chan]);
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   res = lp_build_select(texel_bld, res, texel_bld->one, texel_bld->zero);
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   texel[0] =
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   texel[1] =
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   texel[2] = res;
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   texel[3] = texel_bld->one;
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Just set texels to white instead of actually sampling the texture.
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For debugging.
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_sample_nop(struct gallivm_state *gallivm,
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    struct lp_type type,
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    unsigned num_coords,
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const LLVMValueRef *coords,
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    LLVMValueRef texel_out[4])
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef one = lp_build_one(gallivm, type);
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   unsigned chan;
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   for (chan = 0; chan < 4; chan++) {
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      texel_out[chan] = one;
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Build texture sampling code.
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 'texel' will return a vector of four LLVMValueRefs corresponding to
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * R, G, B, A.
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param type  vector float type to use for coords, etc.
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \param derivs  partial derivatives of (s,t,r,q) with respect to x and y
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_sample_soa(struct gallivm_state *gallivm,
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const struct lp_sampler_static_state *static_state,
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    struct lp_sampler_dynamic_state *dynamic_state,
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    struct lp_type type,
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    unsigned unit,
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    unsigned num_coords,
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const LLVMValueRef *coords,
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const struct lp_derivatives *derivs,
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    LLVMValueRef lod_bias, /* optional */
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    LLVMValueRef explicit_lod, /* optional */
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    LLVMValueRef texel_out[4])
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   unsigned dims = texture_dims(static_state->target);
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct lp_build_sample_context bld;
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context);
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMBuilderRef builder = gallivm->builder;
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef tex_width, tex_height, tex_depth;
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef s;
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef t;
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef r;
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (0) {
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      enum pipe_format fmt = static_state->format;
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      debug_printf("Sample from %s\n", util_format_name(fmt));
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   assert(type.floating);
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* Setup our build context */
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   memset(&bld, 0, sizeof bld);
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.gallivm = gallivm;
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.static_state = static_state;
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.dynamic_state = dynamic_state;
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.format_desc = util_format_description(static_state->format);
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.dims = dims;
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.vector_width = lp_type_width(type);
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.float_type = lp_type_float(32);
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.int_type = lp_type_int(32);
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.coord_type = type;
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.int_coord_type = lp_int_type(type);
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.float_size_type = lp_type_float(32);
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.float_size_type.length = dims > 1 ? 4 : 1;
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.int_size_type = lp_int_type(bld.float_size_type);
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.texel_type = type;
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.perquadf_type = type;
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* we want native vector size to be able to use our intrinsics */
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.perquadf_type.length = type.length > 4 ? ((type.length + 15) / 16) * 4 : 1;
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.perquadi_type = lp_int_type(bld.perquadf_type);
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_context_init(&bld.float_bld, gallivm, bld.float_type);
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_context_init(&bld.float_vec_bld, gallivm, type);
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_context_init(&bld.int_bld, gallivm, bld.int_type);
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_context_init(&bld.coord_bld, gallivm, bld.coord_type);
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_context_init(&bld.int_coord_bld, gallivm, bld.int_coord_type);
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_context_init(&bld.int_size_bld, gallivm, bld.int_size_type);
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_context_init(&bld.float_size_bld, gallivm, bld.float_size_type);
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_context_init(&bld.texel_bld, gallivm, bld.texel_type);
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_context_init(&bld.perquadf_bld, gallivm, bld.perquadf_type);
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_context_init(&bld.perquadi_bld, gallivm, bld.perquadi_type);
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* Get the dynamic state */
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   tex_width = dynamic_state->width(dynamic_state, gallivm, unit);
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   tex_height = dynamic_state->height(dynamic_state, gallivm, unit);
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   tex_depth = dynamic_state->depth(dynamic_state, gallivm, unit);
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.row_stride_array = dynamic_state->row_stride(dynamic_state, gallivm, unit);
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.img_stride_array = dynamic_state->img_stride(dynamic_state, gallivm, unit);
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   bld.data_array = dynamic_state->data_ptr(dynamic_state, gallivm, unit);
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* Note that data_array is an array[level] of pointers to texture images */
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   s = coords[0];
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   t = coords[1];
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   r = coords[2];
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* width, height, depth as single int vector */
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (dims <= 1) {
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bld.int_size = tex_width;
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   else {
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bld.int_size = LLVMBuildInsertElement(builder, bld.int_size_bld.undef,
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            tex_width, LLVMConstInt(i32t, 0, 0), "");
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (dims >= 2) {
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         bld.int_size = LLVMBuildInsertElement(builder, bld.int_size,
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               tex_height, LLVMConstInt(i32t, 1, 0), "");
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         if (dims >= 3) {
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld.int_size = LLVMBuildInsertElement(builder, bld.int_size,
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  tex_depth, LLVMConstInt(i32t, 2, 0), "");
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (0) {
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* For debug: no-op texture sampling */
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_sample_nop(gallivm,
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          bld.texel_type,
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          num_coords,
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          coords,
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          texel_out);
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   else {
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LLVMValueRef lod_ipart = NULL, lod_fpart = NULL;
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LLVMValueRef ilevel0 = NULL, ilevel1 = NULL;
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned num_quads = type.length / 4;
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const unsigned mip_filter = bld.static_state->min_mip_filter;
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      boolean use_aos = util_format_fits_8unorm(bld.format_desc) &&
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        lp_is_simple_wrap_mode(static_state->wrap_s) &&
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        lp_is_simple_wrap_mode(static_state->wrap_t);
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if ((gallivm_debug & GALLIVM_DEBUG_PERF) &&
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !use_aos && util_format_fits_8unorm(bld.format_desc)) {
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         debug_printf("%s: using floating point linear filtering for %s\n",
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      __FUNCTION__, bld.format_desc->short_name);
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         debug_printf("  min_img %d  mag_img %d  mip %d  wraps %d  wrapt %d\n",
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      static_state->min_img_filter,
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      static_state->mag_img_filter,
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      static_state->min_mip_filter,
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      static_state->wrap_s,
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      static_state->wrap_t);
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lp_build_sample_common(&bld, unit,
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &s, &t, &r,
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             derivs, lod_bias, explicit_lod,
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &lod_ipart, &lod_fpart,
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &ilevel0, &ilevel1);
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /*
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       * we only try 8-wide sampling with soa as it appears to
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       * be a loss with aos with AVX.
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       */
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (num_quads == 1 || (mip_filter == PIPE_TEX_MIPFILTER_NONE &&
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             !use_aos)) {
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         if (num_quads > 1) {
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            LLVMValueRef index0 = lp_build_const_int32(gallivm, 0);
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* These parameters are the same for all quads */
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lod_ipart = LLVMBuildExtractElement(builder, lod_ipart, index0, "");
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ilevel0 = LLVMBuildExtractElement(builder, ilevel0, index0, "");
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         if (use_aos) {
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* do sampling/filtering with fixed pt arithmetic */
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_sample_aos(&bld, unit,
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                s, t, r,
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                lod_ipart, lod_fpart,
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                ilevel0, ilevel1,
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                texel_out);
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         else {
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_sample_general(&bld, unit,
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    s, t, r,
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    lod_ipart, lod_fpart,
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    ilevel0, ilevel1,
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    texel_out);
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else {
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         struct lp_build_if_state if_ctx;
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         LLVMValueRef notsame_levels, notsame;
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         LLVMValueRef index0 = lp_build_const_int32(gallivm, 0);
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         LLVMValueRef texels[4];
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         LLVMValueRef texelout[4];
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         unsigned j;
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         texels[0] = lp_build_alloca(gallivm, bld.texel_bld.vec_type, "texr");
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         texels[1] = lp_build_alloca(gallivm, bld.texel_bld.vec_type, "texg");
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         texels[2] = lp_build_alloca(gallivm, bld.texel_bld.vec_type, "texb");
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         texels[3] = lp_build_alloca(gallivm, bld.texel_bld.vec_type, "texa");
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /* only build the if if we MAY split, otherwise always split */
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         if (!use_aos) {
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            notsame = lp_build_extract_broadcast(gallivm,
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 bld.perquadi_bld.type,
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 bld.perquadi_bld.type,
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 ilevel0, index0);
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            notsame = lp_build_sub(&bld.perquadi_bld, ilevel0, notsame);
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            notsame_levels = lp_build_any_true_range(&bld.perquadi_bld, num_quads,
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     notsame);
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               notsame = lp_build_extract_broadcast(gallivm,
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    bld.perquadi_bld.type,
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    bld.perquadi_bld.type,
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    ilevel1, index0);
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               notsame = lp_build_sub(&bld.perquadi_bld, ilevel1, notsame);
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               notsame = lp_build_any_true_range(&bld.perquadi_bld, num_quads, notsame);
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               notsame_levels = LLVMBuildOr(builder, notsame_levels, notsame, "");
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_if(&if_ctx, gallivm, notsame_levels);
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         {
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            struct lp_build_sample_context bld4;
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            struct lp_type type4 = type;
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            unsigned i;
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            LLVMValueRef texelout4[4];
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            LLVMValueRef texelouttmp[4][LP_MAX_VECTOR_LENGTH/16];
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            type4.length = 4;
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* Setup our build context */
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            memset(&bld4, 0, sizeof bld4);
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.gallivm = bld.gallivm;
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.static_state = bld.static_state;
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.dynamic_state = bld.dynamic_state;
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.format_desc = bld.format_desc;
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.dims = bld.dims;
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.row_stride_array = bld.row_stride_array;
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.img_stride_array = bld.img_stride_array;
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.data_array = bld.data_array;
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.int_size = bld.int_size;
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.vector_width = lp_type_width(type4);
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.float_type = lp_type_float(32);
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.int_type = lp_type_int(32);
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.coord_type = type4;
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.int_coord_type = lp_int_type(type4);
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.float_size_type = lp_type_float(32);
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.float_size_type.length = dims > 1 ? 4 : 1;
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.int_size_type = lp_int_type(bld4.float_size_type);
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.texel_type = type4;
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.perquadf_type = type4;
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* we want native vector size to be able to use our intrinsics */
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.perquadf_type.length = 1;
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bld4.perquadi_type = lp_int_type(bld4.perquadf_type);
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_context_init(&bld4.float_bld, gallivm, bld4.float_type);
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_context_init(&bld4.float_vec_bld, gallivm, type4);
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_context_init(&bld4.int_bld, gallivm, bld4.int_type);
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_context_init(&bld4.coord_bld, gallivm, bld4.coord_type);
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_context_init(&bld4.int_coord_bld, gallivm, bld4.int_coord_type);
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_context_init(&bld4.int_size_bld, gallivm, bld4.int_size_type);
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_context_init(&bld4.float_size_bld, gallivm, bld4.float_size_type);
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_context_init(&bld4.texel_bld, gallivm, bld4.texel_type);
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_context_init(&bld4.perquadf_bld, gallivm, bld4.perquadf_type);
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_context_init(&bld4.perquadi_bld, gallivm, bld4.perquadi_type);
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for (i = 0; i < num_quads; i++) {
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               LLVMValueRef s4, t4, r4;
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               LLVMValueRef lod_iparts, lod_fparts = NULL;
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               LLVMValueRef ilevel0s, ilevel1s = NULL;
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               LLVMValueRef indexi = lp_build_const_int32(gallivm, i);
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               s4 = lp_build_extract_range(gallivm, s, 4*i, 4);
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               t4 = lp_build_extract_range(gallivm, t, 4*i, 4);
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               r4 = lp_build_extract_range(gallivm, r, 4*i, 4);
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               lod_iparts = LLVMBuildExtractElement(builder, lod_ipart, indexi, "");
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               ilevel0s = LLVMBuildExtractElement(builder, ilevel0, indexi, "");
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  ilevel1s = LLVMBuildExtractElement(builder, ilevel1, indexi, "");
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  lod_fparts = LLVMBuildExtractElement(builder, lod_fpart, indexi, "");
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               }
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               if (use_aos) {
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  /* do sampling/filtering with fixed pt arithmetic */
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  lp_build_sample_aos(&bld4, unit,
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      s4, t4, r4,
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      lod_iparts, lod_fparts,
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      ilevel0s, ilevel1s,
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      texelout4);
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               }
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               else {
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  lp_build_sample_general(&bld4, unit,
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          s4, t4, r4,
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          lod_iparts, lod_fparts,
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          ilevel0s, ilevel1s,
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          texelout4);
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               }
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               for (j = 0; j < 4; j++) {
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  texelouttmp[j][i] = texelout4[j];
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               }
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for (j = 0; j < 4; j++) {
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               texelout[j] = lp_build_concat(gallivm, texelouttmp[j], type4, num_quads);
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               LLVMBuildStore(builder, texelout[j], texels[j]);
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         if (!use_aos) {
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            LLVMValueRef ilevel0s, lod_iparts, ilevel1s = NULL;
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_else(&if_ctx);
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* These parameters are the same for all quads */
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lod_iparts = LLVMBuildExtractElement(builder, lod_ipart, index0, "");
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ilevel0s = LLVMBuildExtractElement(builder, ilevel0, index0, "");
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               ilevel1s = LLVMBuildExtractElement(builder, ilevel1, index0, "");
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (use_aos) {
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               /* do sampling/filtering with fixed pt arithmetic */
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               lp_build_sample_aos(&bld, unit,
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   s, t, r,
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   lod_iparts, lod_fpart,
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   ilevel0s, ilevel1s,
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   texelout);
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else {
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               lp_build_sample_general(&bld, unit,
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       s, t, r,
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       lod_iparts, lod_fpart,
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       ilevel0s, ilevel1s,
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       texelout);
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for (j = 0; j < 4; j++) {
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               LLVMBuildStore(builder, texelout[j], texels[j]);
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            lp_build_endif(&if_ctx);
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         for (j = 0; j < 4; j++) {
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            texel_out[j] = LLVMBuildLoad(builder, texels[j], "");
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         }
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_sample_compare(&bld, r, texel_out);
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   apply_sampler_swizzle(&bld, texel_out);
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_size_query_soa(struct gallivm_state *gallivm,
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const struct lp_sampler_static_state *static_state,
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        struct lp_sampler_dynamic_state *dynamic_state,
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        struct lp_type int_type,
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        unsigned unit,
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        LLVMValueRef explicit_lod,
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        LLVMValueRef *sizes_out)
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef lod;
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMValueRef size;
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   int dims, i;
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct lp_build_context bld_int_vec;
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   switch (static_state->target) {
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEXTURE_1D:
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_BUFFER:
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dims = 1;
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEXTURE_2D:
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEXTURE_CUBE:
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEXTURE_RECT:
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dims = 2;
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PIPE_TEXTURE_3D:
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dims = 3;
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   default:
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert(0);
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   assert(!int_type.floating);
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   lp_build_context_init(&bld_int_vec, gallivm, lp_type_int_vec(32, 128));
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (explicit_lod) {
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LLVMValueRef first_level;
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lod = LLVMBuildExtractElement(gallivm->builder, explicit_lod, lp_build_const_int32(gallivm, 0), "");
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      first_level = dynamic_state->first_level(dynamic_state, gallivm, unit);
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lod = lp_build_broadcast_scalar(&bld_int_vec,
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      LLVMBuildAdd(gallivm->builder, lod, first_level, "lod"));
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   } else {
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      lod = bld_int_vec.zero;
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   size = bld_int_vec.undef;
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   size = LLVMBuildInsertElement(gallivm->builder, size,
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 dynamic_state->width(dynamic_state, gallivm, unit),
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 lp_build_const_int32(gallivm, 0), "");
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (dims >= 2) {
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size = LLVMBuildInsertElement(gallivm->builder, size,
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    dynamic_state->height(dynamic_state, gallivm, unit),
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    lp_build_const_int32(gallivm, 1), "");
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (dims >= 3) {
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size = LLVMBuildInsertElement(gallivm->builder, size,
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    dynamic_state->depth(dynamic_state, gallivm, unit),
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    lp_build_const_int32(gallivm, 2), "");
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   size = lp_build_minify(&bld_int_vec, size, lod);
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   for (i=0; i < dims; i++) {
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sizes_out[i] = lp_build_extract_broadcast(gallivm, bld_int_vec.type, int_type,
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                size,
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                lp_build_const_int32(gallivm, i));
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)