X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_draw_feedback.c;h=c70599a10c7aac8e7e74a6d4aa0c45a284217706;hb=627c01977c29d142d5024591bf910a1ed92814c9;hp=fccb3dbdc4a25ad21adea3696132cde37b973d10;hpb=e91b044bd824b1c74e8e6e7df3e37be96e5e7f9b;p=mesa.git diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index fccb3dbdc4a..c70599a10c7 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2007 VMware, Inc. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,10 +22,10 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ -#include "main/imports.h" + #include "main/arrayobj.h" #include "main/image.h" #include "main/macros.h" @@ -100,18 +100,19 @@ st_feedback_draw_vbo(struct gl_context *ctx, GLboolean index_bounds_valid, GLuint min_index, GLuint max_index, + GLuint num_instances, + GLuint base_instance, struct gl_transform_feedback_object *tfb_vertcount, - unsigned stream, - struct gl_buffer_object *indirect) + unsigned stream) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; struct draw_context *draw = st_get_draw_context(st); const struct st_vertex_program *vp; - struct st_vp_variant *vp_variant; + struct st_common_variant *vp_variant; struct pipe_vertex_buffer vbuffers[PIPE_MAX_SHADER_INPUTS]; unsigned num_vbuffers = 0; - struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; + struct cso_velems_state velements; struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {NULL}; struct pipe_transfer *ib_transfer = NULL; GLuint i; @@ -133,20 +134,17 @@ st_feedback_draw_vbo(struct gl_context *ctx, st_validate_state(st, ST_PIPELINE_RENDER); - if (!index_bounds_valid) + if (ib && !index_bounds_valid) vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, nr_prims); /* must get these after state validation! */ - vp = (struct st_vertex_program *)st->vp; - vp_variant = st->vp_variant; + struct st_common_variant_key key; + /* We have to use memcpy to make sure that all bits are copied. */ + memcpy(&key, &st->vp_variant->key, sizeof(key)); + key.is_draw_shader = true; - struct pipe_shader_state state = {0}; - state.type = PIPE_SHADER_IR_TGSI; - state.tokens = vp_variant->tokens; - - if (!vp_variant->draw_shader) { - vp_variant->draw_shader = draw_create_vertex_shader(draw, &state); - } + vp = (struct st_vertex_program *)st->vp; + vp_variant = st_get_vp_variant(st, st->vp, &key); /* * Set up the draw module's state. @@ -158,14 +156,16 @@ st_feedback_draw_vbo(struct gl_context *ctx, draw_set_viewport_states(draw, 0, 1, &st->state.viewport[0]); draw_set_clip_state(draw, &st->state.clip); draw_set_rasterizer_state(draw, &st->state.rasterizer, NULL); - draw_bind_vertex_shader(draw, vp_variant->draw_shader); + draw_bind_vertex_shader(draw, vp_variant->base.driver_shader); set_feedback_vertex_format(ctx); /* Must setup these after state validation! */ /* Setup arrays */ - st_setup_arrays(st, vp, vp_variant, velements, vbuffers, &num_vbuffers); + bool uses_user_vertex_buffers; + st_setup_arrays(st, vp, vp_variant, &velements, vbuffers, &num_vbuffers, + &uses_user_vertex_buffers); /* Setup current values as userspace arrays */ - st_setup_current_user(st, vp, vp_variant, velements, vbuffers, &num_vbuffers); + st_setup_current_user(st, vp, vp_variant, &velements, vbuffers, &num_vbuffers); /* Map all buffers and tell draw about their mapping */ for (unsigned buf = 0; buf < num_vbuffers; ++buf) { @@ -182,13 +182,13 @@ st_feedback_draw_vbo(struct gl_context *ctx, } draw_set_vertex_buffers(draw, 0, num_vbuffers, vbuffers); - draw_set_vertex_elements(draw, vp->num_inputs, velements); + draw_set_vertex_elements(draw, vp->num_inputs, velements.velems); unsigned start = 0; if (ib) { struct gl_buffer_object *bufobj = ib->obj; - unsigned index_size = ib->index_size; + unsigned index_size = 1 << ib->index_size_shift; if (index_size == 0) goto out_unref_vertex; @@ -196,7 +196,7 @@ st_feedback_draw_vbo(struct gl_context *ctx, if (bufobj && bufobj->Name) { struct st_buffer_object *stobj = st_buffer_object(bufobj); - start = pointer_to_offset(ib->ptr) / index_size; + start = pointer_to_offset(ib->ptr) >> ib->index_size_shift; mapped_indices = pipe_buffer_map(pipe, stobj->buffer, PIPE_TRANSFER_READ, &ib_transfer); } @@ -204,7 +204,7 @@ st_feedback_draw_vbo(struct gl_context *ctx, mapped_indices = ib->ptr; } - info.index_size = ib->index_size; + info.index_size = index_size; info.min_index = min_index; info.max_index = max_index; info.has_user_indices = true; @@ -216,7 +216,7 @@ st_feedback_draw_vbo(struct gl_context *ctx, if (ctx->Array._PrimitiveRestart) { info.primitive_restart = true; - info.restart_index = _mesa_primitive_restart_index(ctx, info.index_size); + info.restart_index = ctx->Array._RestartIndex[index_size - 1]; } } else { info.index_size = 0; @@ -232,7 +232,7 @@ st_feedback_draw_vbo(struct gl_context *ctx, struct pipe_transfer *ubo_transfer[PIPE_MAX_CONSTANT_BUFFERS] = {0}; assert(prog->info.num_ubos <= ARRAY_SIZE(ubo_transfer)); - for (unsigned i = 0; i < prog->info.num_ubos; i++) { + for (unsigned i = 0; i < prog->sh.NumUniformBlocks; i++) { struct gl_buffer_binding *binding = &st->ctx->UniformBufferBindings[prog->sh.UniformBlocks[i]->Binding]; struct st_buffer_object *st_obj = st_buffer_object(binding->BufferObject); @@ -257,6 +257,36 @@ st_feedback_draw_vbo(struct gl_context *ctx, size); } + /* shader buffers */ + /* TODO: atomic counter buffers */ + struct pipe_transfer *ssbo_transfer[PIPE_MAX_SHADER_BUFFERS] = {0}; + + for (unsigned i = 0; i < prog->info.num_ssbos; i++) { + struct gl_buffer_binding *binding = + &st->ctx->ShaderStorageBufferBindings[ + prog->sh.ShaderStorageBlocks[i]->Binding]; + struct st_buffer_object *st_obj = st_buffer_object(binding->BufferObject); + struct pipe_resource *buf = st_obj->buffer; + + if (!buf) + continue; + + unsigned offset = binding->Offset; + unsigned size = buf->width0 - binding->Offset; + + /* AutomaticSize is FALSE if the buffer was set with BindBufferRange. + * Take the minimum just to be sure. + */ + if (!binding->AutomaticSize) + size = MIN2(size, (unsigned) binding->Size); + + void *ptr = pipe_buffer_map_range(pipe, buf, offset, size, + PIPE_TRANSFER_READ, &ssbo_transfer[i]); + + draw_set_mapped_shader_buffer(draw, PIPE_SHADER_VERTEX, + i, ptr, size); + } + /* samplers */ struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS]; for (unsigned i = 0; i < st->state.num_vert_samplers; i++) @@ -340,10 +370,60 @@ st_feedback_draw_vbo(struct gl_context *ctx, draw_set_mapped_texture(draw, PIPE_SHADER_VERTEX, i, width0, res->height0, num_layers, first_level, - last_level, (void*)base_addr, row_stride, + last_level, 0, 0, (void*)base_addr, row_stride, img_stride, mip_offset); } + /* shader images */ + struct pipe_image_view images[PIPE_MAX_SHADER_IMAGES]; + struct pipe_transfer *img_transfer[PIPE_MAX_SHADER_IMAGES] = {0}; + + for (unsigned i = 0; i < prog->info.num_images; i++) { + struct pipe_image_view *img = &images[i]; + + st_convert_image_from_unit(st, img, prog->sh.ImageUnits[i], + prog->sh.ImageAccess[i]); + + struct pipe_resource *res = img->resource; + if (!res) + continue; + + unsigned width, height, num_layers, row_stride, img_stride; + void *addr; + + if (res->target != PIPE_BUFFER) { + width = u_minify(res->width0, img->u.tex.level); + height = u_minify(res->height0, img->u.tex.level); + num_layers = img->u.tex.last_layer - img->u.tex.first_layer + 1; + + addr = pipe_transfer_map_3d(pipe, res, img->u.tex.level, + PIPE_TRANSFER_READ, 0, 0, + img->u.tex.first_layer, + width, height, num_layers, + &img_transfer[i]); + row_stride = img_transfer[i]->stride; + img_stride = img_transfer[i]->layer_stride; + } else { + width = img->u.buf.size / util_format_get_blocksize(img->format); + + /* probably don't really need to fill that out */ + row_stride = 0; + img_stride = 0; + height = num_layers = 1; + + addr = pipe_buffer_map_range(pipe, res, img->u.buf.offset, + img->u.buf.size, PIPE_TRANSFER_READ, + &img_transfer[i]); + } + + draw_set_mapped_image(draw, PIPE_SHADER_VERTEX, i, width, height, + num_layers, addr, row_stride, img_stride, 0, 0); + } + draw_set_images(draw, PIPE_SHADER_VERTEX, images, prog->info.num_images); + + info.start_instance = base_instance; + info.instance_count = num_instances; + /* draw here */ for (i = 0; i < nr_prims; i++) { info.count = prims[i].count; @@ -353,8 +433,6 @@ st_feedback_draw_vbo(struct gl_context *ctx, info.mode = prims[i].mode; info.start = start + prims[i].start; - info.start_instance = prims[i].base_instance; - info.instance_count = prims[i].num_instances; info.index_bias = prims[i].basevertex; info.drawid = prims[i].draw_id; if (!ib) { @@ -365,6 +443,14 @@ st_feedback_draw_vbo(struct gl_context *ctx, draw_vbo(draw, &info); } + /* unmap images */ + for (unsigned i = 0; i < prog->info.num_images; i++) { + if (img_transfer[i]) { + draw_set_mapped_image(draw, PIPE_SHADER_VERTEX, i, 0, 0, 0, NULL, 0, 0, 0, 0); + pipe_transfer_unmap(pipe, img_transfer[i]); + } + } + /* unmap sampler views */ for (unsigned i = 0; i < st->state.num_sampler_views[PIPE_SHADER_VERTEX]; i++) { struct pipe_sampler_view *view = st->state.vert_sampler_views[i]; @@ -384,6 +470,14 @@ st_feedback_draw_vbo(struct gl_context *ctx, draw_set_samplers(draw, PIPE_SHADER_VERTEX, NULL, 0); draw_set_sampler_views(draw, PIPE_SHADER_VERTEX, NULL, 0); + for (unsigned i = 0; i < prog->info.num_ssbos; i++) { + if (ssbo_transfer[i]) { + draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 1 + i, + NULL, 0); + pipe_buffer_unmap(pipe, ssbo_transfer[i]); + } + } + for (unsigned i = 0; i < prog->info.num_ubos; i++) { if (ubo_transfer[i]) { draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 1 + i,