aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/draw
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h3
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c99
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.h16
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h10
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c7
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c4
10 files changed, 122 insertions, 31 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index 6caa62ab31b..4eb1919b871 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -364,9 +364,11 @@ draw_set_vertex_elements(struct draw_context *draw,
*/
void
draw_set_mapped_vertex_buffer(struct draw_context *draw,
- unsigned attr, const void *buffer)
+ unsigned attr, const void *buffer,
+ size_t size)
{
- draw->pt.user.vbuffer[attr] = buffer;
+ draw->pt.user.vbuffer[attr].map = buffer;
+ draw->pt.user.vbuffer[attr].size = size;
}
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index 94fac880c68..c7a40a1b1a2 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -215,7 +215,8 @@ void draw_set_indexes(struct draw_context *draw,
const void *elements, unsigned elem_size);
void draw_set_mapped_vertex_buffer(struct draw_context *draw,
- unsigned attr, const void *buffer);
+ unsigned attr, const void *buffer,
+ size_t size);
void
draw_set_mapped_constant_buffer(struct draw_context *draw,
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 8e2ab1e3006..24b7be31362 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -78,6 +78,44 @@ draw_gs_llvm_iface(const struct lp_build_tgsi_gs_iface *iface)
}
/**
+ * Create LLVM type for draw_vertex_buffer.
+ */
+static LLVMTypeRef
+create_jit_dvbuffer_type(struct gallivm_state *gallivm,
+ const char *struct_name)
+{
+ LLVMTargetDataRef target = gallivm->target;
+ LLVMTypeRef dvbuffer_type;
+ LLVMTypeRef elem_types[DRAW_JIT_DVBUFFER_NUM_FIELDS];
+ LLVMTypeRef int32_type = LLVMInt32TypeInContext(gallivm->context);
+
+ elem_types[DRAW_JIT_DVBUFFER_MAP] =
+ LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 8), 0);
+ elem_types[DRAW_JIT_DVBUFFER_SIZE] = int32_type;
+
+ dvbuffer_type = LLVMStructTypeInContext(gallivm->context, elem_types,
+ Elements(elem_types), 0);
+
+#if HAVE_LLVM < 0x0300
+ LLVMAddTypeName(gallivm->module, struct_name, dvbuffer_type);
+
+ /* Make sure the target's struct layout cache doesn't return
+ * stale/invalid data.
+ */
+ LLVMInvalidateStructLayout(gallivm->target, dvbuffer_type);
+#endif
+
+ LP_CHECK_MEMBER_OFFSET(struct draw_vertex_buffer, map,
+ target, dvbuffer_type,
+ DRAW_JIT_DVBUFFER_MAP);
+ LP_CHECK_MEMBER_OFFSET(struct draw_vertex_buffer, size,
+ target, dvbuffer_type,
+ DRAW_JIT_DVBUFFER_SIZE);
+
+ return dvbuffer_type;
+}
+
+/**
* Create LLVM type for struct draw_jit_texture
*/
static LLVMTypeRef
@@ -328,7 +366,8 @@ create_gs_jit_input_type(struct gallivm_state *gallivm)
* Create LLVM type for struct pipe_vertex_buffer
*/
static LLVMTypeRef
-create_jit_vertex_buffer_type(struct gallivm_state *gallivm, const char *struct_name)
+create_jit_vertex_buffer_type(struct gallivm_state *gallivm,
+ const char *struct_name)
{
LLVMTargetDataRef target = gallivm->target;
LLVMTypeRef elem_types[4];
@@ -337,7 +376,7 @@ create_jit_vertex_buffer_type(struct gallivm_state *gallivm, const char *struct_
elem_types[0] =
elem_types[1] = LLVMInt32TypeInContext(gallivm->context);
elem_types[2] =
- elem_types[3] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); /* vs_constants */
+ elem_types[3] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0);
vb_type = LLVMStructTypeInContext(gallivm->context, elem_types,
Elements(elem_types), 0);
@@ -422,7 +461,8 @@ static void
create_jit_types(struct draw_llvm_variant *variant)
{
struct gallivm_state *gallivm = variant->gallivm;
- LLVMTypeRef texture_type, sampler_type, context_type, buffer_type, vb_type;
+ LLVMTypeRef texture_type, sampler_type, context_type, buffer_type,
+ vb_type;
texture_type = create_jit_texture_type(gallivm, "texture");
sampler_type = create_jit_sampler_type(gallivm, "sampler");
@@ -431,9 +471,9 @@ create_jit_types(struct draw_llvm_variant *variant)
"draw_jit_context");
variant->context_ptr_type = LLVMPointerType(context_type, 0);
- buffer_type = LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 8), 0);
+ buffer_type = create_jit_dvbuffer_type(gallivm, "draw_vertex_buffer");
variant->buffer_ptr_type = LLVMPointerType(buffer_type, 0);
-
+
vb_type = create_jit_vertex_buffer_type(gallivm, "pipe_vertex_buffer");
variant->vb_ptr_type = LLVMPointerType(vb_type, 0);
}
@@ -631,7 +671,6 @@ generate_vs(struct draw_llvm_variant *variant,
}
}
-
static void
generate_fetch(struct gallivm_state *gallivm,
LLVMValueRef vbuffers_ptr,
@@ -641,7 +680,8 @@ generate_fetch(struct gallivm_state *gallivm,
LLVMValueRef index,
LLVMValueRef instance_id)
{
- const struct util_format_description *format_desc = util_format_description(velem->src_format);
+ const struct util_format_description *format_desc =
+ util_format_description(velem->src_format);
LLVMValueRef zero = LLVMConstNull(LLVMInt32TypeInContext(gallivm->context));
LLVMBuilderRef builder = gallivm->builder;
LLVMValueRef indices =
@@ -651,7 +691,14 @@ generate_fetch(struct gallivm_state *gallivm,
&indices, 1, "");
LLVMValueRef vb_stride = draw_jit_vbuffer_stride(gallivm, vbuf);
LLVMValueRef vb_buffer_offset = draw_jit_vbuffer_offset(gallivm, vbuf);
+ LLVMValueRef map_ptr = draw_jit_dvbuffer_map(gallivm, vbuffer_ptr);
+ LLVMValueRef buffer_size = draw_jit_dvbuffer_size(gallivm, vbuffer_ptr);
LLVMValueRef stride;
+ LLVMValueRef buffer_overflowed;
+ LLVMValueRef temp_ptr =
+ lp_build_alloca(gallivm,
+ lp_build_vec_type(gallivm, lp_float32_vec4_type()), "");
+ struct lp_build_if_state if_ctx;
if (velem->instance_divisor) {
/* array index = instance_id / instance_divisor */
@@ -662,8 +709,6 @@ generate_fetch(struct gallivm_state *gallivm,
stride = LLVMBuildMul(builder, vb_stride, index, "");
- vbuffer_ptr = LLVMBuildLoad(builder, vbuffer_ptr, "vbuffer");
-
stride = LLVMBuildAdd(builder, stride,
vb_buffer_offset,
"");
@@ -671,14 +716,36 @@ generate_fetch(struct gallivm_state *gallivm,
lp_build_const_int32(gallivm, velem->src_offset),
"");
-/* lp_build_printf(gallivm, "vbuf index = %d, stride is %d\n", indices, stride);*/
- vbuffer_ptr = LLVMBuildGEP(builder, vbuffer_ptr, &stride, 1, "");
+ buffer_overflowed = LLVMBuildICmp(builder, LLVMIntUGE,
+ stride, buffer_size,
+ "buffer_overflowed");
+ /*
+ lp_build_printf(gallivm, "vbuf index = %d, stride is %d\n", indices, stride);
+ lp_build_print_value(gallivm, " buffer size = ", buffer_size);
+ lp_build_print_value(gallivm, " buffer overflowed = ", buffer_overflowed);
+ */
+
+ lp_build_if(&if_ctx, gallivm, buffer_overflowed);
+ {
+ LLVMValueRef val =
+ lp_build_const_vec(gallivm, lp_float32_vec4_type(), 0);
+ LLVMBuildStore(builder, val, temp_ptr);
+ }
+ lp_build_else(&if_ctx);
+ {
+ LLVMValueRef val;
+ map_ptr = LLVMBuildGEP(builder, map_ptr, &stride, 1, "");
+
+ val = lp_build_fetch_rgba_aos(gallivm,
+ format_desc,
+ lp_float32_vec4_type(),
+ map_ptr,
+ zero, zero, zero);
+ LLVMBuildStore(builder, val, temp_ptr);
+ }
+ lp_build_endif(&if_ctx);
- *res = lp_build_fetch_rgba_aos(gallivm,
- format_desc,
- lp_float32_vec4_type(),
- vbuffer_ptr,
- zero, zero, zero);
+ *res = LLVMBuildLoad(builder, temp_ptr, "aos");
}
static void
diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h
index 5909fc10a2d..d517b290666 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.h
+++ b/src/gallium/auxiliary/draw/draw_llvm.h
@@ -173,6 +173,18 @@ enum {
#define draw_jit_vbuffer_offset(_gallivm, _ptr) \
lp_build_struct_get(_gallivm, _ptr, 1, "buffer_offset")
+enum {
+ DRAW_JIT_DVBUFFER_MAP = 0,
+ DRAW_JIT_DVBUFFER_SIZE,
+ DRAW_JIT_DVBUFFER_NUM_FIELDS /* number of fields above */
+};
+
+#define draw_jit_dvbuffer_map(_gallivm, _ptr) \
+ lp_build_struct_get(_gallivm, _ptr, DRAW_JIT_DVBUFFER_MAP, "map")
+
+#define draw_jit_dvbuffer_size(_gallivm, _ptr) \
+ lp_build_struct_get(_gallivm, _ptr, DRAW_JIT_DVBUFFER_SIZE, "size")
+
/**
* This structure is passed directly to the generated geometry shader.
@@ -246,7 +258,7 @@ enum {
typedef int
(*draw_jit_vert_func)(struct draw_jit_context *context,
struct vertex_header *io,
- const char *vbuffers[PIPE_MAX_ATTRIBS],
+ const struct draw_vertex_buffer vbuffers[PIPE_MAX_ATTRIBS],
unsigned start,
unsigned count,
unsigned stride,
@@ -257,7 +269,7 @@ typedef int
typedef int
(*draw_jit_vert_func_elts)(struct draw_jit_context *context,
struct vertex_header *io,
- const char *vbuffers[PIPE_MAX_ATTRIBS],
+ const struct draw_vertex_buffer vbuffers[PIPE_MAX_ATTRIBS],
const unsigned *fetch_elts,
unsigned fetch_count,
unsigned stride,
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 25a8ae61498..84344c36773 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -67,6 +67,14 @@ struct draw_pt_front_end;
/**
+ * Represents the mapped vertex buffer.
+ */
+struct draw_vertex_buffer {
+ const void *map;
+ size_t size;
+};
+
+/**
* Basic vertex info.
* Carry some useful information around with the vertices in the prim pipe.
*/
@@ -183,7 +191,7 @@ struct draw_context
unsigned max_index;
/** vertex arrays */
- const void *vbuffer[PIPE_MAX_ATTRIBS];
+ struct draw_vertex_buffer vbuffer[PIPE_MAX_ATTRIBS];
/** constant buffers (for vertex/geometry shader) */
const void *vs_constants[PIPE_MAX_CONSTANT_BUFFERS];
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index 602d076dce2..a797d65de8c 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -282,7 +282,7 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
for (j = 0; j < draw->pt.nr_vertex_elements; j++) {
uint buf = draw->pt.vertex_element[j].vertex_buffer_index;
- ubyte *ptr = (ubyte *) draw->pt.user.vbuffer[buf];
+ ubyte *ptr = (ubyte *) draw->pt.user.vbuffer[buf].map;
if (draw->pt.vertex_element[j].instance_divisor) {
ii = draw->instance_id / draw->pt.vertex_element[j].instance_divisor;
@@ -524,11 +524,12 @@ draw_vbo(struct draw_context *draw,
}
debug_printf("Buffers:\n");
for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
- debug_printf(" %u: stride=%u offset=%u ptr=%p\n",
+ debug_printf(" %u: stride=%u offset=%u size=%d ptr=%p\n",
i,
draw->pt.vertex_buffer[i].stride,
draw->pt.vertex_buffer[i].buffer_offset,
- draw->pt.user.vbuffer[i]);
+ draw->pt.user.vbuffer[i].size,
+ draw->pt.user.vbuffer[i].map);
}
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c
index 9fab7b681fb..3740deab5a8 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c
@@ -159,7 +159,7 @@ draw_pt_fetch_run(struct pt_fetch *fetch,
for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
translate->set_buffer(translate,
i,
- ((char *)draw->pt.user.vbuffer[i] +
+ ((char *)draw->pt.user.vbuffer[i].map +
draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride,
draw->pt.max_index);
@@ -186,7 +186,7 @@ draw_pt_fetch_run_linear(struct pt_fetch *fetch,
for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
translate->set_buffer(translate,
i,
- ((char *)draw->pt.user.vbuffer[i] +
+ ((char *)draw->pt.user.vbuffer[i].map +
draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride,
draw->pt.max_index);
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index f30db1386cc..dc6decba70e 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -169,7 +169,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
feme->translate->set_buffer(feme->translate,
i,
- ((char *)draw->pt.user.vbuffer[i] +
+ ((char *)draw->pt.user.vbuffer[i].map +
draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride,
draw->pt.max_index);
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
index 870b23bbf58..d30cd412ef6 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
@@ -159,7 +159,7 @@ fse_prepare(struct draw_pt_middle_end *middle,
for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
fse->active->set_buffer( fse->active,
i,
- ((const ubyte *) draw->pt.user.vbuffer[i] +
+ ((const ubyte *) draw->pt.user.vbuffer[i].map +
draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride,
draw->pt.max_index );
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 1924c7351b2..bc99c169deb 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
@@ -348,7 +348,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle,
if (fetch_info->linear)
clipped = fpme->current_variant->jit_func( &fpme->llvm->jit_context,
llvm_vert_info.verts,
- (const char **)draw->pt.user.vbuffer,
+ draw->pt.user.vbuffer,
fetch_info->start,
fetch_info->count,
fpme->vertex_size,
@@ -357,7 +357,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle,
else
clipped = fpme->current_variant->jit_func_elts( &fpme->llvm->jit_context,
llvm_vert_info.verts,
- (const char **)draw->pt.user.vbuffer,
+ draw->pt.user.vbuffer,
fetch_info->elts,
fetch_info->count,
fpme->vertex_size,