summaryrefslogtreecommitdiff
path: root/lib/mesa/src/gallium/auxiliary/draw
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2021-07-22 10:17:30 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2021-07-22 10:17:30 +0000
commitca11beabae33eb59fb981b8adf50b1d47a2a98f0 (patch)
tree3e4691a396e6e54cd54224a190663d5cf976625b /lib/mesa/src/gallium/auxiliary/draw
parent27c8a50e8bbde7d28b1fc46d715a4c469e24f2c4 (diff)
Import Mesa 21.1.5
Diffstat (limited to 'lib/mesa/src/gallium/auxiliary/draw')
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_cliptest_tmp.h27
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_gs.c181
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_gs.h8
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_llvm_sample.c91
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_pipe.c4
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_pipe.h1
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_pipe_cull.c131
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_pipe_offset.c6
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_pipe_pstipple.c17
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_pipe_util.c4
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_prim_assembler.c31
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_pt_emit.c6
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c6
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_pt_so_emit.c3
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_split_tmp.h7
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_vbuf.h5
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_vs.c2
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_vs.h2
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_vs_llvm.c3
-rw-r--r--lib/mesa/src/gallium/auxiliary/draw/draw_vs_variant.c6
20 files changed, 267 insertions, 274 deletions
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_cliptest_tmp.h b/lib/mesa/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
index dd57c5678..b7c77bfd8 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
@@ -43,14 +43,18 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
unsigned j;
unsigned i;
bool have_cd = false;
+ bool uses_vp_idx = draw_current_shader_uses_viewport_index(pvs->draw);
unsigned viewport_index_output =
draw_current_shader_viewport_index_output(pvs->draw);
- int viewport_index =
- draw_current_shader_uses_viewport_index(pvs->draw) ?
- u_bitcast_f2u(out->data[viewport_index_output][0]): 0;
+ int viewport_index = 0;
int num_written_clipdistance =
draw_current_shader_num_written_clipdistances(pvs->draw);
+ if (uses_vp_idx) {
+ viewport_index = u_bitcast_f2u(out->data[viewport_index_output][0]);
+ viewport_index = draw_clamp_viewport_idx(viewport_index);
+ }
+
cd[0] = draw_current_shader_ccdistance_output(pvs->draw, 0);
cd[1] = draw_current_shader_ccdistance_output(pvs->draw, 1);
@@ -65,22 +69,23 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
}
assert(pos != -1);
+ unsigned prim_idx = 0, prim_vert_idx = 0;
for (j = 0; j < info->count; j++) {
float *position = out->data[pos];
unsigned mask = 0x0;
- float *scale = pvs->draw->viewports[0].scale;
- float *trans = pvs->draw->viewports[0].translate;
- if (draw_current_shader_uses_viewport_index(pvs->draw)) {
- unsigned verts_per_prim = u_vertices_per_prim(prim_info->prim);
+
+ if (uses_vp_idx) {
/* only change the viewport_index for the leading vertex */
- if (!(j % verts_per_prim)) {
+ if (prim_vert_idx == (prim_info->primitive_lengths[prim_idx])) {
+ prim_idx++;
+ prim_vert_idx = 0;
viewport_index = u_bitcast_f2u(out->data[viewport_index_output][0]);
viewport_index = draw_clamp_viewport_idx(viewport_index);
}
- scale = pvs->draw->viewports[viewport_index].scale;
- trans = pvs->draw->viewports[viewport_index].translate;
+ prim_vert_idx++;
}
-
+ float *scale = pvs->draw->viewports[viewport_index].scale;
+ float *trans = pvs->draw->viewports[viewport_index].translate;
initialize_vertex_header(out);
if (flags & (DO_CLIP_XY | DO_CLIP_XY_GUARD_BAND |
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_gs.c b/lib/mesa/src/gallium/auxiliary/draw/draw_gs.c
index e2ffa1bdd..ed698e920 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_gs.c
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_gs.c
@@ -29,7 +29,7 @@
#include "draw_private.h"
#include "draw_context.h"
-#ifdef LLVM_AVAILABLE
+#ifdef DRAW_LLVM_AVAILABLE
#include "draw_llvm.h"
#endif
@@ -69,7 +69,7 @@ draw_gs_get_input_index(int semantic, int index,
static inline boolean
draw_gs_should_flush(struct draw_geometry_shader *shader)
{
- return (shader->fetched_prim_count == shader->vector_length);
+ return (shader->fetched_prim_count == shader->vector_length || shader->num_invocations > 1);
}
/*#define DEBUG_OUTPUTS 1*/
@@ -132,6 +132,12 @@ static void tgsi_fetch_gs_input(struct draw_geometry_shader *shader,
unsigned input_vertex_stride = shader->input_vertex_stride;
const float (*input_ptr)[4];
+ int primid_sv = machine->SysSemanticToIndex[TGSI_SEMANTIC_PRIMID];
+ if (primid_sv != -1) {
+ for (unsigned j = 0; j < TGSI_QUAD_SIZE; j++)
+ machine->SystemValue[primid_sv].xyzw[0].i[j] = shader->in_prim_idx;
+ }
+
input_ptr = shader->input;
for (i = 0; i < num_vertices; ++i) {
@@ -192,15 +198,8 @@ static void tgsi_gs_prepare(struct draw_geometry_shader *shader,
const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS])
{
struct tgsi_exec_machine *machine = shader->machine;
- int j;
tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS,
constants, constants_size);
-
- if (shader->info.uses_invocationid) {
- unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INVOCATIONID];
- for (j = 0; j < TGSI_QUAD_SIZE; j++)
- machine->SystemValue[i].xyzw[0].i[j] = shader->invocation_id;
- }
}
static void tgsi_gs_run(struct draw_geometry_shader *shader,
@@ -210,36 +209,20 @@ static void tgsi_gs_run(struct draw_geometry_shader *shader,
struct tgsi_exec_machine *machine = shader->machine;
int i;
+ if (shader->info.uses_invocationid) {
+ unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INVOCATIONID];
+ for (int j = 0; j < TGSI_QUAD_SIZE; j++)
+ machine->SystemValue[i].xyzw[0].i[j] = shader->invocation_id;
+ }
+
/* run interpreter */
tgsi_exec_machine_run(machine, 0);
- for (i = 0; i < 4; i++) {
- int prim_i;
- int prim_c;
- switch (i) {
- case 0:
- prim_i = TGSI_EXEC_TEMP_PRIMITIVE_I;
- prim_c = TGSI_EXEC_TEMP_PRIMITIVE_C;
- break;
- case 1:
- prim_i = TGSI_EXEC_TEMP_PRIMITIVE_S1_I;
- prim_c = TGSI_EXEC_TEMP_PRIMITIVE_S1_C;
- break;
- case 2:
- prim_i = TGSI_EXEC_TEMP_PRIMITIVE_S2_I;
- prim_c = TGSI_EXEC_TEMP_PRIMITIVE_S2_C;
- break;
- case 3:
- prim_i = TGSI_EXEC_TEMP_PRIMITIVE_S3_I;
- prim_c = TGSI_EXEC_TEMP_PRIMITIVE_S3_C;
- break;
- };
-
- out_prims[i] = machine->Temps[prim_i].xyzw[prim_c].u[0];
- }
+ for (i = 0; i < 4; i++)
+ out_prims[i] = machine->OutputPrimCount[i];
}
-#ifdef LLVM_AVAILABLE
+#ifdef DRAW_LLVM_AVAILABLE
static void
llvm_fetch_gs_input(struct draw_geometry_shader *shader,
@@ -321,23 +304,23 @@ llvm_fetch_gs_outputs(struct draw_geometry_shader *shader,
int vertex_count = 0;
int total_prims = 0;
int max_prims_per_invocation = 0;
- char *output_ptr = (char*)shader->gs_output;
+ char *output_ptr = (char*)shader->gs_output[stream];
int i, j, prim_idx;
unsigned next_prim_boundary = shader->primitive_boundary;
for (i = 0; i < shader->vector_length; ++i) {
- int prims = shader->llvm_emitted_primitives[i];
+ int prims = shader->llvm_emitted_primitives[i + (stream * shader->vector_length)];
total_prims += prims;
max_prims_per_invocation = MAX2(max_prims_per_invocation, prims);
}
for (i = 0; i < shader->vector_length; ++i) {
- total_verts += shader->llvm_emitted_vertices[i];
+ total_verts += shader->llvm_emitted_vertices[i + (stream * shader->vector_length)];
}
- output_ptr += shader->stream[0].emitted_vertices * shader->vertex_size;
+ output_ptr += shader->stream[stream].emitted_vertices * shader->vertex_size;
for (i = 0; i < shader->vector_length - 1; ++i) {
- int current_verts = shader->llvm_emitted_vertices[i];
- int next_verts = shader->llvm_emitted_vertices[i + 1];
+ int current_verts = shader->llvm_emitted_vertices[i + (stream * shader->vector_length)];
+ int next_verts = shader->llvm_emitted_vertices[i + 1 + (stream * shader->vector_length)];
#if 0
int j;
for (j = 0; j < current_verts; ++j) {
@@ -377,18 +360,18 @@ llvm_fetch_gs_outputs(struct draw_geometry_shader *shader,
prim_idx = 0;
for (i = 0; i < shader->vector_length; ++i) {
- int num_prims = shader->llvm_emitted_primitives[i];
+ int num_prims = shader->llvm_emitted_primitives[i + (stream * shader->vector_length)];
for (j = 0; j < num_prims; ++j) {
int prim_length =
- shader->llvm_prim_lengths[j][i];
- shader->stream[0].primitive_lengths[shader->stream[0].emitted_primitives + prim_idx] =
+ shader->llvm_prim_lengths[j * shader->num_vertex_streams + stream][i];
+ shader->stream[stream].primitive_lengths[shader->stream[stream].emitted_primitives + prim_idx] =
prim_length;
++prim_idx;
}
}
- shader->stream[0].emitted_primitives += total_prims;
- shader->stream[0].emitted_vertices += total_verts;
+ shader->stream[stream].emitted_primitives += total_prims;
+ shader->stream[stream].emitted_vertices += total_verts;
}
static void
@@ -402,20 +385,25 @@ static void
llvm_gs_run(struct draw_geometry_shader *shader,
unsigned input_primitives, unsigned *out_prims)
{
- unsigned ret;
- char *input = (char*)shader->gs_output;
-
- input += (shader->stream[0].emitted_vertices * shader->vertex_size);
+ struct vertex_header *input[PIPE_MAX_VERTEX_STREAMS];
+ for (unsigned i = 0; i < shader->num_vertex_streams; i++) {
+ char *tmp = (char *)shader->gs_output[i];
+ tmp += shader->stream[i].emitted_vertices * shader->vertex_size;
+ input[i] = (struct vertex_header *)tmp;
+ }
- ret = shader->current_variant->jit_func(
+ shader->current_variant->jit_func(
shader->jit_context, shader->gs_input->data,
- (struct vertex_header*)input,
+ input,
input_primitives,
shader->draw->instance_id,
shader->llvm_prim_ids,
- shader->invocation_id);
+ shader->invocation_id,
+ shader->draw->pt.user.viewid);
- *out_prims = ret;
+ for (unsigned i = 0; i < shader->num_vertex_streams; i++) {
+ out_prims[i] = shader->jit_context->emitted_prims[i];
+ }
}
#endif
@@ -433,10 +421,13 @@ static void gs_flush(struct draw_geometry_shader *shader)
debug_assert(input_primitives > 0 &&
input_primitives <= 4);
- shader->run(shader, input_primitives, out_prim_count);
- for (i = 0; i < shader->num_vertex_streams; i++) {
- shader->fetch_outputs(shader, i, out_prim_count[i],
- &shader->stream[i].tmp_output);
+ for (unsigned invocation = 0; invocation < shader->num_invocations; invocation++) {
+ shader->invocation_id = invocation;
+ shader->run(shader, input_primitives, out_prim_count);
+ for (i = 0; i < shader->num_vertex_streams; i++) {
+ shader->fetch_outputs(shader, i, out_prim_count[i],
+ &shader->stream[i].tmp_output);
+ }
}
#if 0
@@ -588,7 +579,6 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
* overflown vertices into some area where they won't harm anyone */
unsigned total_verts_per_buffer = shader->primitive_boundary *
num_in_primitives;
- unsigned invocation;
int i;
//Assume at least one primitive
max_out_prims = MAX2(max_out_prims, 1);
@@ -599,16 +589,18 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
output_verts[i].stride = output_verts[i].vertex_size;
output_verts[i].verts =
(struct vertex_header *)MALLOC(output_verts[i].vertex_size *
- total_verts_per_buffer * shader->num_invocations);
+ total_verts_per_buffer * shader->num_invocations +
+ DRAW_EXTRA_VERTICES_PADDING);
debug_assert(output_verts[i].verts);
}
#if 0
- debug_printf("%s count = %d (in prims # = %d)\n",
- __FUNCTION__, num_input_verts, num_in_primitives);
+ debug_printf("%s count = %d (in prims # = %d, invocs = %d, streams = %d)\n",
+ __FUNCTION__, num_input_verts, num_in_primitives,
+ shader->num_invocations, shader->num_vertex_streams);
debug_printf("\tlinear = %d, prim_info->count = %d\n",
input_prim->linear, input_prim->count);
- debug_printf("\tprim pipe = %s, shader in = %s, shader out = %s\n"
+ debug_printf("\tprim pipe = %s, shader in = %s, shader out = %s\n",
u_prim_name(input_prim->prim),
u_prim_name(shader->input_primitive),
u_prim_name(shader->output_primitive));
@@ -632,20 +624,22 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
shader->input = input;
shader->input_info = input_info;
-#ifdef LLVM_AVAILABLE
+#ifdef DRAW_LLVM_AVAILABLE
if (shader->draw->llvm) {
- shader->gs_output = output_verts[0].verts;
+ for (i = 0; i < shader->num_vertex_streams; i++) {
+ shader->gs_output[i] = output_verts[i].verts;
+ }
if (max_out_prims > shader->max_out_prims) {
unsigned i;
if (shader->llvm_prim_lengths) {
- for (i = 0; i < shader->max_out_prims; ++i) {
+ for (i = 0; i < shader->num_vertex_streams * shader->max_out_prims; ++i) {
align_free(shader->llvm_prim_lengths[i]);
}
FREE(shader->llvm_prim_lengths);
}
- shader->llvm_prim_lengths = MALLOC(max_out_prims * sizeof(unsigned*));
- for (i = 0; i < max_out_prims; ++i) {
+ shader->llvm_prim_lengths = MALLOC(shader->num_vertex_streams * max_out_prims * sizeof(unsigned*));
+ for (i = 0; i < shader->num_vertex_streams * max_out_prims; ++i) {
int vector_size = shader->vector_length * sizeof(unsigned);
shader->llvm_prim_lengths[i] =
align_malloc(vector_size, vector_size);
@@ -659,26 +653,22 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
}
#endif
- for (invocation = 0; invocation < shader->num_invocations; invocation++) {
- shader->invocation_id = invocation;
-
- shader->prepare(shader, constants, constants_size);
+ shader->prepare(shader, constants, constants_size);
- if (input_prim->linear)
- gs_run(shader, input_prim, input_verts,
- output_prims, output_verts);
- else
- gs_run_elts(shader, input_prim, input_verts,
- output_prims, output_verts);
+ if (input_prim->linear)
+ gs_run(shader, input_prim, input_verts,
+ output_prims, output_verts);
+ else
+ gs_run_elts(shader, input_prim, input_verts,
+ output_prims, output_verts);
- /* Flush the remaining primitives. Will happen if
- * num_input_primitives % 4 != 0
- */
- if (shader->fetched_prim_count > 0) {
- gs_flush(shader);
- }
- debug_assert(shader->fetched_prim_count == 0);
+ /* Flush the remaining primitives. Will happen if
+ * num_input_primitives % 4 != 0
+ */
+ if (shader->fetched_prim_count > 0) {
+ gs_flush(shader);
}
+ debug_assert(shader->fetched_prim_count == 0);
/* Update prim_info:
*/
@@ -765,14 +755,14 @@ struct draw_geometry_shader *
draw_create_geometry_shader(struct draw_context *draw,
const struct pipe_shader_state *state)
{
-#ifdef LLVM_AVAILABLE
+#ifdef DRAW_LLVM_AVAILABLE
boolean use_llvm = draw->llvm != NULL;
struct llvm_geometry_shader *llvm_gs = NULL;
#endif
struct draw_geometry_shader *gs;
unsigned i;
-#ifdef LLVM_AVAILABLE
+#ifdef DRAW_LLVM_AVAILABLE
if (use_llvm) {
llvm_gs = CALLOC_STRUCT(llvm_geometry_shader);
@@ -808,7 +798,7 @@ draw_create_geometry_shader(struct draw_context *draw,
/* setup the defaults */
gs->max_out_prims = 0;
-#ifdef LLVM_AVAILABLE
+#ifdef DRAW_LLVM_AVAILABLE
if (use_llvm) {
/* TODO: change the input array to handle the following
vector length, instead of the currently hardcoded
@@ -865,16 +855,16 @@ draw_create_geometry_shader(struct draw_context *draw,
gs->num_vertex_streams = gs->state.stream_output.output[i].stream + 1;
}
-#ifdef LLVM_AVAILABLE
+#ifdef DRAW_LLVM_AVAILABLE
if (use_llvm) {
int vector_size = gs->vector_length * sizeof(float);
gs->gs_input = align_malloc(sizeof(struct draw_gs_inputs), 16);
memset(gs->gs_input, 0, sizeof(struct draw_gs_inputs));
gs->llvm_prim_lengths = 0;
- gs->llvm_emitted_primitives = align_malloc(vector_size, vector_size);
- gs->llvm_emitted_vertices = align_malloc(vector_size, vector_size);
- gs->llvm_prim_ids = align_malloc(vector_size, vector_size);
+ gs->llvm_emitted_primitives = align_malloc(vector_size * gs->num_vertex_streams, vector_size);
+ gs->llvm_emitted_vertices = align_malloc(vector_size * gs->num_vertex_streams, vector_size);
+ gs->llvm_prim_ids = align_calloc(vector_size, vector_size);
gs->fetch_outputs = llvm_fetch_gs_outputs;
gs->fetch_inputs = llvm_fetch_gs_input;
@@ -925,7 +915,7 @@ void draw_delete_geometry_shader(struct draw_context *draw,
if (!dgs) {
return;
}
-#ifdef LLVM_AVAILABLE
+#ifdef DRAW_LLVM_AVAILABLE
if (draw->llvm) {
struct llvm_geometry_shader *shader = llvm_geometry_shader(dgs);
struct draw_gs_llvm_variant_list_item *li;
@@ -941,7 +931,7 @@ void draw_delete_geometry_shader(struct draw_context *draw,
if (dgs->llvm_prim_lengths) {
unsigned i;
- for (i = 0; i < dgs->max_out_prims; ++i) {
+ for (i = 0; i < dgs->num_vertex_streams * dgs->max_out_prims; ++i) {
align_free(dgs->llvm_prim_lengths[i]);
}
FREE(dgs->llvm_prim_lengths);
@@ -954,6 +944,9 @@ void draw_delete_geometry_shader(struct draw_context *draw,
}
#endif
+ if (draw->gs.tgsi.machine && draw->gs.tgsi.machine->Tokens == dgs->state.tokens)
+ draw->gs.tgsi.machine->Tokens = NULL;
+
for (i = 0; i < TGSI_MAX_VERTEX_STREAMS; i++)
FREE(dgs->stream[i].primitive_lengths);
@@ -964,7 +957,7 @@ void draw_delete_geometry_shader(struct draw_context *draw,
}
-#ifdef LLVM_AVAILABLE
+#ifdef DRAW_LLVM_AVAILABLE
void draw_gs_set_current_variant(struct draw_geometry_shader *shader,
struct draw_gs_llvm_variant *variant)
{
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_gs.h b/lib/mesa/src/gallium/auxiliary/draw/draw_gs.h
index 9a86910c1..9449ec509 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_gs.h
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_gs.h
@@ -36,7 +36,7 @@
struct draw_context;
-#ifdef LLVM_AVAILABLE
+#ifdef DRAW_LLVM_AVAILABLE
struct draw_gs_jit_context;
struct draw_gs_llvm_variant;
@@ -96,11 +96,11 @@ struct draw_geometry_shader {
unsigned num_invocations;
unsigned invocation_id;
-#ifdef LLVM_AVAILABLE
+#ifdef DRAW_LLVM_AVAILABLE
struct draw_gs_inputs *gs_input;
struct draw_gs_jit_context *jit_context;
struct draw_gs_llvm_variant *current_variant;
- struct vertex_header *gs_output;
+ struct vertex_header *gs_output[PIPE_MAX_VERTEX_STREAMS];
int **llvm_prim_lengths;
int *llvm_emitted_primitives;
@@ -146,7 +146,7 @@ void draw_geometry_shader_prepare(struct draw_geometry_shader *shader,
int draw_gs_max_output_vertices(struct draw_geometry_shader *shader,
unsigned pipe_prim);
-#ifdef LLVM_AVAILABLE
+#ifdef DRAW_LLVM_AVAILABLE
void draw_gs_set_current_variant(struct draw_geometry_shader *shader,
struct draw_gs_llvm_variant *variant);
#endif
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_llvm_sample.c b/lib/mesa/src/gallium/auxiliary/draw/draw_llvm_sample.c
index 9d7114a9a..a3895c798 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_llvm_sample.c
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_llvm_sample.c
@@ -70,6 +70,8 @@ struct draw_llvm_sampler_soa
struct lp_build_sampler_soa base;
struct draw_llvm_sampler_dynamic_state dynamic_state;
+
+ unsigned nr_samplers;
};
struct draw_llvm_image_dynamic_state
@@ -84,6 +86,8 @@ struct draw_llvm_image_soa
struct lp_build_image_soa base;
struct draw_llvm_image_dynamic_state dynamic_state;
+
+ unsigned nr_images;
};
/**
@@ -99,6 +103,7 @@ draw_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
struct gallivm_state *gallivm,
LLVMValueRef context_ptr,
unsigned texture_unit,
+ LLVMValueRef texture_unit_offset,
unsigned member_index,
const char *member_name,
boolean emit_load)
@@ -116,6 +121,11 @@ draw_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
indices[1] = lp_build_const_int32(gallivm, DRAW_JIT_CTX_TEXTURES);
/* context[0].textures[unit] */
indices[2] = lp_build_const_int32(gallivm, texture_unit);
+ if (texture_unit_offset) {
+ indices[2] = LLVMBuildAdd(gallivm->builder, indices[2], texture_unit_offset, "");
+ LLVMValueRef cond = LLVMBuildICmp(gallivm->builder, LLVMIntULT, indices[2], lp_build_const_int32(gallivm, PIPE_MAX_SHADER_SAMPLER_VIEWS), "");
+ indices[2] = LLVMBuildSelect(gallivm->builder, cond, indices[2], lp_build_const_int32(gallivm, texture_unit), "");
+ }
/* context[0].textures[unit].member */
indices[3] = lp_build_const_int32(gallivm, member_index);
@@ -190,6 +200,7 @@ draw_llvm_image_member(const struct lp_sampler_dynamic_state *base,
struct gallivm_state *gallivm,
LLVMValueRef context_ptr,
unsigned image_unit,
+ LLVMValueRef image_unit_offset,
unsigned member_index,
const char *member_name,
boolean emit_load)
@@ -207,6 +218,11 @@ draw_llvm_image_member(const struct lp_sampler_dynamic_state *base,
indices[1] = lp_build_const_int32(gallivm, DRAW_JIT_CTX_IMAGES);
/* context[0].textures[unit] */
indices[2] = lp_build_const_int32(gallivm, image_unit);
+ if (image_unit_offset) {
+ indices[2] = LLVMBuildAdd(gallivm->builder, indices[2], image_unit_offset, "");
+ LLVMValueRef cond = LLVMBuildICmp(gallivm->builder, LLVMIntULT, indices[2], lp_build_const_int32(gallivm, PIPE_MAX_SHADER_IMAGES), "");
+ indices[2] = LLVMBuildSelect(gallivm->builder, cond, indices[2], lp_build_const_int32(gallivm, image_unit), "");
+ }
/* context[0].textures[unit].member */
indices[3] = lp_build_const_int32(gallivm, member_index);
@@ -236,10 +252,12 @@ draw_llvm_image_member(const struct lp_sampler_dynamic_state *base,
draw_llvm_texture_##_name( const struct lp_sampler_dynamic_state *base, \
struct gallivm_state *gallivm, \
LLVMValueRef context_ptr, \
- unsigned texture_unit) \
+ unsigned texture_unit, \
+ LLVMValueRef texture_unit_offset) \
{ \
return draw_llvm_texture_member(base, gallivm, context_ptr, \
- texture_unit, _index, #_name, _emit_load ); \
+ texture_unit, texture_unit_offset, \
+ _index, #_name, _emit_load ); \
}
@@ -252,7 +270,8 @@ DRAW_LLVM_TEXTURE_MEMBER(base_ptr, DRAW_JIT_TEXTURE_BASE, 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(mip_offsets, DRAW_JIT_TEXTURE_MIP_OFFSETS, FALSE)
-
+DRAW_LLVM_TEXTURE_MEMBER(num_samples, DRAW_JIT_TEXTURE_NUM_SAMPLES, TRUE)
+DRAW_LLVM_TEXTURE_MEMBER(sample_stride, DRAW_JIT_TEXTURE_SAMPLE_STRIDE, TRUE)
#define DRAW_LLVM_SAMPLER_MEMBER(_name, _index, _emit_load) \
static LLVMValueRef \
@@ -274,12 +293,13 @@ 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) \
+ struct gallivm_state *gallivm, \
+ LLVMValueRef context_ptr, \
+ unsigned image_unit, LLVMValueRef image_unit_offset) \
{ \
return draw_llvm_image_member(base, gallivm, context_ptr, \
- image_unit, _index, #_name, _emit_load ); \
+ image_unit, image_unit_offset, \
+ _index, #_name, _emit_load ); \
}
@@ -289,6 +309,8 @@ 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)
+DRAW_LLVM_IMAGE_MEMBER(num_samples, DRAW_JIT_IMAGE_NUM_SAMPLES, TRUE)
+DRAW_LLVM_IMAGE_MEMBER(sample_stride, DRAW_JIT_IMAGE_SAMPLE_STRIDE, TRUE)
static void
draw_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
@@ -313,10 +335,27 @@ draw_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
assert(texture_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
assert(sampler_index < PIPE_MAX_SAMPLERS);
- lp_build_sample_soa(&sampler->dynamic_state.static_state[texture_index].texture_state,
- &sampler->dynamic_state.static_state[sampler_index].sampler_state,
- &sampler->dynamic_state.base,
- gallivm, params);
+ if (params->texture_index_offset) {
+ struct lp_build_sample_array_switch switch_info;
+ memset(&switch_info, 0, sizeof(switch_info));
+ LLVMValueRef unit = LLVMBuildAdd(gallivm->builder, params->texture_index_offset,
+ lp_build_const_int32(gallivm, texture_index), "");
+ lp_build_sample_array_init_soa(&switch_info, gallivm, params, unit,
+ 0, sampler->nr_samplers);
+
+ for (unsigned i = 0; i < sampler->nr_samplers; i++) {
+ lp_build_sample_array_case_soa(&switch_info, i,
+ &sampler->dynamic_state.static_state[i].texture_state,
+ &sampler->dynamic_state.static_state[i].sampler_state,
+ &sampler->dynamic_state.base);
+ }
+ lp_build_sample_array_fini_soa(&switch_info);
+ } else {
+ lp_build_sample_soa(&sampler->dynamic_state.static_state[texture_index].texture_state,
+ &sampler->dynamic_state.static_state[sampler_index].sampler_state,
+ &sampler->dynamic_state.base,
+ gallivm, params);
+ }
}
@@ -339,7 +378,8 @@ draw_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base,
}
struct lp_build_sampler_soa *
-draw_llvm_sampler_soa_create(const struct draw_sampler_static_state *static_state)
+draw_llvm_sampler_soa_create(const struct draw_sampler_static_state *static_state,
+ unsigned nr_samplers)
{
struct draw_llvm_sampler_soa *sampler;
@@ -359,12 +399,15 @@ draw_llvm_sampler_soa_create(const struct draw_sampler_static_state *static_stat
sampler->dynamic_state.base.img_stride = draw_llvm_texture_img_stride;
sampler->dynamic_state.base.base_ptr = draw_llvm_texture_base_ptr;
sampler->dynamic_state.base.mip_offsets = draw_llvm_texture_mip_offsets;
+ sampler->dynamic_state.base.num_samples = draw_llvm_texture_num_samples;
+ sampler->dynamic_state.base.sample_stride = draw_llvm_texture_sample_stride;
sampler->dynamic_state.base.min_lod = draw_llvm_sampler_min_lod;
sampler->dynamic_state.base.max_lod = draw_llvm_sampler_max_lod;
sampler->dynamic_state.base.lod_bias = draw_llvm_sampler_lod_bias;
sampler->dynamic_state.base.border_color = draw_llvm_sampler_border_color;
sampler->dynamic_state.static_state = static_state;
+ sampler->nr_samplers = nr_samplers;
return &sampler->base;
}
@@ -377,9 +420,25 @@ draw_llvm_image_soa_emit_op(const struct lp_build_image_soa *base,
unsigned image_index = params->image_index;
assert(image_index < PIPE_MAX_SHADER_IMAGES);
+ if (params->image_index_offset) {
+ struct lp_build_img_op_array_switch switch_info;
+ memset(&switch_info, 0, sizeof(switch_info));
+ LLVMValueRef unit = LLVMBuildAdd(gallivm->builder, params->image_index_offset,
+ lp_build_const_int32(gallivm, image_index), "");
+ lp_build_image_op_switch_soa(&switch_info, gallivm, params,
+ unit, 0, image->nr_images);
+
+ for (unsigned i = 0; i < image->nr_images; i++) {
+ lp_build_image_op_array_case(&switch_info, i,
+ &image->dynamic_state.static_state[i].image_state,
+ &image->dynamic_state.base);
+ }
+ lp_build_image_op_array_fini_soa(&switch_info);
+ return;
+ }
lp_build_img_op_soa(&image->dynamic_state.static_state[image_index].image_state,
&image->dynamic_state.base,
- gallivm, params);
+ gallivm, params, params->outdata);
}
/**
* Fetch the texture size.
@@ -405,7 +464,8 @@ draw_llvm_image_soa_destroy(struct lp_build_image_soa *image)
}
struct lp_build_image_soa *
-draw_llvm_image_soa_create(const struct draw_image_static_state *static_state)
+draw_llvm_image_soa_create(const struct draw_image_static_state *static_state,
+ unsigned nr_images)
{
struct draw_llvm_image_soa *image;
@@ -424,8 +484,11 @@ draw_llvm_image_soa_create(const struct draw_image_static_state *static_state)
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.base.num_samples = draw_llvm_image_num_samples;
+ image->dynamic_state.base.sample_stride = draw_llvm_image_sample_stride;
image->dynamic_state.static_state = static_state;
+ image->nr_images = nr_images;
return &image->base;
}
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe.c b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe.c
index 27a376252..339bc7f4d 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe.c
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe.c
@@ -49,6 +49,7 @@ boolean draw_pipeline_init( struct draw_context *draw )
draw->pipeline.clip = draw_clip_stage( draw );
draw->pipeline.flatshade = draw_flatshade_stage( draw );
draw->pipeline.cull = draw_cull_stage( draw );
+ draw->pipeline.user_cull = draw_user_cull_stage( draw );
draw->pipeline.validate = draw_validate_stage( draw );
draw->pipeline.first = draw->pipeline.validate;
@@ -61,6 +62,7 @@ boolean draw_pipeline_init( struct draw_context *draw )
!draw->pipeline.clip ||
!draw->pipeline.flatshade ||
!draw->pipeline.cull ||
+ !draw->pipeline.user_cull ||
!draw->pipeline.validate)
return FALSE;
@@ -95,6 +97,8 @@ void draw_pipeline_destroy( struct draw_context *draw )
draw->pipeline.flatshade->destroy( draw->pipeline.flatshade );
if (draw->pipeline.cull)
draw->pipeline.cull->destroy( draw->pipeline.cull );
+ if (draw->pipeline.user_cull)
+ draw->pipeline.user_cull->destroy( draw->pipeline.user_cull );
if (draw->pipeline.validate)
draw->pipeline.validate->destroy( draw->pipeline.validate );
if (draw->pipeline.aaline)
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe.h b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe.h
index e69dcbded..4ae8883f0 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe.h
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe.h
@@ -87,6 +87,7 @@ extern struct draw_stage *draw_offset_stage( struct draw_context *context );
extern struct draw_stage *draw_clip_stage( struct draw_context *context );
extern struct draw_stage *draw_flatshade_stage( struct draw_context *context );
extern struct draw_stage *draw_cull_stage( struct draw_context *context );
+extern struct draw_stage *draw_user_cull_stage( struct draw_context *draw );
extern struct draw_stage *draw_stipple_stage( struct draw_context *context );
extern struct draw_stage *draw_wide_line_stage( struct draw_context *context );
extern struct draw_stage *draw_wide_point_stage( struct draw_context *context );
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_cull.c b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_cull.c
index 318d743db..a873edbe7 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_cull.c
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_cull.c
@@ -51,105 +51,12 @@ static inline struct cull_stage *cull_stage( struct draw_stage *stage )
return (struct cull_stage *)stage;
}
-static inline boolean
-cull_distance_is_out(float dist)
-{
- return (dist < 0.0f) || util_is_inf_or_nan(dist);
-}
-
/*
- * If the shader writes the culldistance then we can
- * perform distance based culling. Distance based
- * culling doesn't require a face and can be performed
- * on primitives without faces (e.g. points and lines)
- */
-static void cull_point( struct draw_stage *stage,
- struct prim_header *header )
-{
- const unsigned num_written_culldistances =
- draw_current_shader_num_written_culldistances(stage->draw);
- const unsigned num_written_clipdistances =
- draw_current_shader_num_written_clipdistances(stage->draw);
- unsigned i;
-
- debug_assert(num_written_culldistances);
-
- for (i = 0; i < num_written_culldistances; ++i) {
- unsigned cull_idx = (num_written_clipdistances + i) / 4;
- unsigned out_idx =
- draw_current_shader_ccdistance_output(stage->draw, cull_idx);
- unsigned idx = (num_written_clipdistances + i) % 4;
- float cull1 = header->v[0]->data[out_idx][idx];
- boolean vert1_out = cull_distance_is_out(cull1);
- if (vert1_out)
- return;
- }
- stage->next->point( stage->next, header );
-}
-
-/*
- * If the shader writes the culldistance then we can
- * perform distance based culling. Distance based
- * culling doesn't require a face and can be performed
- * on primitives without faces (e.g. points and lines)
- */
-static void cull_line( struct draw_stage *stage,
- struct prim_header *header )
-{
- const unsigned num_written_culldistances =
- draw_current_shader_num_written_culldistances(stage->draw);
- const unsigned num_written_clipdistances =
- draw_current_shader_num_written_clipdistances(stage->draw);
- unsigned i;
-
- debug_assert(num_written_culldistances);
-
- for (i = 0; i < num_written_culldistances; ++i) {
- unsigned cull_idx = (num_written_clipdistances + i) / 4;
- unsigned out_idx =
- draw_current_shader_ccdistance_output(stage->draw, cull_idx);
- unsigned idx = (num_written_clipdistances + i) % 4;
- float cull1 = header->v[0]->data[out_idx][idx];
- float cull2 = header->v[1]->data[out_idx][idx];
- boolean vert1_out = cull_distance_is_out(cull1);
- boolean vert2_out = cull_distance_is_out(cull2);
- if (vert1_out && vert2_out)
- return;
- }
- stage->next->line( stage->next, header );
-}
-
-/*
- * Triangles can be culled either using the cull distance
- * shader outputs or the regular face culling. If required
- * this function performs both, starting with distance culling.
+ * Triangles can be culled using regular face cull.
*/
static void cull_tri( struct draw_stage *stage,
struct prim_header *header )
{
- const unsigned num_written_culldistances =
- draw_current_shader_num_written_culldistances(stage->draw);
- const unsigned num_written_clipdistances =
- draw_current_shader_num_written_clipdistances(stage->draw);
- /* Do the distance culling */
- if (num_written_culldistances) {
- unsigned i;
- for (i = 0; i < num_written_culldistances; ++i) {
- unsigned cull_idx = (num_written_clipdistances + i) / 4;
- unsigned out_idx =
- draw_current_shader_ccdistance_output(stage->draw, cull_idx);
- unsigned idx = (num_written_clipdistances + i) % 4;
- float cull1 = header->v[0]->data[out_idx][idx];
- float cull2 = header->v[1]->data[out_idx][idx];
- float cull3 = header->v[2]->data[out_idx][idx];
- boolean vert1_out = cull_distance_is_out(cull1);
- boolean vert2_out = cull_distance_is_out(cull2);
- boolean vert3_out = cull_distance_is_out(cull3);
- if (vert1_out && vert2_out && vert3_out)
- return;
- }
- }
-
/* Do the regular face culling */
{
const unsigned pos = draw_current_shader_position_output(stage->draw);
@@ -195,36 +102,6 @@ static void cull_tri( struct draw_stage *stage,
}
}
-static void cull_first_point( struct draw_stage *stage,
- struct prim_header *header )
-{
- const unsigned num_written_culldistances =
- draw_current_shader_num_written_culldistances(stage->draw);
-
- if (num_written_culldistances) {
- stage->point = cull_point;
- stage->point( stage, header );
- } else {
- stage->point = draw_pipe_passthrough_point;
- stage->point( stage, header );
- }
-}
-
-static void cull_first_line( struct draw_stage *stage,
- struct prim_header *header )
-{
- const unsigned num_written_culldistances =
- draw_current_shader_num_written_culldistances(stage->draw);
-
- if (num_written_culldistances) {
- stage->line = cull_line;
- stage->line( stage, header );
- } else {
- stage->line = draw_pipe_passthrough_line;
- stage->line( stage, header );
- }
-}
-
static void cull_first_tri( struct draw_stage *stage,
struct prim_header *header )
{
@@ -240,8 +117,6 @@ static void cull_first_tri( struct draw_stage *stage,
static void cull_flush( struct draw_stage *stage, unsigned flags )
{
- stage->point = cull_first_point;
- stage->line = cull_first_line;
stage->tri = cull_first_tri;
stage->next->flush( stage->next, flags );
}
@@ -272,8 +147,8 @@ struct draw_stage *draw_cull_stage( struct draw_context *draw )
cull->stage.draw = draw;
cull->stage.name = "cull";
cull->stage.next = NULL;
- cull->stage.point = cull_first_point;
- cull->stage.line = cull_first_line;
+ cull->stage.point = draw_pipe_passthrough_point;
+ cull->stage.line = draw_pipe_passthrough_line;
cull->stage.tri = cull_first_tri;
cull->stage.flush = cull_flush;
cull->stage.reset_stipple_counter = cull_reset_stipple_counter;
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_offset.c b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_offset.c
index 191bd43d1..08d47f005 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_offset.c
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_offset.c
@@ -120,9 +120,9 @@ static void do_offset_tri( struct draw_stage *stage,
* Note: we're applying the offset and clamping per-vertex.
* Ideally, the offset is applied per-fragment prior to fragment shading.
*/
- v0[2] = CLAMP(v0[2] + zoffset, 0.0f, 1.0f);
- v1[2] = CLAMP(v1[2] + zoffset, 0.0f, 1.0f);
- v2[2] = CLAMP(v2[2] + zoffset, 0.0f, 1.0f);
+ v0[2] = SATURATE(v0[2] + zoffset);
+ v1[2] = SATURATE(v1[2] + zoffset);
+ v2[2] = SATURATE(v2[2] + zoffset);
stage->next->tri( stage->next, header );
}
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index bd74cb42a..eb7ad8bf2 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -108,6 +108,7 @@ struct pstip_stage
void (*driver_set_sampler_views)(struct pipe_context *,
enum pipe_shader_type shader,
unsigned start, unsigned count,
+ unsigned unbind_num_trailing_slots,
struct pipe_sampler_view **);
void (*driver_set_polygon_stipple)(struct pipe_context *,
@@ -143,11 +144,9 @@ generate_pstip_fs(struct pstip_stage *pstip)
if (pstip_fs.tokens == NULL)
return FALSE;
} else {
-#ifdef LLVM_AVAILABLE
pstip_fs.ir.nir = nir_shader_clone(NULL, orig_fs->ir.nir);
nir_lower_pstipple_fs(pstip_fs.ir.nir,
&pstip->fs->sampler_unit, 0, wincoord_file == TGSI_FILE_SYSTEM_VALUE);
-#endif
}
assert(pstip->fs->sampler_unit < PIPE_MAX_SAMPLERS);
@@ -225,7 +224,7 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
num_samplers, pstip->state.samplers);
pstip->driver_set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0,
- num_sampler_views, pstip->state.sampler_views);
+ num_sampler_views, 0, pstip->state.sampler_views);
draw->suspend_flushing = FALSE;
@@ -254,7 +253,7 @@ pstip_flush(struct draw_stage *stage, unsigned flags)
pstip->state.samplers);
pstip->driver_set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0,
- pstip->num_sampler_views,
+ pstip->num_sampler_views, 0,
pstip->state.sampler_views);
draw->suspend_flushing = FALSE;
@@ -334,7 +333,7 @@ pstip_stage_from_pipe(struct pipe_context *pipe)
/**
* This function overrides the driver's create_fs_state() function and
- * will typically be called by the state tracker.
+ * will typically be called by the gallium frontend.
*/
static void *
pstip_create_fs_state(struct pipe_context *pipe,
@@ -418,6 +417,7 @@ static void
pstip_set_sampler_views(struct pipe_context *pipe,
enum pipe_shader_type shader,
unsigned start, unsigned num,
+ unsigned unbind_num_trailing_slots,
struct pipe_sampler_view **views)
{
struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
@@ -429,11 +429,16 @@ pstip_set_sampler_views(struct pipe_context *pipe,
pipe_sampler_view_reference(&pstip->state.sampler_views[start + i],
views[i]);
}
+ for (; i < num + unbind_num_trailing_slots; i++) {
+ pipe_sampler_view_reference(&pstip->state.sampler_views[start + i],
+ NULL);
+ }
pstip->num_sampler_views = num;
}
/* pass-through */
- pstip->driver_set_sampler_views(pstip->pipe, shader, start, num, views);
+ pstip->driver_set_sampler_views(pstip->pipe, shader, start, num,
+ unbind_num_trailing_slots, views);
}
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_util.c b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_util.c
index 53a42a6a0..c2cb156a5 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_util.c
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_util.c
@@ -76,8 +76,8 @@ boolean draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr )
if (nr != 0)
{
unsigned i;
- ubyte *store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr );
-
+ ubyte *store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr +
+ DRAW_EXTRA_VERTICES_PADDING );
if (!store)
return FALSE;
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_prim_assembler.c b/lib/mesa/src/gallium/auxiliary/draw/draw_prim_assembler.c
index 7ff705a91..e628a143d 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_prim_assembler.c
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_prim_assembler.c
@@ -29,7 +29,7 @@
#include "draw_fs.h"
#include "draw_gs.h"
-
+#include "draw_tess.h"
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "util/u_prim.h"
@@ -59,8 +59,14 @@ needs_primid(const struct draw_context *draw)
{
const struct draw_fragment_shader *fs = draw->fs.fragment_shader;
const struct draw_geometry_shader *gs = draw->gs.geometry_shader;
+ const struct draw_tess_eval_shader *tes = draw->tes.tess_eval_shader;
if (fs && fs->info.uses_primid) {
- return !gs || !gs->info.uses_primid;
+ if (gs)
+ return !gs->info.uses_primid;
+ else if (tes)
+ return !tes->info.uses_primid;
+ else
+ return TRUE;
}
return FALSE;
}
@@ -70,6 +76,9 @@ draw_prim_assembler_is_required(const struct draw_context *draw,
const struct draw_prim_info *prim_info,
const struct draw_vertex_info *vert_info)
{
+ /* viewport index requires primitive boundaries to get correct vertex */
+ if (draw_current_shader_uses_viewport_index(draw))
+ return TRUE;
switch (prim_info->prim) {
case PIPE_PRIM_LINES_ADJACENCY:
case PIPE_PRIM_LINE_STRIP_ADJACENCY:
@@ -81,6 +90,16 @@ draw_prim_assembler_is_required(const struct draw_context *draw,
}
}
+static void
+add_prim(struct draw_assembler *asmblr, unsigned length)
+{
+ struct draw_prim_info *output_prims = asmblr->output_prims;
+
+ output_prims->primitive_lengths = realloc(output_prims->primitive_lengths, sizeof(unsigned) * (output_prims->primitive_count + 1));
+ output_prims->primitive_lengths[output_prims->primitive_count] = length;
+ output_prims->primitive_count++;
+}
+
/*
* Copy the vertex header along with its data from the current
* vertex buffer into a buffer holding vertices arranged
@@ -141,7 +160,8 @@ prim_point(struct draw_assembler *asmblr,
inject_primid(asmblr, idx, asmblr->primid++);
}
indices[0] = idx;
-
+
+ add_prim(asmblr, 1);
copy_verts(asmblr, indices, 1);
}
@@ -158,6 +178,7 @@ prim_line(struct draw_assembler *asmblr,
indices[0] = i0;
indices[1] = i1;
+ add_prim(asmblr, 2);
copy_verts(asmblr, indices, 2);
}
@@ -176,6 +197,7 @@ prim_tri(struct draw_assembler *asmblr,
indices[1] = i1;
indices[2] = i2;
+ add_prim(asmblr, 3);
copy_verts(asmblr, indices, 3);
}
@@ -246,7 +268,7 @@ draw_prim_assembler_run(struct draw_context *draw,
output_verts->vertex_size = input_verts->vertex_size;
output_verts->stride = input_verts->stride;
output_verts->verts = (struct vertex_header*)MALLOC(
- input_verts->vertex_size * max_verts);
+ input_verts->vertex_size * max_verts + DRAW_EXTRA_VERTICES_PADDING);
output_verts->count = 0;
@@ -263,7 +285,6 @@ draw_prim_assembler_run(struct draw_context *draw,
}
}
- output_prims->primitive_lengths[0] = output_verts->count;
output_prims->count = output_verts->count;
}
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pt_emit.c b/lib/mesa/src/gallium/auxiliary/draw/draw_pt_emit.c
index 984c76fdf..de42241ac 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_pt_emit.c
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pt_emit.c
@@ -71,6 +71,8 @@ draw_pt_emit_prepare(struct pt_emit *emit,
emit->prim = prim;
draw->render->set_primitive(draw->render, emit->prim);
+ if (draw->render->set_view_index)
+ draw->render->set_view_index(draw->render, draw->pt.user.viewid);
/* Must do this after set_primitive() above:
*/
@@ -157,6 +159,8 @@ draw_pt_emit(struct pt_emit *emit,
* between vbuf.c and here...
*/
render->set_primitive(draw->render, prim_info->prim);
+ if (draw->render->set_view_index)
+ draw->render->set_view_index(draw->render, draw->pt.user.viewid);
assert(vertex_count <= 65535);
render->allocate_vertices(render,
@@ -229,6 +233,8 @@ draw_pt_emit_linear(struct pt_emit *emit,
* between vbuf.c and here...
*/
render->set_primitive(draw->render, prim_info->prim);
+ if (draw->render->set_view_index)
+ draw->render->set_view_index(draw->render, draw->pt.user.viewid);
assert(count <= 65535);
if (!render->allocate_vertices(render,
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/lib/mesa/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
index 07838fb7e..2b5cb7dc0 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -214,7 +214,8 @@ draw_vertex_shader_run(struct draw_vertex_shader *vshader,
output_verts->count = input_verts->count;
output_verts->verts =
(struct vertex_header *)MALLOC(output_verts->vertex_size *
- align(output_verts->count, 4));
+ align(output_verts->count, 4) +
+ DRAW_EXTRA_VERTICES_PADDING);
vshader->run_linear(vshader,
(const float (*)[4])input_verts->verts->data,
@@ -254,7 +255,8 @@ fetch_pipeline_generic(struct draw_pt_middle_end *middle,
fetched_vert_info.stride = fpme->vertex_size;
fetched_vert_info.verts =
(struct vertex_header *)MALLOC(fpme->vertex_size *
- align(fetch_info->count, 4));
+ align(fetch_info->count, 4) +
+ DRAW_EXTRA_VERTICES_PADDING);
if (!fetched_vert_info.verts) {
assert(0);
return;
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pt_so_emit.c b/lib/mesa/src/gallium/auxiliary/draw/draw_pt_so_emit.c
index 6cb38fb9a..83f4a31a6 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_pt_so_emit.c
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pt_so_emit.c
@@ -28,6 +28,7 @@
#include "draw/draw_private.h"
#include "draw/draw_vs.h"
#include "draw/draw_gs.h"
+#include "draw/draw_tess.h"
#include "draw/draw_context.h"
#include "draw/draw_vbuf.h"
#include "draw/draw_vertex.h"
@@ -60,6 +61,8 @@ draw_so_info(const struct draw_context *draw)
if (draw->gs.geometry_shader) {
state = &draw->gs.geometry_shader->state.stream_output;
+ } else if (draw->tes.tess_eval_shader) {
+ state = &draw->tes.tess_eval_shader->state.stream_output;
} else {
state = &draw->vs.vertex_shader->state.stream_output;
}
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_split_tmp.h b/lib/mesa/src/gallium/auxiliary/draw/draw_split_tmp.h
index 084699df6..dc6918897 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_split_tmp.h
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_split_tmp.h
@@ -40,7 +40,11 @@ FUNC(FUNC_VARS)
max_count_loop, max_count_fan);
}
- draw_pt_split_prim(prim, &first, &incr);
+ if (prim == PIPE_PRIM_PATCHES) {
+ first = vsplit->draw->pt.vertices_per_patch;
+ incr = vsplit->draw->pt.vertices_per_patch;
+ } else
+ draw_pt_split_prim(prim, &first, &incr);
/* sanitize primitive length */
count = draw_pt_trim_count(count, first, incr);
if (count < first)
@@ -75,6 +79,7 @@ FUNC(FUNC_VARS)
* That is, remaining is implicitly trimmed.
*/
switch (prim) {
+ case PIPE_PRIM_PATCHES:
case PIPE_PRIM_POINTS:
case PIPE_PRIM_LINES:
case PIPE_PRIM_LINE_STRIP:
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_vbuf.h b/lib/mesa/src/gallium/auxiliary/draw/draw_vbuf.h
index 6e737ae5b..57b247eed 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_vbuf.h
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_vbuf.h
@@ -100,6 +100,11 @@ struct vbuf_render {
void (*set_primitive)( struct vbuf_render *, enum pipe_prim_type prim );
/**
+ * Notify the renderer of the current view index.
+ */
+ void (*set_view_index)( struct vbuf_render *, unsigned view_index );
+
+ /**
* Draw indexed primitives. Note that indices are ushort. The driver
* must complete this call, if necessary splitting the index list itself.
*/
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_vs.c b/lib/mesa/src/gallium/auxiliary/draw/draw_vs.c
index 802ff92b8..e8dbc11bc 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_vs.c
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_vs.c
@@ -59,7 +59,7 @@ draw_create_vertex_shader(struct draw_context *draw,
tgsi_dump(shader->tokens, 0);
}
-#ifdef LLVM_AVAILABLE
+#ifdef DRAW_LLVM_AVAILABLE
if (draw->pt.middle.llvm) {
vs = draw_create_vs_llvm(draw, shader);
}
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_vs.h b/lib/mesa/src/gallium/auxiliary/draw/draw_vs.h
index c0c29002b..2a11f86f2 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_vs.h
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_vs.h
@@ -164,7 +164,7 @@ draw_create_vs_exec(struct draw_context *draw,
struct draw_vs_variant_key;
struct draw_vertex_shader;
-#ifdef LLVM_AVAILABLE
+#ifdef DRAW_LLVM_AVAILABLE
struct draw_vertex_shader *
draw_create_vs_llvm(struct draw_context *draw,
const struct pipe_shader_state *state);
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_vs_llvm.c b/lib/mesa/src/gallium/auxiliary/draw/draw_vs_llvm.c
index ec3c5b00f..00c63ed5f 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_vs_llvm.c
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_vs_llvm.c
@@ -98,6 +98,9 @@ draw_create_vs_llvm(struct draw_context *draw,
for ir.nir & PIPE_SHADER_IR_NIR here. */
if (state->ir.nir && state->type == PIPE_SHADER_IR_NIR) {
vs->base.state.ir.nir = state->ir.nir;
+ nir_shader *nir = (nir_shader *)state->ir.nir;
+ if (!nir->options->lower_uniforms_to_ubo)
+ NIR_PASS_V(state->ir.nir, nir_lower_uniforms_to_ubo, false, false);
nir_tgsi_scan_shader(state->ir.nir, &vs->base.info, true);
} else {
/* we make a private copy of the tokens */
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_vs_variant.c b/lib/mesa/src/gallium/auxiliary/draw/draw_vs_variant.c
index 44cf29b8e..bc320cb1c 100644
--- a/lib/mesa/src/gallium/auxiliary/draw/draw_vs_variant.c
+++ b/lib/mesa/src/gallium/auxiliary/draw/draw_vs_variant.c
@@ -158,7 +158,8 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_variant *variant,
{
struct draw_vs_variant_generic *vsvg = (struct draw_vs_variant_generic *)variant;
unsigned temp_vertex_stride = vsvg->temp_vertex_stride;
- void *temp_buffer = MALLOC( align(count,4) * temp_vertex_stride );
+ void *temp_buffer = MALLOC( align(count,4) * temp_vertex_stride +
+ DRAW_EXTRA_VERTICES_PADDING );
if (0) debug_printf("%s %d \n", __FUNCTION__, count);
@@ -227,7 +228,8 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_variant *variant,
{
struct draw_vs_variant_generic *vsvg = (struct draw_vs_variant_generic *)variant;
unsigned temp_vertex_stride = vsvg->temp_vertex_stride;
- void *temp_buffer = MALLOC( align(count,4) * temp_vertex_stride );
+ void *temp_buffer = MALLOC( align(count,4) * temp_vertex_stride +
+ DRAW_EXTRA_VERTICES_PADDING );
if (0) debug_printf("%s %d %d (sz %d, %d)\n", __FUNCTION__, start, count,
vsvg->base.key.output_stride,