Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2010 VMware, Inc.
  4.  * All rights reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. /**
  29.  * Texture sampling code generation
  30.  * @author Jose Fonseca <jfonseca@vmware.com>
  31.  */
  32.  
  33. #include "pipe/p_defines.h"
  34. #include "pipe/p_shader_tokens.h"
  35. #include "gallivm/lp_bld_const.h"
  36. #include "gallivm/lp_bld_debug.h"
  37. #include "gallivm/lp_bld_type.h"
  38. #include "gallivm/lp_bld_sample.h"
  39. #include "gallivm/lp_bld_tgsi.h"
  40.  
  41.  
  42. #include "util/u_debug.h"
  43. #include "util/u_memory.h"
  44. #include "util/u_pointer.h"
  45. #include "util/u_string.h"
  46.  
  47. #include "draw_llvm.h"
  48.  
  49.  
  50. /**
  51.  * This provides the bridge between the sampler state store in
  52.  * lp_jit_context and lp_jit_texture and the sampler code
  53.  * generator. It provides the texture layout information required by
  54.  * the texture sampler code generator in terms of the state stored in
  55.  * lp_jit_context and lp_jit_texture in runtime.
  56.  */
  57. struct draw_llvm_sampler_dynamic_state
  58. {
  59.    struct lp_sampler_dynamic_state base;
  60.  
  61.    const struct draw_sampler_static_state *static_state;
  62. };
  63.  
  64.  
  65. /**
  66.  * This is the bridge between our sampler and the TGSI translator.
  67.  */
  68. struct draw_llvm_sampler_soa
  69. {
  70.    struct lp_build_sampler_soa base;
  71.  
  72.    struct draw_llvm_sampler_dynamic_state dynamic_state;
  73. };
  74.  
  75.  
  76. /**
  77.  * Fetch the specified member of the lp_jit_texture structure.
  78.  * \param emit_load  if TRUE, emit the LLVM load instruction to actually
  79.  *                   fetch the field's value.  Otherwise, just emit the
  80.  *                   GEP code to address the field.
  81.  *
  82.  * @sa http://llvm.org/docs/GetElementPtr.html
  83.  */
  84. static LLVMValueRef
  85. draw_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
  86.                          struct gallivm_state *gallivm,
  87.                          LLVMValueRef context_ptr,
  88.                          unsigned texture_unit,
  89.                          unsigned member_index,
  90.                          const char *member_name,
  91.                          boolean emit_load)
  92. {
  93.    LLVMBuilderRef builder = gallivm->builder;
  94.    LLVMValueRef indices[4];
  95.    LLVMValueRef ptr;
  96.    LLVMValueRef res;
  97.  
  98.    debug_assert(texture_unit < PIPE_MAX_SHADER_SAMPLER_VIEWS);
  99.  
  100.    /* context[0] */
  101.    indices[0] = lp_build_const_int32(gallivm, 0);
  102.    /* context[0].textures */
  103.    indices[1] = lp_build_const_int32(gallivm, DRAW_JIT_CTX_TEXTURES);
  104.    /* context[0].textures[unit] */
  105.    indices[2] = lp_build_const_int32(gallivm, texture_unit);
  106.    /* context[0].textures[unit].member */
  107.    indices[3] = lp_build_const_int32(gallivm, member_index);
  108.  
  109.    ptr = LLVMBuildGEP(builder, context_ptr, indices, Elements(indices), "");
  110.  
  111.    if (emit_load)
  112.       res = LLVMBuildLoad(builder, ptr, "");
  113.    else
  114.       res = ptr;
  115.  
  116.    lp_build_name(res, "context.texture%u.%s", texture_unit, member_name);
  117.  
  118.    return res;
  119. }
  120.  
  121.  
  122. /**
  123.  * Fetch the specified member of the lp_jit_sampler structure.
  124.  * \param emit_load  if TRUE, emit the LLVM load instruction to actually
  125.  *                   fetch the field's value.  Otherwise, just emit the
  126.  *                   GEP code to address the field.
  127.  *
  128.  * @sa http://llvm.org/docs/GetElementPtr.html
  129.  */
  130. static LLVMValueRef
  131. draw_llvm_sampler_member(const struct lp_sampler_dynamic_state *base,
  132.                          struct gallivm_state *gallivm,
  133.                          LLVMValueRef context_ptr,
  134.                          unsigned sampler_unit,
  135.                          unsigned member_index,
  136.                          const char *member_name,
  137.                          boolean emit_load)
  138. {
  139.    LLVMBuilderRef builder = gallivm->builder;
  140.    LLVMValueRef indices[4];
  141.    LLVMValueRef ptr;
  142.    LLVMValueRef res;
  143.  
  144.    debug_assert(sampler_unit < PIPE_MAX_SAMPLERS);
  145.  
  146.    /* context[0] */
  147.    indices[0] = lp_build_const_int32(gallivm, 0);
  148.    /* context[0].samplers */
  149.    indices[1] = lp_build_const_int32(gallivm, DRAW_JIT_CTX_SAMPLERS);
  150.    /* context[0].samplers[unit] */
  151.    indices[2] = lp_build_const_int32(gallivm, sampler_unit);
  152.    /* context[0].samplers[unit].member */
  153.    indices[3] = lp_build_const_int32(gallivm, member_index);
  154.  
  155.    ptr = LLVMBuildGEP(builder, context_ptr, indices, Elements(indices), "");
  156.  
  157.    if (emit_load)
  158.       res = LLVMBuildLoad(builder, ptr, "");
  159.    else
  160.       res = ptr;
  161.  
  162.    lp_build_name(res, "context.sampler%u.%s", sampler_unit, member_name);
  163.  
  164.    return res;
  165. }
  166.  
  167.  
  168. /**
  169.  * Helper macro to instantiate the functions that generate the code to
  170.  * fetch the members of lp_jit_texture to fulfill the sampler code
  171.  * generator requests.
  172.  *
  173.  * This complexity is the price we have to pay to keep the texture
  174.  * sampler code generator a reusable module without dependencies to
  175.  * llvmpipe internals.
  176.  */
  177. #define DRAW_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load)  \
  178.    static LLVMValueRef \
  179.    draw_llvm_texture_##_name( const struct lp_sampler_dynamic_state *base, \
  180.                               struct gallivm_state *gallivm,               \
  181.                               LLVMValueRef context_ptr,                    \
  182.                               unsigned texture_unit)                       \
  183.    { \
  184.       return draw_llvm_texture_member(base, gallivm, context_ptr, \
  185.                                       texture_unit, _index, #_name, _emit_load ); \
  186.    }
  187.  
  188.  
  189. DRAW_LLVM_TEXTURE_MEMBER(width,      DRAW_JIT_TEXTURE_WIDTH, TRUE)
  190. DRAW_LLVM_TEXTURE_MEMBER(height,     DRAW_JIT_TEXTURE_HEIGHT, TRUE)
  191. DRAW_LLVM_TEXTURE_MEMBER(depth,      DRAW_JIT_TEXTURE_DEPTH, TRUE)
  192. DRAW_LLVM_TEXTURE_MEMBER(first_level,DRAW_JIT_TEXTURE_FIRST_LEVEL, TRUE)
  193. DRAW_LLVM_TEXTURE_MEMBER(last_level, DRAW_JIT_TEXTURE_LAST_LEVEL, TRUE)
  194. DRAW_LLVM_TEXTURE_MEMBER(base_ptr,   DRAW_JIT_TEXTURE_BASE, TRUE)
  195. DRAW_LLVM_TEXTURE_MEMBER(row_stride, DRAW_JIT_TEXTURE_ROW_STRIDE, FALSE)
  196. DRAW_LLVM_TEXTURE_MEMBER(img_stride, DRAW_JIT_TEXTURE_IMG_STRIDE, FALSE)
  197. DRAW_LLVM_TEXTURE_MEMBER(mip_offsets, DRAW_JIT_TEXTURE_MIP_OFFSETS, FALSE)
  198.  
  199.  
  200. #define DRAW_LLVM_SAMPLER_MEMBER(_name, _index, _emit_load)  \
  201.    static LLVMValueRef \
  202.    draw_llvm_sampler_##_name( const struct lp_sampler_dynamic_state *base, \
  203.                               struct gallivm_state *gallivm,               \
  204.                               LLVMValueRef context_ptr,                    \
  205.                               unsigned sampler_unit)                       \
  206.    { \
  207.       return draw_llvm_sampler_member(base, gallivm, context_ptr, \
  208.                                       sampler_unit, _index, #_name, _emit_load ); \
  209.    }
  210.  
  211.  
  212. DRAW_LLVM_SAMPLER_MEMBER(min_lod,    DRAW_JIT_SAMPLER_MIN_LOD, TRUE)
  213. DRAW_LLVM_SAMPLER_MEMBER(max_lod,    DRAW_JIT_SAMPLER_MAX_LOD, TRUE)
  214. DRAW_LLVM_SAMPLER_MEMBER(lod_bias,   DRAW_JIT_SAMPLER_LOD_BIAS, TRUE)
  215. DRAW_LLVM_SAMPLER_MEMBER(border_color, DRAW_JIT_SAMPLER_BORDER_COLOR, FALSE)
  216.  
  217.  
  218. static void
  219. draw_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
  220. {
  221.    FREE(sampler);
  222. }
  223.  
  224.  
  225. /**
  226.  * Fetch filtered values from texture.
  227.  * The 'texel' parameter returns four vectors corresponding to R, G, B, A.
  228.  */
  229. static void
  230. draw_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
  231.                                        struct gallivm_state *gallivm,
  232.                                        const struct lp_sampler_params *params)
  233. {
  234.    struct draw_llvm_sampler_soa *sampler = (struct draw_llvm_sampler_soa *)base;
  235.    unsigned texture_index = params->texture_index;
  236.    unsigned sampler_index = params->sampler_index;
  237.  
  238.    assert(texture_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
  239.    assert(sampler_index < PIPE_MAX_SAMPLERS);
  240.  
  241.    lp_build_sample_soa(&sampler->dynamic_state.static_state[texture_index].texture_state,
  242.                        &sampler->dynamic_state.static_state[sampler_index].sampler_state,
  243.                        &sampler->dynamic_state.base,
  244.                        gallivm, params);
  245. }
  246.  
  247.  
  248. /**
  249.  * Fetch the texture size.
  250.  */
  251. static void
  252. draw_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base,
  253.                                       struct gallivm_state *gallivm,
  254.                                       struct lp_type type,
  255.                                       unsigned texture_unit,
  256.                                       unsigned target,
  257.                                       LLVMValueRef context_ptr,
  258.                                       boolean is_sviewinfo,
  259.                                       enum lp_sampler_lod_property lod_property,
  260.                                       LLVMValueRef explicit_lod, /* optional */
  261.                                       LLVMValueRef *sizes_out)
  262. {
  263.    struct draw_llvm_sampler_soa *sampler = (struct draw_llvm_sampler_soa *)base;
  264.  
  265.    assert(texture_unit < PIPE_MAX_SHADER_SAMPLER_VIEWS);
  266.  
  267.    lp_build_size_query_soa(gallivm,
  268.                            &sampler->dynamic_state.static_state[texture_unit].texture_state,
  269.                            &sampler->dynamic_state.base,
  270.                            type,
  271.                            texture_unit,
  272.                            target,
  273.                            context_ptr,
  274.                            is_sviewinfo,
  275.                            lod_property,
  276.                            explicit_lod,
  277.                            sizes_out);
  278. }
  279.  
  280. struct lp_build_sampler_soa *
  281. draw_llvm_sampler_soa_create(const struct draw_sampler_static_state *static_state)
  282. {
  283.    struct draw_llvm_sampler_soa *sampler;
  284.  
  285.    sampler = CALLOC_STRUCT(draw_llvm_sampler_soa);
  286.    if(!sampler)
  287.       return NULL;
  288.  
  289.    sampler->base.destroy = draw_llvm_sampler_soa_destroy;
  290.    sampler->base.emit_tex_sample = draw_llvm_sampler_soa_emit_fetch_texel;
  291.    sampler->base.emit_size_query = draw_llvm_sampler_soa_emit_size_query;
  292.    sampler->dynamic_state.base.width = draw_llvm_texture_width;
  293.    sampler->dynamic_state.base.height = draw_llvm_texture_height;
  294.    sampler->dynamic_state.base.depth = draw_llvm_texture_depth;
  295.    sampler->dynamic_state.base.first_level = draw_llvm_texture_first_level;
  296.    sampler->dynamic_state.base.last_level = draw_llvm_texture_last_level;
  297.    sampler->dynamic_state.base.row_stride = draw_llvm_texture_row_stride;
  298.    sampler->dynamic_state.base.img_stride = draw_llvm_texture_img_stride;
  299.    sampler->dynamic_state.base.base_ptr = draw_llvm_texture_base_ptr;
  300.    sampler->dynamic_state.base.mip_offsets = draw_llvm_texture_mip_offsets;
  301.    sampler->dynamic_state.base.min_lod = draw_llvm_sampler_min_lod;
  302.    sampler->dynamic_state.base.max_lod = draw_llvm_sampler_max_lod;
  303.    sampler->dynamic_state.base.lod_bias = draw_llvm_sampler_lod_bias;
  304.    sampler->dynamic_state.base.border_color = draw_llvm_sampler_border_color;
  305.    sampler->dynamic_state.static_state = static_state;
  306.  
  307.    return &sampler->base;
  308. }
  309.  
  310.