diff options
Diffstat (limited to 'src/gallium')
| -rw-r--r-- | src/gallium/auxiliary/Makefile | 3 | ||||
| -rw-r--r-- | src/gallium/auxiliary/SConscript | 3 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_context.c | 56 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_context.h | 18 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm.c | 98 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm.h | 42 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm_sample.c | 216 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_private.h | 7 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c | 5 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_screen.c | 2 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup.c | 73 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup.h | 5 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_context.h | 4 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_derived.c | 8 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_sampler.c | 8 | 
15 files changed, 516 insertions, 32 deletions
| diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index 91f8b1034a..731f60d216 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -171,7 +171,8 @@ GALLIVM_SOURCES = \          draw/draw_llvm.c \          draw/draw_vs_llvm.c \          draw/draw_pt_fetch_shade_pipeline_llvm.c \ -        draw/draw_llvm_translate.c +        draw/draw_llvm_translate.c \ +        draw/draw_llvm_sample.c  GALLIVM_CPP_SOURCES = \      gallivm/lp_bld_misc.cpp diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript index af3f47bbf0..7e06cc0c76 100644 --- a/src/gallium/auxiliary/SConscript +++ b/src/gallium/auxiliary/SConscript @@ -221,7 +221,8 @@ if env['llvm']:      'draw/draw_llvm.c',      'draw/draw_pt_fetch_shade_pipeline_llvm.c',      'draw/draw_llvm_translate.c', -    'draw/draw_vs_llvm.c' +    'draw/draw_vs_llvm.c', +    'draw/draw_llvm_sample.c'      ]  gallium = env.ConvenienceLibrary( diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index dab95e5051..aac1ed602c 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -40,6 +40,7 @@  #if HAVE_LLVM  #include "gallivm/lp_bld_init.h" +#include "draw_llvm.h"  #endif  struct draw_context *draw_create( struct pipe_context *pipe ) @@ -52,6 +53,7 @@ struct draw_context *draw_create( struct pipe_context *pipe )     lp_build_init();     assert(lp_build_engine);     draw->engine = lp_build_engine; +   draw->llvm = draw_llvm_create(draw);  #endif     if (!draw_init(draw)) @@ -132,6 +134,9 @@ void draw_destroy( struct draw_context *draw )     draw_pt_destroy( draw );     draw_vs_destroy( draw );     draw_gs_destroy( draw ); +#ifdef HAVE_LLVM +   draw_llvm_destroy( draw->llvm ); +#endif     FREE( draw );  } @@ -601,3 +606,54 @@ draw_set_so_state(struct draw_context *draw,            state,            sizeof(struct pipe_stream_output_state));  } + +void +draw_set_sampler_views(struct draw_context *draw, +                       struct pipe_sampler_view **views, +                       unsigned num) +{ +   unsigned i; + +   debug_assert(num <= PIPE_MAX_VERTEX_SAMPLERS); + +   for (i = 0; i < num; ++i) +      draw->sampler_views[i] = views[i]; +   for (i = num; i < PIPE_MAX_VERTEX_SAMPLERS; ++i) +      draw->sampler_views[i] = NULL; + +   draw->num_sampler_views = num; +} + +void +draw_set_samplers(struct draw_context *draw, +                  struct pipe_sampler_state **samplers, +                  unsigned num) +{ +   unsigned i; + +   debug_assert(num <= PIPE_MAX_VERTEX_SAMPLERS); + +   for (i = 0; i < num; ++i) +      draw->samplers[i] = samplers[i]; +   for (i = num; i < PIPE_MAX_VERTEX_SAMPLERS; ++i) +      draw->samplers[i] = NULL; + +   draw->num_samplers = num; +} + +void +draw_set_mapped_texture(struct draw_context *draw, +                        unsigned sampler_idx, +                        uint32_t width, uint32_t height, uint32_t depth, +                        uint32_t last_level, +                        uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS], +                        uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS], +                        const void *data[DRAW_MAX_TEXTURE_LEVELS]) +{ +#ifdef HAVE_LLVM +   draw_llvm_set_mapped_texture(draw, +                                sampler_idx, +                                width, height, depth, last_level, +                                row_stride, img_stride, data); +#endif +} diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index c0122f2aca..724f992783 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -47,6 +47,7 @@ struct draw_vertex_shader;  struct draw_geometry_shader;  struct tgsi_sampler; +#define DRAW_MAX_TEXTURE_LEVELS 13  /* 4K x 4K for now */  struct draw_context *draw_create( struct pipe_context *pipe ); @@ -101,6 +102,23 @@ draw_texture_samplers(struct draw_context *draw,                        uint num_samplers,                        struct tgsi_sampler **samplers); +void +draw_set_sampler_views(struct draw_context *draw, +                       struct pipe_sampler_view **views, +                       unsigned num); +void +draw_set_samplers(struct draw_context *draw, +                  struct pipe_sampler_state **samplers, +                  unsigned num); + +void +draw_set_mapped_texture(struct draw_context *draw, +                        unsigned sampler_idx, +                        uint32_t width, uint32_t height, uint32_t depth, +                        uint32_t last_level, +                        uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS], +                        uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS], +                        const void *data[DRAW_MAX_TEXTURE_LEVELS]);  /* diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index f521669fcd..42653d36ec 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -42,14 +42,13 @@  #include "tgsi/tgsi_dump.h"  #include "util/u_cpu_detect.h" -#include "util/u_string.h"  #include "util/u_pointer.h" +#include "util/u_string.h"  #include <llvm-c/Transforms/Scalar.h>  #define DEBUG_STORE 0 -  /* generates the draw jit function */  static void  draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *var); @@ -63,12 +62,19 @@ init_globals(struct draw_llvm *llvm)     /* struct draw_jit_texture */     { -      LLVMTypeRef elem_types[4]; +      LLVMTypeRef elem_types[DRAW_JIT_TEXTURE_NUM_FIELDS];        elem_types[DRAW_JIT_TEXTURE_WIDTH]  = LLVMInt32Type();        elem_types[DRAW_JIT_TEXTURE_HEIGHT] = LLVMInt32Type(); -      elem_types[DRAW_JIT_TEXTURE_STRIDE] = LLVMInt32Type(); -      elem_types[DRAW_JIT_TEXTURE_DATA]   = LLVMPointerType(LLVMInt8Type(), 0); +      elem_types[DRAW_JIT_TEXTURE_DEPTH] = LLVMInt32Type(); +      elem_types[DRAW_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32Type(); +      elem_types[DRAW_JIT_TEXTURE_ROW_STRIDE] = +         LLVMArrayType(LLVMInt32Type(), DRAW_MAX_TEXTURE_LEVELS); +      elem_types[DRAW_JIT_TEXTURE_IMG_STRIDE] = +         LLVMArrayType(LLVMInt32Type(), DRAW_MAX_TEXTURE_LEVELS); +      elem_types[DRAW_JIT_TEXTURE_DATA] = +         LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0), +                       DRAW_MAX_TEXTURE_LEVELS);        texture_type = LLVMStructType(elem_types, Elements(elem_types), 0); @@ -78,9 +84,18 @@ init_globals(struct draw_llvm *llvm)        LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, height,                               llvm->target, texture_type,                               DRAW_JIT_TEXTURE_HEIGHT); -      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, stride, +      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, depth, +                             llvm->target, texture_type, +                             DRAW_JIT_TEXTURE_DEPTH); +      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, last_level, +                             llvm->target, texture_type, +                             DRAW_JIT_TEXTURE_LAST_LEVEL); +      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, row_stride,                               llvm->target, texture_type, -                             DRAW_JIT_TEXTURE_STRIDE); +                             DRAW_JIT_TEXTURE_ROW_STRIDE); +      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, img_stride, +                             llvm->target, texture_type, +                             DRAW_JIT_TEXTURE_IMG_STRIDE);        LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, data,                               llvm->target, texture_type,                               DRAW_JIT_TEXTURE_DATA); @@ -98,7 +113,8 @@ init_globals(struct draw_llvm *llvm)        elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* vs_constants */        elem_types[1] = LLVMPointerType(LLVMFloatType(), 0); /* vs_constants */ -      elem_types[2] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */ +      elem_types[2] = LLVMArrayType(texture_type, +                                    PIPE_MAX_VERTEX_SAMPLERS); /* textures */        context_type = LLVMStructType(elem_types, Elements(elem_types), 0); @@ -108,7 +124,7 @@ init_globals(struct draw_llvm *llvm)                               llvm->target, context_type, 1);        LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, textures,                               llvm->target, context_type, -                             DRAW_JIT_CONTEXT_TEXTURES_INDEX); +                             DRAW_JIT_CTX_TEXTURES);        LP_CHECK_STRUCT_SIZE(struct draw_jit_context,                             llvm->target, context_type); @@ -290,7 +306,8 @@ generate_vs(struct draw_llvm *llvm,              LLVMBuilderRef builder,              LLVMValueRef (*outputs)[NUM_CHANNELS],              const LLVMValueRef (*inputs)[NUM_CHANNELS], -            LLVMValueRef context_ptr) +            LLVMValueRef context_ptr, +            struct lp_build_sampler_soa *sampler)  {     const struct tgsi_token *tokens = llvm->draw->vs.vertex_shader->state.tokens;     struct lp_type vs_type; @@ -318,7 +335,7 @@ generate_vs(struct draw_llvm *llvm,                       NULL /*pos*/,                       inputs,                       outputs, -                     NULL/*sampler*/, +                     sampler,                       &llvm->draw->vs.vertex_shader->info);  } @@ -641,6 +658,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)     const int max_vertices = 4;     LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];     void *code; +   struct lp_build_sampler_soa *sampler = 0;     arg_types[0] = llvm->context_ptr_type;           /* context */     arg_types[1] = llvm->vertex_header_ptr_type;     /* vertex_header */ @@ -688,6 +706,10 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)     step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0); +   /* code generated texture sampling */ +   sampler = draw_llvm_sampler_soa_create(variant->key.sampler, +                                          context_ptr); +  #if DEBUG_STORE     lp_build_printf(builder, "start = %d, end = %d, step = %d\n",                     start, end, step); @@ -729,7 +751,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)                    builder,                    outputs,                    ptr_aos, -                  context_ptr); +                  context_ptr, +                  sampler);        convert_to_aos(builder, io, outputs,                       draw->vs.vertex_shader->info.num_outputs, @@ -737,6 +760,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)     }     lp_build_loop_end_cond(builder, end, step, LLVMIntUGE, &lp_loop); +   sampler->destroy(sampler); +     LLVMBuildRetVoid(builder);     LLVMDisposeBuilder(builder); @@ -787,6 +812,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian     LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];     LLVMValueRef fetch_max;     void *code; +   struct lp_build_sampler_soa *sampler = 0;     arg_types[0] = llvm->context_ptr_type;               /* context */     arg_types[1] = llvm->vertex_header_ptr_type;         /* vertex_header */ @@ -833,6 +859,10 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian     step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0); +   /* code generated texture sampling */ +   sampler = draw_llvm_sampler_soa_create(variant->key.sampler, +                                          context_ptr); +     fetch_max = LLVMBuildSub(builder, fetch_count,                              LLVMConstInt(LLVMInt32Type(), 1, 0),                              "fetch_max"); @@ -884,7 +914,8 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian                    builder,                    outputs,                    ptr_aos, -                  context_ptr); +                  context_ptr, +                  sampler);        convert_to_aos(builder, io, outputs,                       draw->vs.vertex_shader->info.num_outputs, @@ -892,6 +923,8 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian     }     lp_build_loop_end_cond(builder, fetch_count, step, LLVMIntUGE, &lp_loop); +   sampler->destroy(sampler); +     LLVMBuildRetVoid(builder);     LLVMDisposeBuilder(builder); @@ -925,6 +958,8 @@ void  draw_llvm_make_variant_key(struct draw_llvm *llvm,                             struct draw_llvm_variant_key *key)  { +   unsigned i; +     memset(key, 0, sizeof(struct draw_llvm_variant_key));     key->nr_vertex_elements = llvm->draw->pt.nr_vertex_elements; @@ -936,6 +971,43 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm,     memcpy(&key->vs,            &llvm->draw->vs.vertex_shader->state,            sizeof(struct pipe_shader_state)); + +   for(i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; ++i) { +      struct draw_vertex_shader *shader = llvm->draw->vs.vertex_shader; +      if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i)) +         lp_sampler_static_state(&key->sampler[i], +                                 llvm->draw->sampler_views[i], +                                 llvm->draw->samplers[i]); +   } +} + +void +draw_llvm_set_mapped_texture(struct draw_context *draw, +                             unsigned sampler_idx, +                             uint32_t width, uint32_t height, uint32_t depth, +                             uint32_t last_level, +                             uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS], +                             uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS], +                             const void *data[DRAW_MAX_TEXTURE_LEVELS]) +{ +   unsigned j; +   struct draw_jit_texture *jit_tex; + +   assert(sampler_idx <= PIPE_MAX_VERTEX_SAMPLERS); + + +   jit_tex = &draw->llvm->jit_context.textures[sampler_idx]; + +   jit_tex->width = width; +   jit_tex->height = height; +   jit_tex->depth = depth; +   jit_tex->last_level = last_level; + +   for (j = 0; j <= last_level; j++) { +      jit_tex->data[j] = data[j]; +      jit_tex->row_stride[j] = row_stride[j]; +      jit_tex->img_stride[j] = img_stride[j]; +   }  }  void diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h index 1ef009b592..05446517c6 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.h +++ b/src/gallium/auxiliary/draw/draw_llvm.h @@ -25,12 +25,13 @@   *   **************************************************************************/ -#ifndef HAVE_LLVM_H -#define HAVE_LLVM_H +#ifndef DRAW_LLVM_H +#define DRAW_LLVM_H  #include "draw/draw_private.h"  #include "draw/draw_vs.h" +#include "gallivm/lp_bld_sample.h"  #include "pipe/p_context.h"  #include "util/u_simple_list.h" @@ -40,6 +41,8 @@  #include <llvm-c/Target.h>  #include <llvm-c/ExecutionEngine.h> +#define DRAW_MAX_TEXTURE_LEVELS 13  /* 4K x 4K for now */ +  struct draw_llvm;  struct llvm_vertex_shader; @@ -47,15 +50,22 @@ struct draw_jit_texture  {     uint32_t width;     uint32_t height; -   uint32_t stride; -   const void *data; +   uint32_t depth; +   uint32_t last_level; +   uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS]; +   uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS]; +   const void *data[DRAW_MAX_TEXTURE_LEVELS];  };  enum {     DRAW_JIT_TEXTURE_WIDTH = 0,     DRAW_JIT_TEXTURE_HEIGHT, -   DRAW_JIT_TEXTURE_STRIDE, -   DRAW_JIT_TEXTURE_DATA +   DRAW_JIT_TEXTURE_DEPTH, +   DRAW_JIT_TEXTURE_LAST_LEVEL, +   DRAW_JIT_TEXTURE_ROW_STRIDE, +   DRAW_JIT_TEXTURE_IMG_STRIDE, +   DRAW_JIT_TEXTURE_DATA, +   DRAW_JIT_TEXTURE_NUM_FIELDS  /* number of fields above */  };  enum { @@ -81,7 +91,7 @@ struct draw_jit_context     const float *gs_constants; -   struct draw_jit_texture textures[PIPE_MAX_SAMPLERS]; +   struct draw_jit_texture textures[PIPE_MAX_VERTEX_SAMPLERS];  }; @@ -91,10 +101,10 @@ struct draw_jit_context  #define draw_jit_context_gs_constants(_builder, _ptr) \     lp_build_struct_get(_builder, _ptr, 1, "gs_constants") -#define DRAW_JIT_CONTEXT_TEXTURES_INDEX 2 +#define DRAW_JIT_CTX_TEXTURES 2  #define draw_jit_context_textures(_builder, _ptr) \ -   lp_build_struct_get_ptr(_builder, _ptr, DRAW_JIT_CONTEXT_TEXTURES_INDEX, "textures") +   lp_build_struct_get_ptr(_builder, _ptr, DRAW_JIT_CTX_TEXTURES, "textures") @@ -142,6 +152,7 @@ struct draw_llvm_variant_key     struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];     unsigned                   nr_vertex_elements;     struct pipe_shader_state   vs; +   struct lp_sampler_static_state sampler[PIPE_MAX_VERTEX_SAMPLERS];  };  struct draw_llvm_variant_list_item @@ -221,4 +232,17 @@ draw_llvm_translate_from(LLVMBuilderRef builder,                           LLVMValueRef vbuffer,                           enum pipe_format from_format); +struct lp_build_sampler_soa * +draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state, +                             LLVMValueRef context_ptr); + +void +draw_llvm_set_mapped_texture(struct draw_context *draw, +                             unsigned sampler_idx, +                             uint32_t width, uint32_t height, uint32_t depth, +                             uint32_t last_level, +                             uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS], +                             uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS], +                             const void *data[DRAW_MAX_TEXTURE_LEVELS]); +  #endif diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c b/src/gallium/auxiliary/draw/draw_llvm_sample.c new file mode 100644 index 0000000000..2613224f75 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c @@ -0,0 +1,216 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Texture sampling code generation + * @author Jose Fonseca <jfonseca@vmware.com> + */ + +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "gallivm/lp_bld_debug.h" +#include "gallivm/lp_bld_type.h" +#include "gallivm/lp_bld_sample.h" +#include "gallivm/lp_bld_tgsi.h" + + +#include "util/u_cpu_detect.h" +#include "util/u_debug.h" +#include "util/u_memory.h" +#include "util/u_pointer.h" +#include "util/u_string.h" + +#include "draw_llvm.h" + + +/** + * This provides the bridge between the sampler state store in + * lp_jit_context and lp_jit_texture and the sampler code + * generator. It provides the texture layout information required by + * the texture sampler code generator in terms of the state stored in + * lp_jit_context and lp_jit_texture in runtime. + */ +struct draw_llvm_sampler_dynamic_state +{ +   struct lp_sampler_dynamic_state base; + +   const struct lp_sampler_static_state *static_state; + +   LLVMValueRef context_ptr; +}; + + +/** + * This is the bridge between our sampler and the TGSI translator. + */ +struct draw_llvm_sampler_soa +{ +   struct lp_build_sampler_soa base; + +   struct draw_llvm_sampler_dynamic_state dynamic_state; +}; + + +/** + * Fetch the specified member of the lp_jit_texture structure. + * \param emit_load  if TRUE, emit the LLVM load instruction to actually + *                   fetch the field's value.  Otherwise, just emit the + *                   GEP code to address the field. + * + * @sa http://llvm.org/docs/GetElementPtr.html + */ +static LLVMValueRef +draw_llvm_texture_member(const struct lp_sampler_dynamic_state *base, +                         LLVMBuilderRef builder, +                         unsigned unit, +                         unsigned member_index, +                         const char *member_name, +                         boolean emit_load) +{ +   struct draw_llvm_sampler_dynamic_state *state = +      (struct draw_llvm_sampler_dynamic_state *)base; +   LLVMValueRef indices[4]; +   LLVMValueRef ptr; +   LLVMValueRef res; + +   debug_assert(unit < PIPE_MAX_VERTEX_SAMPLERS); + +   /* context[0] */ +   indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0); +   /* context[0].textures */ +   indices[1] = LLVMConstInt(LLVMInt32Type(), DRAW_JIT_CTX_TEXTURES, 0); +   /* context[0].textures[unit] */ +   indices[2] = LLVMConstInt(LLVMInt32Type(), unit, 0); +   /* context[0].textures[unit].member */ +   indices[3] = LLVMConstInt(LLVMInt32Type(), member_index, 0); + +   ptr = LLVMBuildGEP(builder, state->context_ptr, indices, Elements(indices), ""); + +   if (emit_load) +      res = LLVMBuildLoad(builder, ptr, ""); +   else +      res = ptr; + +   lp_build_name(res, "context.texture%u.%s", unit, member_name); + +   return res; +} + + +/** + * Helper macro to instantiate the functions that generate the code to + * fetch the members of lp_jit_texture to fulfill the sampler code + * generator requests. + * + * This complexity is the price we have to pay to keep the texture + * sampler code generator a reusable module without dependencies to + * llvmpipe internals. + */ +#define DRAW_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load)  \ +   static LLVMValueRef \ +   draw_llvm_texture_##_name( const struct lp_sampler_dynamic_state *base, \ +                              LLVMBuilderRef builder,                   \ +                              unsigned unit)                            \ +   { \ +      return draw_llvm_texture_member(base, builder, unit, _index, #_name, _emit_load ); \ +   } + + +DRAW_LLVM_TEXTURE_MEMBER(width,      DRAW_JIT_TEXTURE_WIDTH, TRUE) +DRAW_LLVM_TEXTURE_MEMBER(height,     DRAW_JIT_TEXTURE_HEIGHT, TRUE) +DRAW_LLVM_TEXTURE_MEMBER(depth,      DRAW_JIT_TEXTURE_DEPTH, TRUE) +DRAW_LLVM_TEXTURE_MEMBER(last_level, DRAW_JIT_TEXTURE_LAST_LEVEL, TRUE) +DRAW_LLVM_TEXTURE_MEMBER(row_stride, DRAW_JIT_TEXTURE_ROW_STRIDE, FALSE) +DRAW_LLVM_TEXTURE_MEMBER(img_stride, DRAW_JIT_TEXTURE_IMG_STRIDE, FALSE) +DRAW_LLVM_TEXTURE_MEMBER(data_ptr,   DRAW_JIT_TEXTURE_DATA, FALSE) + + +static void +draw_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler) +{ +   FREE(sampler); +} + + +/** + * Fetch filtered values from texture. + * The 'texel' parameter returns four vectors corresponding to R, G, B, A. + */ +static void +draw_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base, +                                       LLVMBuilderRef builder, +                                       struct lp_type type, +                                       unsigned unit, +                                       unsigned num_coords, +                                       const LLVMValueRef *coords, +                                       const LLVMValueRef *ddx, +                                       const LLVMValueRef *ddy, +                                       LLVMValueRef lod_bias, /* optional */ +                                       LLVMValueRef explicit_lod, /* optional */ +                                       LLVMValueRef *texel) +{ +   struct draw_llvm_sampler_soa *sampler = (struct draw_llvm_sampler_soa *)base; + +   assert(unit < PIPE_MAX_VERTEX_SAMPLERS); + +   lp_build_sample_soa(builder, +                       &sampler->dynamic_state.static_state[unit], +                       &sampler->dynamic_state.base, +                       type, +                       unit, +                       num_coords, coords, +                       ddx, ddy, +                       lod_bias, explicit_lod, +                       texel); +} + + +struct lp_build_sampler_soa * +draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state, +                             LLVMValueRef context_ptr) +{ +   struct draw_llvm_sampler_soa *sampler; + +   sampler = CALLOC_STRUCT(draw_llvm_sampler_soa); +   if(!sampler) +      return NULL; + +   sampler->base.destroy = draw_llvm_sampler_soa_destroy; +   sampler->base.emit_fetch_texel = draw_llvm_sampler_soa_emit_fetch_texel; +   sampler->dynamic_state.base.width = draw_llvm_texture_width; +   sampler->dynamic_state.base.height = draw_llvm_texture_height; +   sampler->dynamic_state.base.depth = draw_llvm_texture_depth; +   sampler->dynamic_state.base.last_level = draw_llvm_texture_last_level; +   sampler->dynamic_state.base.row_stride = draw_llvm_texture_row_stride; +   sampler->dynamic_state.base.img_stride = draw_llvm_texture_img_stride; +   sampler->dynamic_state.base.data_ptr = draw_llvm_texture_data_ptr; +   sampler->dynamic_state.static_state = static_state; +   sampler->dynamic_state.context_ptr = context_ptr; + +   return &sampler->base; +} + diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 54944a7c67..8af885908e 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -48,6 +48,7 @@  #ifdef HAVE_LLVM  #include <llvm-c/ExecutionEngine.h> +struct draw_llvm;  #endif @@ -262,9 +263,15 @@ struct draw_context     unsigned instance_id;  #ifdef HAVE_LLVM +   struct draw_llvm *llvm;     LLVMExecutionEngineRef engine;  #endif +   struct pipe_sampler_view *sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; +   unsigned num_sampler_views; +   const struct pipe_sampler_state *samplers[PIPE_MAX_VERTEX_SAMPLERS]; +   unsigned num_samplers; +     void *driver_private;  }; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index d33969ac70..6aefbede59 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -392,9 +392,6 @@ static void llvm_middle_end_destroy( struct draw_pt_middle_end *middle )     if (fpme->post_vs)        draw_pt_post_vs_destroy( fpme->post_vs ); -   if (fpme->llvm) -      draw_llvm_destroy( fpme->llvm ); -     FREE(middle);  } @@ -436,7 +433,7 @@ draw_pt_fetch_pipeline_or_emit_llvm(struct draw_context *draw)     if (!fpme->so_emit)        goto fail; -   fpme->llvm = draw_llvm_create(draw); +   fpme->llvm = draw->llvm;     if (!fpme->llvm)        goto fail; diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 49b13f464a..edcab0f8d9 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -86,7 +86,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)     case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:        return PIPE_MAX_SAMPLERS;     case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: -      return 0; +      return PIPE_MAX_VERTEX_SAMPLERS;     case PIPE_CAP_MAX_COMBINED_SAMPLERS:        return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;     case PIPE_CAP_NPOT_TEXTURES: diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 2597fa8f71..fcb6e06123 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -641,7 +641,6 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,              /*               * XXX: Where should this be unmapped?               */ -              struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);              struct sw_winsys *winsys = screen->winsys;              jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt, @@ -658,6 +657,75 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,  /** + * Called during state validation when LP_NEW_SAMPLER_VIEW is set. + */ +void +lp_setup_set_vertex_sampler_views(struct lp_setup_context *setup, +                                  unsigned num, +                                  struct pipe_sampler_view **views) +{ +   unsigned i; +   uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS]; +   uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS]; +   const void *data[DRAW_MAX_TEXTURE_LEVELS]; +   struct lp_scene *scene; +   struct llvmpipe_context *lp; + +   LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); + +   assert(num <= PIPE_MAX_VERTEX_SAMPLERS); + +   scene = lp_setup_get_current_scene(setup); +   lp = llvmpipe_context(scene->pipe); + +   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { +      struct pipe_sampler_view *view = i < num ? views[i] : NULL; + +      if (view) { +         struct pipe_resource *tex = view->texture; +         struct llvmpipe_resource *lp_tex = llvmpipe_resource(tex); + +         /* We're referencing the texture's internal data, so save a +          * reference to it. +          */ +         pipe_resource_reference(&setup->vs.current_tex[i], tex); + +         if (!lp_tex->dt) { +            /* regular texture - setup array of mipmap level pointers */ +            int j; +            for (j = 0; j <= tex->last_level; j++) { +               data[j] = +                  llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ, +                                                 LP_TEX_LAYOUT_LINEAR); +               row_stride[j] = lp_tex->row_stride[j]; +               img_stride[j] = lp_tex->img_stride[j]; +            } +         } +         else { +            /* display target texture/surface */ +            /* +             * XXX: Where should this be unmapped? +             */ +            struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen); +            struct sw_winsys *winsys = screen->winsys; +            data[0] = winsys->displaytarget_map(winsys, lp_tex->dt, +                                                PIPE_TRANSFER_READ); +            row_stride[0] = lp_tex->row_stride[0]; +            img_stride[0] = lp_tex->img_stride[0]; +            assert(data[0]); +         } +         draw_set_mapped_texture(lp->draw, +                                 i, +                                 tex->width0, tex->height0, tex->depth0, +                                 tex->last_level, +                                 row_stride, img_stride, data); +      } +   } +} + + + +/**   * Is the given texture referenced by any scene?   * Note: we have to check all scenes including any scenes currently   * being rendered and the current scene being built. @@ -850,6 +918,9 @@ lp_setup_destroy( struct lp_setup_context *setup )     util_unreference_framebuffer_state(&setup->fb); +   for (i = 0; i < Elements(setup->vs.current_tex); i++) { +      pipe_resource_reference(&setup->vs.current_tex[i], NULL); +   }     for (i = 0; i < Elements(setup->fs.current_tex); i++) {        pipe_resource_reference(&setup->fs.current_tex[i], NULL);     } diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 6a0dc55129..fd2c927c2e 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -133,6 +133,11 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,                                      unsigned num,                                      struct pipe_sampler_view **views); +void +lp_setup_set_vertex_sampler_views(struct lp_setup_context *setup, +                                  unsigned num, +                                  struct pipe_sampler_view **views); +  unsigned  lp_setup_is_resource_referenced( const struct lp_setup_context *setup,                                  const struct pipe_resource *texture ); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 8f4e00f073..947d5efe2b 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -116,6 +116,10 @@ struct lp_setup_context        struct pipe_resource *current_tex[PIPE_MAX_SAMPLERS];     } fs; +   struct { +      struct pipe_resource *current_tex[PIPE_MAX_VERTEX_SAMPLERS]; +   } vs; +     /** fragment shader constants */     struct {        struct pipe_resource *current; diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index d20a5218d4..263b117494 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -188,10 +188,14 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )        lp_setup_set_fs_constants(llvmpipe->setup,                                   llvmpipe->constants[PIPE_SHADER_FRAGMENT][0]); -   if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW) -      lp_setup_set_fragment_sampler_views(llvmpipe->setup,  +   if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW) { +      lp_setup_set_fragment_sampler_views(llvmpipe->setup,                                            llvmpipe->num_fragment_sampler_views,                                            llvmpipe->fragment_sampler_views); +      lp_setup_set_vertex_sampler_views(llvmpipe->setup, +                                        llvmpipe->num_vertex_sampler_views, +                                        llvmpipe->vertex_sampler_views); +   }     llvmpipe->dirty = 0;  } diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c index e94065fb6a..0fea7f20a7 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c @@ -100,6 +100,10 @@ llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,     llvmpipe->num_vertex_samplers = num_samplers; +   draw_set_samplers(llvmpipe->draw, +                     llvmpipe->vertex_samplers, +                     llvmpipe->num_vertex_samplers); +     llvmpipe->dirty |= LP_NEW_SAMPLER;  } @@ -166,6 +170,10 @@ llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe,     llvmpipe->num_vertex_sampler_views = num; +   draw_set_sampler_views(llvmpipe->draw, +                          llvmpipe->vertex_sampler_views, +                          llvmpipe->num_vertex_sampler_views); +     llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;  } | 
