draw: add vs/gs images support
authorDave Airlie <airlied@redhat.com>
Sat, 20 Jul 2019 04:26:48 +0000 (14:26 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 27 Aug 2019 02:30:01 +0000 (12:30 +1000)
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
src/gallium/auxiliary/draw/draw_context.c
src/gallium/auxiliary/draw/draw_context.h
src/gallium/auxiliary/draw/draw_gs.c
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/draw/draw_llvm.h
src/gallium/auxiliary/draw/draw_llvm_sample.c
src/gallium/auxiliary/draw/draw_private.h
src/gallium/auxiliary/draw/draw_vs_llvm.c

index 74436f98016e689212050135e44aee92fa49cac5..9de40d76221b4451899becabc5b8c05fd20e2fcd 100644 (file)
@@ -1033,6 +1033,27 @@ draw_set_samplers(struct draw_context *draw,
 #endif
 }
 
+void
+draw_set_images(struct draw_context *draw,
+                enum pipe_shader_type shader_stage,
+                struct pipe_image_view *views,
+                unsigned num)
+{
+   unsigned i;
+
+   debug_assert(shader_stage < PIPE_SHADER_TYPES);
+   debug_assert(num <= PIPE_MAX_SHADER_IMAGES);
+
+   draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
+
+   for (i = 0; i < num; ++i)
+      draw->images[shader_stage][i] = &views[i];
+   for (i = num; i < draw->num_sampler_views[shader_stage]; ++i)
+      draw->images[shader_stage][i] = NULL;
+
+   draw->num_images[shader_stage] = num;
+}
+
 void
 draw_set_mapped_texture(struct draw_context *draw,
                         enum pipe_shader_type shader_stage,
@@ -1055,6 +1076,26 @@ draw_set_mapped_texture(struct draw_context *draw,
 #endif
 }
 
+void
+draw_set_mapped_image(struct draw_context *draw,
+                      enum pipe_shader_type shader_stage,
+                      unsigned idx,
+                      uint32_t width, uint32_t height, uint32_t depth,
+                      const void *base_ptr,
+                      uint32_t row_stride,
+                      uint32_t img_stride)
+{
+#ifdef HAVE_LLVM
+   if (draw->llvm)
+      draw_llvm_set_mapped_image(draw,
+                                 shader_stage,
+                                 idx,
+                                 width, height, depth,
+                                 base_ptr,
+                                 row_stride, img_stride);
+#endif
+}
+
 /**
  * XXX: Results for PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS because there are two
  * different ways of setting textures, and drivers typically only support one.
index 868d0195a02b0d4d4afc6859da838f2469858d80..69138690de7b2fc3347bf9baf53b40f5b79c1607 100644 (file)
@@ -176,6 +176,12 @@ draw_set_samplers(struct draw_context *draw,
                   struct pipe_sampler_state **samplers,
                   unsigned num);
 
+void
+draw_set_images(struct draw_context *draw,
+                enum pipe_shader_type shader_stage,
+                struct pipe_image_view *images,
+                unsigned num);
+
 void
 draw_set_mapped_texture(struct draw_context *draw,
                         enum pipe_shader_type shader_stage,
@@ -187,6 +193,14 @@ draw_set_mapped_texture(struct draw_context *draw,
                         uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS],
                         uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]);
 
+void
+draw_set_mapped_image(struct draw_context *draw,
+                      enum pipe_shader_type shader_stage,
+                      unsigned idx,
+                      uint32_t width, uint32_t height, uint32_t depth,
+                      const void *base_ptr,
+                      uint32_t row_stride,
+                      uint32_t img_stride);
 
 /*
  * Vertex shader functions
index c752163ee05a7c5dce991188fcb09eee700c7ed1..a75fe671777d2fde6ca5f495eccffcd243dd8d51 100644 (file)
@@ -883,7 +883,8 @@ draw_create_geometry_shader(struct draw_context *draw,
       llvm_gs->variant_key_size =
          draw_gs_llvm_variant_key_size(
             MAX2(gs->info.file_max[TGSI_FILE_SAMPLER]+1,
-                 gs->info.file_max[TGSI_FILE_SAMPLER_VIEW]+1));
+                 gs->info.file_max[TGSI_FILE_SAMPLER_VIEW]+1),
+            gs->info.file_max[TGSI_FILE_IMAGE]+1);
    } else
 #endif
    {
index 7b5280e3175b22dde483cd91231e2dbc0f1a10c8..0416e002cd7bb403d80d66e6e8d22b418352947b 100644 (file)
@@ -681,6 +681,7 @@ generate_vs(struct draw_llvm_variant *variant,
             const struct lp_bld_tgsi_system_values *system_values,
             LLVMValueRef context_ptr,
             const struct lp_build_sampler_soa *draw_sampler,
+            const struct lp_build_image_soa *draw_image,
             boolean clamp_vertex_color,
             struct lp_build_mask_context *bld_mask)
 {
@@ -709,6 +710,7 @@ generate_vs(struct draw_llvm_variant *variant,
    params.info = &llvm->draw->vs.vertex_shader->info;
    params.ssbo_ptr = ssbos_ptr;
    params.ssbo_sizes_ptr = num_ssbos_ptr;
+   params.image = draw_image;
 
    lp_build_tgsi_soa(variant->gallivm,
                      tokens,
@@ -1635,6 +1637,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
    const int vector_length = lp_native_vector_width / 32;
    LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS];
    struct lp_build_sampler_soa *sampler = 0;
+   struct lp_build_image_soa *image = NULL;
    LLVMValueRef ret, clipmask_bool_ptr;
    struct draw_llvm_variant_key *key = &variant->key;
    /* If geometry shader is present we need to skip both the viewport
@@ -1750,6 +1753,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
    /* code generated texture sampling */
    sampler = draw_llvm_sampler_soa_create(draw_llvm_variant_key_samplers(key));
 
+   image = draw_llvm_image_soa_create(draw_llvm_variant_key_images(key));
+
    step = lp_build_const_int32(gallivm, vector_length);
 
    ind_vec = blduivec.undef;
@@ -1994,6 +1999,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
                   &system_values,
                   context_ptr,
                   sampler,
+                  image,
                   key->clamp_vertex_color,
                   &mask);
 
@@ -2040,6 +2046,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
    lp_build_loop_end_cond(&lp_loop, count, step, LLVMIntUGE);
 
    sampler->destroy(sampler);
+   image->destroy(image);
 
    /* return clipping boolean value for function */
    ret = clipmask_booli8(gallivm, vs_type, clipmask_bool_ptr,
@@ -2057,6 +2064,7 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store)
    unsigned i;
    struct draw_llvm_variant_key *key;
    struct draw_sampler_static_state *draw_sampler;
+   struct draw_image_static_state *draw_image;
 
    key = (struct draw_llvm_variant_key *)store;
 
@@ -2089,6 +2097,8 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store)
       key->nr_sampler_views = key->nr_samplers;
    }
 
+   key->nr_images = llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_IMAGE] + 1;
+
    /* Presumably all variants of the shader should have the same
     * number of vertex elements - ie the number of shader inputs.
     * NOTE: we NEED to store the needed number of needed inputs
@@ -2127,6 +2137,13 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store)
                                       llvm->draw->sampler_views[PIPE_SHADER_VERTEX][i]);
    }
 
+   draw_image = draw_llvm_variant_key_images(key);
+   memset(draw_image, 0,
+          key->nr_images * sizeof *draw_image);
+   for (i = 0; i < key->nr_images; i++) {
+      lp_sampler_static_texture_state_image(&draw_image[i].image_state,
+                                            llvm->draw->images[PIPE_SHADER_VERTEX][i]);
+   }
    return key;
 }
 
@@ -2136,7 +2153,7 @@ draw_llvm_dump_variant_key(struct draw_llvm_variant_key *key)
 {
    unsigned i;
    struct draw_sampler_static_state *sampler = draw_llvm_variant_key_samplers(key);
-
+   struct draw_image_static_state *image = draw_llvm_variant_key_images(key);
    debug_printf("clamp_vertex_color = %u\n", key->clamp_vertex_color);
    debug_printf("clip_xy = %u\n", key->clip_xy);
    debug_printf("clip_z = %u\n", key->clip_z);
@@ -2157,6 +2174,9 @@ draw_llvm_dump_variant_key(struct draw_llvm_variant_key *key)
    for (i = 0 ; i < key->nr_sampler_views; i++) {
       debug_printf("sampler[%i].src_format = %s\n", i, util_format_name(sampler[i].texture_state.format));
    }
+
+   for (i = 0 ; i < key->nr_images; i++)
+      debug_printf("images[%i].format = %s\n", i, util_format_name(image[i].image_state.format));
 }
 
 
@@ -2204,6 +2224,42 @@ draw_llvm_set_mapped_texture(struct draw_context *draw,
    }
 }
 
+void
+draw_llvm_set_mapped_image(struct draw_context *draw,
+                           enum pipe_shader_type shader_stage,
+                           unsigned idx,
+                           uint32_t width, uint32_t height, uint32_t depth,
+                           const void *base_ptr,
+                           uint32_t row_stride,
+                           uint32_t img_stride)
+{
+   struct draw_jit_image *jit_image;
+
+   assert(shader_stage == PIPE_SHADER_VERTEX ||
+          shader_stage == PIPE_SHADER_GEOMETRY);
+
+   if (shader_stage == PIPE_SHADER_VERTEX) {
+      assert(idx < ARRAY_SIZE(draw->llvm->jit_context.images));
+
+      jit_image = &draw->llvm->jit_context.images[idx];
+   } else if (shader_stage == PIPE_SHADER_GEOMETRY) {
+      assert(idx < ARRAY_SIZE(draw->llvm->gs_jit_context.images));
+
+      jit_image = &draw->llvm->gs_jit_context.images[idx];
+   } else {
+      assert(0);
+      return;
+   }
+
+   jit_image->width = width;
+   jit_image->height = height;
+   jit_image->depth = depth;
+   jit_image->base = base_ptr;
+
+   jit_image->row_stride = row_stride;
+   jit_image->img_stride = img_stride;
+}
+
 
 void
 draw_llvm_set_sampler_state(struct draw_context *draw, 
@@ -2331,6 +2387,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
    LLVMBuilderRef builder;
    LLVMValueRef io_ptr, input_array, num_prims, mask_val;
    struct lp_build_sampler_soa *sampler = 0;
+   struct lp_build_image_soa *image = NULL;
    struct lp_build_context bld;
    struct lp_bld_tgsi_system_values system_values;
    char func_name[64];
@@ -2427,7 +2484,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
 
    /* code generated texture sampling */
    sampler = draw_llvm_sampler_soa_create(variant->key.samplers);
-
+   image = draw_llvm_image_soa_create(draw_gs_llvm_variant_key_images(&variant->key));
    mask_val = generate_mask_value(variant, gs_type);
    lp_build_mask_begin(&mask, gallivm, gs_type, mask_val);
 
@@ -2454,6 +2511,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
    params.gs_iface = (const struct lp_build_tgsi_gs_iface *)&gs_iface;
    params.ssbo_ptr = ssbos_ptr;
    params.ssbo_sizes_ptr = num_ssbos_ptr;
+   params.image = image;
 
    lp_build_tgsi_soa(variant->gallivm,
                      tokens,
@@ -2461,6 +2519,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
                      outputs);
 
    sampler->destroy(sampler);
+   image->destroy(image);
 
    lp_build_mask_end(&mask);
 
@@ -2545,6 +2604,7 @@ draw_gs_llvm_make_variant_key(struct draw_llvm *llvm, char *store)
    unsigned i;
    struct draw_gs_llvm_variant_key *key;
    struct draw_sampler_static_state *draw_sampler;
+   struct draw_image_static_state *draw_image;
 
    key = (struct draw_gs_llvm_variant_key *)store;
 
@@ -2565,6 +2625,8 @@ draw_gs_llvm_make_variant_key(struct draw_llvm *llvm, char *store)
       key->nr_sampler_views = key->nr_samplers;
    }
 
+   key->nr_images = llvm->draw->gs.geometry_shader->info.file_max[TGSI_FILE_IMAGE] + 1;
+
    draw_sampler = key->samplers;
 
    memset(draw_sampler, 0, MAX2(key->nr_samplers, key->nr_sampler_views) * sizeof *draw_sampler);
@@ -2578,6 +2640,13 @@ draw_gs_llvm_make_variant_key(struct draw_llvm *llvm, char *store)
                                       llvm->draw->sampler_views[PIPE_SHADER_GEOMETRY][i]);
    }
 
+   draw_image = draw_gs_llvm_variant_key_images(key);
+   memset(draw_image, 0,
+          key->nr_images * sizeof *draw_image);
+   for (i = 0; i < key->nr_images; i++) {
+      lp_sampler_static_texture_state_image(&draw_image[i].image_state,
+                                            llvm->draw->images[PIPE_SHADER_GEOMETRY][i]);
+   }
    return key;
 }
 
@@ -2586,9 +2655,13 @@ draw_gs_llvm_dump_variant_key(struct draw_gs_llvm_variant_key *key)
 {
    unsigned i;
    struct draw_sampler_static_state *sampler = key->samplers;
-
+   struct draw_image_static_state *image = draw_gs_llvm_variant_key_images(key);
    for (i = 0 ; i < key->nr_sampler_views; i++) {
       debug_printf("sampler[%i].src_format = %s\n", i,
                    util_format_name(sampler[i].texture_state.format));
    }
+
+   for (i = 0 ; i < key->nr_images; i++)
+      debug_printf("images[%i].format = %s\n", i, util_format_name(image[i].image_state.format));
+
 }
index 9507bd87bb63944e4433d13aa3aaee50dfb9b1b1..914f783fd000209b9715a103528ce9548d9d0ec1 100644 (file)
@@ -69,6 +69,11 @@ struct draw_sampler_static_state
    struct lp_static_texture_state texture_state;
 };
 
+struct draw_image_static_state
+{
+   struct lp_static_texture_state image_state;
+};
+
 
 struct draw_jit_sampler
 {
@@ -340,6 +345,7 @@ struct draw_llvm_variant_key
    unsigned nr_vertex_elements:8;
    unsigned nr_samplers:8;
    unsigned nr_sampler_views:8;
+   unsigned nr_images:8;
    unsigned clamp_vertex_color:1;
    unsigned clip_xy:1;
    unsigned clip_z:1;
@@ -359,42 +365,50 @@ struct draw_llvm_variant_key
    /* Followed by variable number of samplers:
     */
 /*   struct draw_sampler_static_state sampler; */
+   /* Followed by variable number of images
+    */
 };
 
 struct draw_gs_llvm_variant_key
 {
    unsigned nr_samplers:8;
    unsigned nr_sampler_views:8;
+   unsigned nr_images:8;
    unsigned num_outputs:8;
    /* note padding here - must use memset */
 
    struct draw_sampler_static_state samplers[1];
+   /* Followed by variable number of images.*/
 };
 
 #define DRAW_LLVM_MAX_VARIANT_KEY_SIZE \
    (sizeof(struct draw_llvm_variant_key) +     \
     PIPE_MAX_SHADER_SAMPLER_VIEWS * sizeof(struct draw_sampler_static_state) + \
+    PIPE_MAX_SHADER_IMAGES * sizeof(struct draw_image_static_state) + \
     (PIPE_MAX_ATTRIBS-1) * sizeof(struct pipe_vertex_element))
 
 #define DRAW_GS_LLVM_MAX_VARIANT_KEY_SIZE \
    (sizeof(struct draw_gs_llvm_variant_key) +  \
+    PIPE_MAX_SHADER_IMAGES * sizeof(struct draw_image_static_state) + \
     PIPE_MAX_SHADER_SAMPLER_VIEWS * sizeof(struct draw_sampler_static_state))
 
 
 static inline size_t
 draw_llvm_variant_key_size(unsigned nr_vertex_elements,
-                           unsigned nr_samplers)
+                           unsigned nr_samplers, unsigned nr_images)
 {
    return (sizeof(struct draw_llvm_variant_key) +
            nr_samplers * sizeof(struct draw_sampler_static_state) +
+           nr_images * sizeof(struct draw_image_static_state) +
            (nr_vertex_elements - 1) * sizeof(struct pipe_vertex_element));
 }
 
 
 static inline size_t
-draw_gs_llvm_variant_key_size(unsigned nr_samplers)
+draw_gs_llvm_variant_key_size(unsigned nr_samplers, unsigned nr_images)
 {
    return (sizeof(struct draw_gs_llvm_variant_key) +
+           (nr_images) * sizeof(struct draw_sampler_static_state) +
            (nr_samplers - 1) * sizeof(struct draw_sampler_static_state));
 }
 
@@ -406,6 +420,21 @@ draw_llvm_variant_key_samplers(struct draw_llvm_variant_key *key)
       &key->vertex_element[key->nr_vertex_elements];
 }
 
+static inline struct draw_image_static_state *
+draw_llvm_variant_key_images(struct draw_llvm_variant_key *key)
+{
+   struct draw_sampler_static_state *samplers = (struct draw_sampler_static_state *)
+      (&key->vertex_element[key->nr_vertex_elements]);
+   return (struct draw_image_static_state *)
+      &samplers[key->nr_samplers];
+}
+
+static inline struct draw_image_static_state *
+draw_gs_llvm_variant_key_images(struct draw_gs_llvm_variant_key *key)
+{
+   return (struct draw_image_static_state *)
+      &key->samplers[key->nr_samplers];
+}
 
 struct draw_llvm_variant_list_item
 {
@@ -558,6 +587,9 @@ draw_gs_llvm_dump_variant_key(struct draw_gs_llvm_variant_key *key);
 struct lp_build_sampler_soa *
 draw_llvm_sampler_soa_create(const struct draw_sampler_static_state *static_state);
 
+struct lp_build_image_soa *
+draw_llvm_image_soa_create(const struct draw_image_static_state *static_state);
+
 void
 draw_llvm_set_sampler_state(struct draw_context *draw,
                             enum pipe_shader_type shader_stage);
@@ -573,4 +605,12 @@ draw_llvm_set_mapped_texture(struct draw_context *draw,
                              uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS],
                              uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]);
 
+void
+draw_llvm_set_mapped_image(struct draw_context *draw,
+                           enum pipe_shader_type shader_stage,
+                           unsigned idx,
+                           uint32_t width, uint32_t height, uint32_t depth,
+                           const void *base_ptr,
+                           uint32_t row_stride,
+                           uint32_t img_stride);
 #endif
index 2671ff0fc4b93dacfcbe83744a6dd736c405c795..9d7114a9a200e71386d027012b02be595c6293fb 100644 (file)
@@ -72,6 +72,19 @@ struct draw_llvm_sampler_soa
    struct draw_llvm_sampler_dynamic_state dynamic_state;
 };
 
+struct draw_llvm_image_dynamic_state
+{
+   struct lp_sampler_dynamic_state base;
+
+   const struct draw_image_static_state *static_state;
+};
+
+struct draw_llvm_image_soa
+{
+   struct lp_build_image_soa base;
+
+   struct draw_llvm_image_dynamic_state dynamic_state;
+};
 
 /**
  * Fetch the specified member of the lp_jit_texture structure.
@@ -164,6 +177,50 @@ draw_llvm_sampler_member(const struct lp_sampler_dynamic_state *base,
    return res;
 }
 
+/**
+ * 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_image_member(const struct lp_sampler_dynamic_state *base,
+                       struct gallivm_state *gallivm,
+                       LLVMValueRef context_ptr,
+                       unsigned image_unit,
+                       unsigned member_index,
+                       const char *member_name,
+                       boolean emit_load)
+{
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMValueRef indices[4];
+   LLVMValueRef ptr;
+   LLVMValueRef res;
+
+   debug_assert(image_unit < PIPE_MAX_SHADER_IMAGES);
+
+   /* context[0] */
+   indices[0] = lp_build_const_int32(gallivm, 0);
+   /* context[0].textures */
+   indices[1] = lp_build_const_int32(gallivm, DRAW_JIT_CTX_IMAGES);
+   /* context[0].textures[unit] */
+   indices[2] = lp_build_const_int32(gallivm, image_unit);
+   /* context[0].textures[unit].member */
+   indices[3] = lp_build_const_int32(gallivm, member_index);
+
+   ptr = LLVMBuildGEP(builder, context_ptr, indices, ARRAY_SIZE(indices), "");
+
+   if (emit_load)
+      res = LLVMBuildLoad(builder, ptr, "");
+   else
+      res = ptr;
+
+   lp_build_name(res, "context.image%u.%s", image_unit, member_name);
+
+   return res;
+}
 
 /**
  * Helper macro to instantiate the functions that generate the code to
@@ -214,6 +271,24 @@ DRAW_LLVM_SAMPLER_MEMBER(max_lod,    DRAW_JIT_SAMPLER_MAX_LOD, TRUE)
 DRAW_LLVM_SAMPLER_MEMBER(lod_bias,   DRAW_JIT_SAMPLER_LOD_BIAS, TRUE)
 DRAW_LLVM_SAMPLER_MEMBER(border_color, DRAW_JIT_SAMPLER_BORDER_COLOR, FALSE)
 
+#define DRAW_LLVM_IMAGE_MEMBER(_name, _index, _emit_load)  \
+   static LLVMValueRef \
+   draw_llvm_image_##_name( const struct lp_sampler_dynamic_state *base, \
+                              struct gallivm_state *gallivm,               \
+                              LLVMValueRef context_ptr,                    \
+                              unsigned image_unit)                       \
+   { \
+      return draw_llvm_image_member(base, gallivm, context_ptr, \
+                                      image_unit, _index, #_name, _emit_load ); \
+   }
+
+
+DRAW_LLVM_IMAGE_MEMBER(width,      DRAW_JIT_IMAGE_WIDTH, TRUE)
+DRAW_LLVM_IMAGE_MEMBER(height,     DRAW_JIT_IMAGE_HEIGHT, TRUE)
+DRAW_LLVM_IMAGE_MEMBER(depth,      DRAW_JIT_IMAGE_DEPTH, TRUE)
+DRAW_LLVM_IMAGE_MEMBER(base_ptr,   DRAW_JIT_IMAGE_BASE, TRUE)
+DRAW_LLVM_IMAGE_MEMBER(row_stride, DRAW_JIT_IMAGE_ROW_STRIDE, TRUE)
+DRAW_LLVM_IMAGE_MEMBER(img_stride, DRAW_JIT_IMAGE_IMG_STRIDE, TRUE)
 
 static void
 draw_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
@@ -293,3 +368,64 @@ draw_llvm_sampler_soa_create(const struct draw_sampler_static_state *static_stat
    return &sampler->base;
 }
 
+static void
+draw_llvm_image_soa_emit_op(const struct lp_build_image_soa *base,
+                            struct gallivm_state *gallivm,
+                            const struct lp_img_params *params)
+{
+   struct draw_llvm_image_soa *image = (struct draw_llvm_image_soa *)base;
+   unsigned image_index = params->image_index;
+   assert(image_index < PIPE_MAX_SHADER_IMAGES);
+
+   lp_build_img_op_soa(&image->dynamic_state.static_state[image_index].image_state,
+                       &image->dynamic_state.base,
+                       gallivm, params);
+}
+/**
+ * Fetch the texture size.
+ */
+static void
+draw_llvm_image_soa_emit_size_query(const struct lp_build_image_soa *base,
+                                    struct gallivm_state *gallivm,
+                                    const struct lp_sampler_size_query_params *params)
+{
+   struct draw_llvm_image_soa *image = (struct draw_llvm_image_soa *)base;
+
+   assert(params->texture_unit < PIPE_MAX_SHADER_IMAGES);
+
+   lp_build_size_query_soa(gallivm,
+                           &image->dynamic_state.static_state[params->texture_unit].image_state,
+                           &image->dynamic_state.base,
+                           params);
+}
+static void
+draw_llvm_image_soa_destroy(struct lp_build_image_soa *image)
+{
+   FREE(image);
+}
+
+struct lp_build_image_soa *
+draw_llvm_image_soa_create(const struct draw_image_static_state *static_state)
+{
+   struct draw_llvm_image_soa *image;
+
+   image = CALLOC_STRUCT(draw_llvm_image_soa);
+   if (!image)
+      return NULL;
+
+   image->base.destroy = draw_llvm_image_soa_destroy;
+   image->base.emit_op = draw_llvm_image_soa_emit_op;
+   image->base.emit_size_query = draw_llvm_image_soa_emit_size_query;
+
+   image->dynamic_state.base.width = draw_llvm_image_width;
+   image->dynamic_state.base.height = draw_llvm_image_height;
+
+   image->dynamic_state.base.depth = draw_llvm_image_depth;
+   image->dynamic_state.base.base_ptr = draw_llvm_image_base_ptr;
+   image->dynamic_state.base.row_stride = draw_llvm_image_row_stride;
+   image->dynamic_state.base.img_stride = draw_llvm_image_img_stride;
+
+   image->dynamic_state.static_state = static_state;
+
+   return &image->base;
+}
index 0b236912bef2594c5eea7d6581bf6366c61c18c9..9be5f94db806027117a27bda1a88da4276c0fb9e 100644 (file)
@@ -342,6 +342,9 @@ struct draw_context
    const struct pipe_sampler_state *samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
    unsigned num_samplers[PIPE_SHADER_TYPES];
 
+   struct pipe_image_view *images[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
+   unsigned num_images[PIPE_SHADER_TYPES];
+
    struct pipe_query_data_pipeline_statistics statistics;
    boolean collect_statistics;
 
index 15486f8ffa8a778f34f336bb01ceeb401afc867c..04484ff13b821344046ead966a493b1819478f9a 100644 (file)
@@ -103,7 +103,8 @@ draw_create_vs_llvm(struct draw_context *draw,
       draw_llvm_variant_key_size(
          vs->base.info.file_max[TGSI_FILE_INPUT]+1,
          MAX2(vs->base.info.file_max[TGSI_FILE_SAMPLER]+1,
-              vs->base.info.file_max[TGSI_FILE_SAMPLER_VIEW]+1));
+              vs->base.info.file_max[TGSI_FILE_SAMPLER_VIEW]+1),
+         vs->base.info.file_max[TGSI_FILE_IMAGE]+1);
 
    vs->base.state.stream_output = state->stream_output;
    vs->base.draw = draw;