[Mesa-dev] [PATCH 1/5] etnaviv: add support for user index buffers

Nicolai Hähnle nhaehnle at gmail.com
Tue Feb 21 08:36:44 UTC 2017


On 20.02.2017 19:03, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> v2: fix a bug in u_helpers

Would've been nice to be more specific here. Anyway, the change is fine:

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at 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..e195576 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 (!new_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..d5bf106 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.ib,
> +                                          &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:
>



More information about the mesa-dev mailing list