diff options
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.c | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.h | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm.c | 44 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm.h | 7 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm_sample.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 14 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_private.h | 8 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt.c | 11 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_vsplit.c | 7 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h | 20 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_vs.c | 7 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_vs_exec.c | 22 |
15 files changed, 125 insertions, 29 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 95d96719873..d99f94edc43 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -751,7 +751,7 @@ void draw_set_mapped_texture(struct draw_context *draw, unsigned sampler_idx, uint32_t width, uint32_t height, uint32_t depth, - uint32_t last_level, + uint32_t first_level, uint32_t last_level, uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS], uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS], const void *data[PIPE_MAX_TEXTURE_LEVELS]) @@ -760,7 +760,7 @@ draw_set_mapped_texture(struct draw_context *draw, if(draw->llvm) draw_llvm_set_mapped_texture(draw, sampler_idx, - width, height, depth, last_level, + width, height, depth, first_level, last_level, row_stride, img_stride, data); #endif } diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index a0b217e4d33..7db75b71b43 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -123,7 +123,7 @@ void draw_set_mapped_texture(struct draw_context *draw, unsigned sampler_idx, uint32_t width, uint32_t height, uint32_t depth, - uint32_t last_level, + uint32_t first_level, uint32_t last_level, uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS], uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS], const void *data[PIPE_MAX_TEXTURE_LEVELS]); diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index a5217c1d4ec..a1b8fc38880 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -106,6 +106,7 @@ create_jit_texture_type(struct gallivm_state *gallivm) elem_types[DRAW_JIT_TEXTURE_WIDTH] = elem_types[DRAW_JIT_TEXTURE_HEIGHT] = elem_types[DRAW_JIT_TEXTURE_DEPTH] = + elem_types[DRAW_JIT_TEXTURE_FIRST_LEVEL] = elem_types[DRAW_JIT_TEXTURE_LAST_LEVEL] = int32_type; elem_types[DRAW_JIT_TEXTURE_ROW_STRIDE] = elem_types[DRAW_JIT_TEXTURE_IMG_STRIDE] = @@ -136,6 +137,9 @@ create_jit_texture_type(struct gallivm_state *gallivm) LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, depth, target, texture_type, DRAW_JIT_TEXTURE_DEPTH); + LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, first_level, + target, texture_type, + DRAW_JIT_TEXTURE_FIRST_LEVEL); LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, last_level, target, texture_type, DRAW_JIT_TEXTURE_LAST_LEVEL); @@ -438,7 +442,8 @@ generate_vs(struct draw_llvm *llvm, const LLVMValueRef (*inputs)[NUM_CHANNELS], LLVMValueRef system_values_array, LLVMValueRef context_ptr, - struct lp_build_sampler_soa *draw_sampler) + struct lp_build_sampler_soa *draw_sampler, + boolean clamp_vertex_color) { const struct tgsi_token *tokens = llvm->draw->vs.vertex_shader->state.tokens; struct lp_type vs_type; @@ -474,6 +479,30 @@ generate_vs(struct draw_llvm *llvm, outputs, sampler, &llvm->draw->vs.vertex_shader->info); + + if(clamp_vertex_color) + { + LLVMValueRef out; + unsigned chan, attrib; + struct lp_build_context bld; + struct tgsi_shader_info* info = &llvm->draw->vs.vertex_shader->info; + lp_build_context_init(&bld, llvm->gallivm, vs_type); + + for (attrib = 0; attrib < info->num_outputs; ++attrib) { + for(chan = 0; chan < NUM_CHANNELS; ++chan) { + if(outputs[attrib][chan]) { + switch (info->output_semantic_name[attrib]) { + case TGSI_SEMANTIC_COLOR: + case TGSI_SEMANTIC_BCOLOR: + out = LLVMBuildLoad(builder, outputs[attrib][chan], ""); + out = lp_build_clamp(&bld, out, bld.zero, bld.one); + LLVMBuildStore(builder, out, outputs[attrib][chan]); + break; + } + } + } + } + } } #if DEBUG_STORE @@ -1235,7 +1264,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) ptr_aos, system_values_array, context_ptr, - sampler); + sampler, + variant->key.clamp_vertex_color); /* store original positions in clip before further manipulation */ store_clip(gallivm, io, outputs); @@ -1446,7 +1476,8 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian ptr_aos, system_values_array, context_ptr, - sampler); + sampler, + variant->key.clamp_vertex_color); /* store original positions in clip before further manipulation */ store_clip(gallivm, io, outputs); @@ -1524,6 +1555,8 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store) key = (struct draw_llvm_variant_key *)store; + key->clamp_vertex_color = llvm->draw->rasterizer->clamp_vertex_color; /**/ + /* Presumably all variants of the shader should have the same * number of vertex elements - ie the number of shader inputs. */ @@ -1566,7 +1599,7 @@ void draw_llvm_set_mapped_texture(struct draw_context *draw, unsigned sampler_idx, uint32_t width, uint32_t height, uint32_t depth, - uint32_t last_level, + uint32_t first_level, uint32_t last_level, uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS], uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS], const void *data[PIPE_MAX_TEXTURE_LEVELS]) @@ -1582,9 +1615,10 @@ draw_llvm_set_mapped_texture(struct draw_context *draw, jit_tex->width = width; jit_tex->height = height; jit_tex->depth = depth; + jit_tex->first_level = first_level; jit_tex->last_level = last_level; - for (j = 0; j <= last_level; j++) { + for (j = first_level; j <= last_level; j++) { jit_tex->data[j] = data[j]; jit_tex->row_stride[j] = row_stride[j]; jit_tex->img_stride[j] = img_stride[j]; diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h index e8623e7bcdc..375b7b8b571 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.h +++ b/src/gallium/auxiliary/draw/draw_llvm.h @@ -50,6 +50,7 @@ struct draw_jit_texture uint32_t width; uint32_t height; uint32_t depth; + uint32_t first_level; uint32_t last_level; uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS]; uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS]; @@ -64,6 +65,7 @@ enum { DRAW_JIT_TEXTURE_WIDTH = 0, DRAW_JIT_TEXTURE_HEIGHT, DRAW_JIT_TEXTURE_DEPTH, + DRAW_JIT_TEXTURE_FIRST_LEVEL, DRAW_JIT_TEXTURE_LAST_LEVEL, DRAW_JIT_TEXTURE_ROW_STRIDE, DRAW_JIT_TEXTURE_IMG_STRIDE, @@ -162,6 +164,7 @@ struct draw_llvm_variant_key { unsigned nr_vertex_elements:8; unsigned nr_samplers:8; + unsigned clamp_vertex_color:1; unsigned clip_xy:1; unsigned clip_z:1; unsigned clip_user:1; @@ -169,7 +172,7 @@ struct draw_llvm_variant_key unsigned bypass_viewport:1; unsigned need_edgeflags:1; unsigned nr_planes:4; - unsigned pad:6; + unsigned pad:5; /* Variable number of vertex elements: */ @@ -295,7 +298,7 @@ void draw_llvm_set_mapped_texture(struct draw_context *draw, unsigned sampler_idx, uint32_t width, uint32_t height, uint32_t depth, - uint32_t last_level, + uint32_t first_level, uint32_t last_level, uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS], uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS], const void *data[PIPE_MAX_TEXTURE_LEVELS]); diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c b/src/gallium/auxiliary/draw/draw_llvm_sample.c index 574c7cc452f..8af34617353 100644 --- a/src/gallium/auxiliary/draw/draw_llvm_sample.c +++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c @@ -144,6 +144,7 @@ draw_llvm_texture_member(const struct lp_sampler_dynamic_state *base, DRAW_LLVM_TEXTURE_MEMBER(width, DRAW_JIT_TEXTURE_WIDTH, TRUE) DRAW_LLVM_TEXTURE_MEMBER(height, DRAW_JIT_TEXTURE_HEIGHT, TRUE) DRAW_LLVM_TEXTURE_MEMBER(depth, DRAW_JIT_TEXTURE_DEPTH, TRUE) +DRAW_LLVM_TEXTURE_MEMBER(first_level,DRAW_JIT_TEXTURE_FIRST_LEVEL, TRUE) DRAW_LLVM_TEXTURE_MEMBER(last_level, DRAW_JIT_TEXTURE_LAST_LEVEL, TRUE) DRAW_LLVM_TEXTURE_MEMBER(row_stride, DRAW_JIT_TEXTURE_ROW_STRIDE, FALSE) DRAW_LLVM_TEXTURE_MEMBER(img_stride, DRAW_JIT_TEXTURE_IMG_STRIDE, FALSE) @@ -209,6 +210,7 @@ draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state, sampler->dynamic_state.base.width = draw_llvm_texture_width; sampler->dynamic_state.base.height = draw_llvm_texture_height; sampler->dynamic_state.base.depth = draw_llvm_texture_depth; + sampler->dynamic_state.base.first_level = draw_llvm_texture_first_level; sampler->dynamic_state.base.last_level = draw_llvm_texture_last_level; sampler->dynamic_state.base.row_stride = draw_llvm_texture_row_stride; sampler->dynamic_state.base.img_stride = draw_llvm_texture_img_stride; diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 58c5858734a..61ae4665539 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -341,6 +341,16 @@ vbuf_flush_vertices( struct vbuf_stage *vbuf ) vbuf->max_vertices = vbuf->nr_vertices = 0; vbuf->vertex_ptr = vbuf->vertices = NULL; } + + /* Reset point/line/tri function pointers. + * If (for example) we transition from points to tris and back to points + * again, we need to call the vbuf_first_point() function again to flush + * the triangles before drawing more points. This can happen when drawing + * with front polygon mode = filled and back polygon mode = line or point. + */ + vbuf->stage.point = vbuf_first_point; + vbuf->stage.line = vbuf_first_line; + vbuf->stage.tri = vbuf_first_tri; } @@ -378,10 +388,6 @@ vbuf_flush( struct draw_stage *stage, unsigned flags ) struct vbuf_stage *vbuf = vbuf_stage( stage ); vbuf_flush_vertices( vbuf ); - - stage->point = vbuf_first_point; - stage->line = vbuf_first_line; - stage->tri = vbuf_first_tri; } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index db2e3c5410d..b7d693f8584 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -146,6 +146,14 @@ struct draw_context struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; unsigned nr_vertex_buffers; + /* + * This is the largest legal index value for the current set of + * bound vertex buffers. Regardless of any other consideration, + * all vertex lookups need to be clamped to 0..max_index to + * prevent out-of-bound access. + */ + unsigned max_index; + struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; unsigned nr_vertex_elements; diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index c3d7e871f7a..e0eda67c1a2 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -470,6 +470,17 @@ draw_vbo(struct draw_context *draw, if (0) draw_print_arrays(draw, info->mode, info->start, MIN2(info->count, 20)); + draw->pt.max_index = util_draw_max_index(draw->pt.vertex_buffer, + draw->pt.nr_vertex_buffers, + draw->pt.vertex_element, + draw->pt.nr_vertex_elements, + info); + + /* + * TODO: We could use draw->pt.max_index to further narrow + * the min_index/max_index hints given by the state tracker. + */ + for (instance = 0; instance < info->instance_count; instance++) { draw->instance_id = instance + info->start_instance; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 4fa3b265e10..5589a8212e4 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -139,7 +139,7 @@ void draw_pt_fetch_run( struct pt_fetch *fetch, ((char *)draw->pt.user.vbuffer[i] + draw->pt.vertex_buffer[i].buffer_offset), draw->pt.vertex_buffer[i].stride, - draw->pt.user.max_index); + draw->pt.max_index); } translate->run_elts( translate, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 51043102a61..0ab11d015c6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -186,7 +186,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, ((char *)draw->pt.user.vbuffer[i] + draw->pt.vertex_buffer[i].buffer_offset), draw->pt.vertex_buffer[i].stride, - draw->pt.user.max_index); + draw->pt.max_index); } *max_vertices = (draw->render->max_vertex_buffer_bytes / diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 1e926fb028e..0dbbfe2b73c 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -169,7 +169,7 @@ static void fse_prepare( struct draw_pt_middle_end *middle, ((const ubyte *) draw->pt.user.vbuffer[i] + draw->pt.vertex_buffer[i].buffer_offset), draw->pt.vertex_buffer[i].stride, - draw->pt.user.max_index ); + draw->pt.max_index ); } *max_vertices = (draw->render->max_vertex_buffer_bytes / diff --git a/src/gallium/auxiliary/draw/draw_pt_vsplit.c b/src/gallium/auxiliary/draw/draw_pt_vsplit.c index a6875253094..c19dcd9e1f7 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vsplit.c +++ b/src/gallium/auxiliary/draw/draw_pt_vsplit.c @@ -85,7 +85,12 @@ vsplit_flush_cache(struct vsplit_frontend *vsplit, unsigned flags) static INLINE void vsplit_add_cache(struct vsplit_frontend *vsplit, unsigned fetch) { - unsigned hash = fetch % MAP_SIZE; + struct draw_context *draw = vsplit->draw; + unsigned hash; + + fetch = MIN2(fetch, draw->pt.max_index); + + hash = fetch % MAP_SIZE; if (vsplit->cache.fetches[hash] != fetch) { /* update cache */ diff --git a/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h index 75dba8c39a5..bb3cbf80ad7 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h @@ -47,14 +47,18 @@ CONCAT(vsplit_primitive_, ELT_TYPE)(struct vsplit_frontend *vsplit, const ushort *draw_elts = NULL; unsigned i; + ib += istart; + /* use the ib directly */ if (min_index == 0 && sizeof(ib[0]) == sizeof(draw_elts[0])) { if (icount > vsplit->max_vertices) return FALSE; for (i = 0; i < icount; i++) { - ELT_TYPE idx = ib[istart + i]; - assert(idx >= min_index && idx <= max_index); + ELT_TYPE idx = ib[i]; + if (idx < min_index || idx > max_index) { + debug_printf("warning: index out of range\n"); + } } draw_elts = (const ushort *) ib; } @@ -83,17 +87,21 @@ CONCAT(vsplit_primitive_, ELT_TYPE)(struct vsplit_frontend *vsplit, if (!draw_elts) { if (min_index == 0) { for (i = 0; i < icount; i++) { - ELT_TYPE idx = ib[istart + i]; + ELT_TYPE idx = ib[i]; - assert(idx >= min_index && idx <= max_index); + if (idx < min_index || idx > max_index) { + debug_printf("warning: index out of range\n"); + } vsplit->draw_elts[i] = (ushort) idx; } } else { for (i = 0; i < icount; i++) { - ELT_TYPE idx = ib[istart + i]; + ELT_TYPE idx = ib[i]; - assert(idx >= min_index && idx <= max_index); + if (idx < min_index || idx > max_index) { + debug_printf("warning: index out of range\n"); + } vsplit->draw_elts[i] = (ushort) (idx - min_index); } } diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index 7caad6f0053..1763dbc199f 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -104,11 +104,18 @@ draw_create_vertex_shader(struct draw_context *draw, } if (!draw->pt.middle.llvm) { +#if 0 +/* these paths don't support vertex clamping + * TODO: either add it, or remove them completely + * use LLVM instead if you want performance + * use exec instead if you want debugging/more correctness + */ #if defined(PIPE_ARCH_X86) vs = draw_create_vs_sse( draw, shader ); #elif defined(PIPE_ARCH_PPC) vs = draw_create_vs_ppc( draw, shader ); #endif +#endif } #if HAVE_LLVM else { diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index c41d7c42a01..d9c4209a42b 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -95,6 +95,7 @@ vs_exec_run_linear( struct draw_vertex_shader *shader, struct tgsi_exec_machine *machine = evs->machine; unsigned int i, j; unsigned slot; + boolean clamp_vertex_color = shader->draw->rasterizer->clamp_vertex_color; tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, constants, const_size); @@ -151,11 +152,22 @@ vs_exec_run_linear( struct draw_vertex_shader *shader, */ for (j = 0; j < max_vertices; j++) { for (slot = 0; slot < shader->info.num_outputs; slot++) { - output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; - + unsigned name = shader->info.output_semantic_name[slot]; + if(clamp_vertex_color && + (name == TGSI_SEMANTIC_COLOR || name == TGSI_SEMANTIC_BCOLOR)) + { + output[slot][0] = CLAMP(machine->Outputs[slot].xyzw[0].f[j], 0.0f, 1.0f); + output[slot][1] = CLAMP(machine->Outputs[slot].xyzw[1].f[j], 0.0f, 1.0f); + output[slot][2] = CLAMP(machine->Outputs[slot].xyzw[2].f[j], 0.0f, 1.0f); + output[slot][3] = CLAMP(machine->Outputs[slot].xyzw[3].f[j], 0.0f, 1.0f); + } + else + { + output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } } #if 0 |