[Mesa-dev] [PATCH 1/5] etnaviv: add support for user index buffers
Marek Olšák
maraeo at gmail.com
Mon Feb 20 18:03:59 UTC 2017
From: Marek Olšák <marek.olsak at amd.com>
v2: fix a bug in u_helpers
---
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:
--
2.7.4
More information about the mesa-dev
mailing list