diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2021-07-22 10:17:30 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2021-07-22 10:17:30 +0000 |
commit | ca11beabae33eb59fb981b8adf50b1d47a2a98f0 (patch) | |
tree | 3e4691a396e6e54cd54224a190663d5cf976625b /lib/mesa/src/gallium/auxiliary/draw | |
parent | 27c8a50e8bbde7d28b1fc46d715a4c469e24f2c4 (diff) |
Import Mesa 21.1.5
Diffstat (limited to 'lib/mesa/src/gallium/auxiliary/draw')
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, |