From: Marek Olšák <marek.ol...@amd.com> --- src/gallium/auxiliary/util/u_helpers.c | 29 +++++++++++++++++++++++++++ src/gallium/auxiliary/util/u_helpers.h | 5 +++++ src/gallium/drivers/etnaviv/etnaviv_context.c | 12 +++++++++++ src/gallium/drivers/etnaviv/etnaviv_screen.c | 2 +- 4 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/src/gallium/auxiliary/util/u_helpers.c b/src/gallium/auxiliary/util/u_helpers.c index 09020b0..85e7fb0 100644 --- a/src/gallium/auxiliary/util/u_helpers.c +++ b/src/gallium/auxiliary/util/u_helpers.c @@ -20,20 +20,21 @@ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR * 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 "util/u_helpers.h" #include "util/u_inlines.h" +#include "util/u_upload_mgr.h" /** * This function is used to copy an array of pipe_vertex_buffer structures, * while properly referencing the pipe_vertex_buffer::buffer member. * * enabled_buffers is updated such that the bits corresponding to the indices * of disabled buffers are set to 0 and the enabled ones are set to 1. * * \sa util_copy_framebuffer_state */ @@ -102,10 +103,38 @@ util_set_index_buffer(struct pipe_index_buffer *dst, { if (src) { pipe_resource_reference(&dst->buffer, src->buffer); memcpy(dst, src, sizeof(*dst)); } else { pipe_resource_reference(&dst->buffer, NULL); memset(dst, 0, sizeof(*dst)); } } + +/** + * Given a user index buffer, save the structure to "saved", and upload it. + */ +bool +util_save_and_upload_index_buffer(struct pipe_context *pipe, + const struct pipe_draw_info *info, + const struct pipe_index_buffer *ib, + struct pipe_index_buffer *out_saved) +{ + struct pipe_index_buffer new_ib = {0}; + unsigned start_offset = info->start * ib->index_size; + + u_upload_data(pipe->stream_uploader, start_offset, + info->count * ib->index_size, 4, + (char*)ib->user_buffer + start_offset, + &new_ib.offset, &new_ib.buffer); + if (!ib->buffer) + return false; + u_upload_unmap(pipe->stream_uploader); + + new_ib.offset -= start_offset; + new_ib.index_size = ib->index_size; + + util_set_index_buffer(out_saved, ib); + pipe->set_index_buffer(pipe, &new_ib); + return true; +} diff --git a/src/gallium/auxiliary/util/u_helpers.h b/src/gallium/auxiliary/util/u_helpers.h index a9a53e4..7de960b 100644 --- a/src/gallium/auxiliary/util/u_helpers.h +++ b/src/gallium/auxiliary/util/u_helpers.h @@ -40,15 +40,20 @@ void util_set_vertex_buffers_mask(struct pipe_vertex_buffer *dst, unsigned start_slot, unsigned count); void util_set_vertex_buffers_count(struct pipe_vertex_buffer *dst, unsigned *dst_count, const struct pipe_vertex_buffer *src, unsigned start_slot, unsigned count); void util_set_index_buffer(struct pipe_index_buffer *dst, const struct pipe_index_buffer *src); +bool util_save_and_upload_index_buffer(struct pipe_context *pipe, + const struct pipe_draw_info *info, + const struct pipe_index_buffer *ib, + struct pipe_index_buffer *out_saved); + #ifdef __cplusplus } #endif #endif diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c index 62297a0..d22939a 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.c +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c @@ -40,20 +40,21 @@ #include "etnaviv_state.h" #include "etnaviv_surface.h" #include "etnaviv_texture.h" #include "etnaviv_transfer.h" #include "etnaviv_translate.h" #include "etnaviv_zsa.h" #include "pipe/p_context.h" #include "pipe/p_state.h" #include "util/u_blitter.h" +#include "util/u_helpers.h" #include "util/u_memory.h" #include "util/u_prim.h" #include "util/u_upload_mgr.h" #include "hw/common.xml.h" static void etna_context_destroy(struct pipe_context *pctx) { struct etna_context *ctx = etna_context(pctx); @@ -130,20 +131,29 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) DBG("Invalid draw primitive mode=%i or no primitives to be drawn", info->mode); return; } draw_mode = translate_draw_mode(info->mode); if (draw_mode == ETNA_NO_MATCH) { BUG("Unsupported draw mode"); return; } + /* Upload a user index buffer. */ + struct pipe_index_buffer ibuffer_saved = {}; + if (info->indexed && ctx->index_buffer.ib.user_buffer && + !util_save_and_upload_index_buffer(pctx, info, &ctx->index_buffer, + &ibuffer_saved)) { + BUG("Index buffer upload failed."); + return; + } + if (info->indexed && !ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.bo) { BUG("Unsupported or no index buffer"); return; } /* Update any derived state */ if (!etna_state_update(ctx)) return; /* @@ -204,20 +214,22 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) etna_stall(ctx->stream, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); } if (DBG_ENABLED(ETNA_DBG_FLUSH_ALL)) pctx->flush(pctx, NULL, 0); if (ctx->framebuffer.cbuf) etna_resource(ctx->framebuffer.cbuf->texture)->seqno++; if (ctx->framebuffer.zsbuf) etna_resource(ctx->framebuffer.zsbuf->texture)->seqno++; + if (info->indexed && ibuffer_saved.user_buffer) + pctx->set_index_buffer(pctx, &ibuffer_saved); } static void etna_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence, enum pipe_flush_flags flags) { struct etna_context *ctx = etna_context(pctx); etna_cmd_stream_flush(ctx->stream); diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c index c277f64..93eeb58 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c @@ -129,20 +129,21 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: case PIPE_CAP_SM3: case PIPE_CAP_TEXTURE_BARRIER: case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: case PIPE_CAP_USER_CONSTANT_BUFFERS: case PIPE_CAP_TGSI_TEXCOORD: case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: + case PIPE_CAP_USER_INDEX_BUFFERS: return 1; /* Memory */ case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: return 256; case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: return 4; /* XXX could easily be supported */ case PIPE_CAP_GLSL_FEATURE_LEVEL: return 120; @@ -173,21 +174,20 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_INDEP_BLEND_ENABLE: case PIPE_CAP_INDEP_BLEND_FUNC: case PIPE_CAP_DEPTH_CLIP_DISABLE: case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: /* Don't skip strict max uniform limit check */ case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: case PIPE_CAP_VERTEX_COLOR_CLAMPED: case PIPE_CAP_USER_VERTEX_BUFFERS: - case PIPE_CAP_USER_INDEX_BUFFERS: case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY: case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: /* TODO: test me out with piglit */ case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT: case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: case PIPE_CAP_TEXTURE_GATHER_SM5: case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: case PIPE_CAP_FAKE_SW_MSAA: case PIPE_CAP_TEXTURE_QUERY_LOD: -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev