From 2d6713c6cd1c9be74f18e147da42ebd2cce8096f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 3 Aug 2018 16:20:43 +1000 Subject: [PATCH] vrend: Enhanced layout support. The enhanced layout extension allows for gaps in the streamout bindings so we have to be able to handle no-handles in the middle of the target array. TGSI also has to deal with components outputs where multiple outputs can be mentioned in the TGSI. It's safe for use to just skip the extra outputs at least for the tests I've been able to run. Once we have those changes in place, the renderer can expose the new CAP bit to the host without any further host extension checks. Reviewed-by: Jakob Bornecrantz Signed-off-by: Jakob Bornecrantz --- src/virgl_hw.h | 1 + src/vrend_renderer.c | 8 +++++++- src/vrend_shader.c | 12 ++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/virgl_hw.h b/src/virgl_hw.h index 787452d..9a358dd 100644 --- a/src/virgl_hw.h +++ b/src/virgl_hw.h @@ -230,6 +230,7 @@ enum virgl_formats { #define VIRGL_CAP_TGSI_FBFETCH (1 << 10) #define VIRGL_CAP_SHADER_CLOCK (1 << 11) #define VIRGL_CAP_TEXTURE_BARRIER (1 << 12) +#define VIRGL_CAP_TGSI_COMPONENTS (1 << 13) /* virgl bind flags - these are compatible with mesa 10.5 gallium. * but are fixed, no other should be passed to virgl either. diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index c33076f..59bdb42 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -6750,7 +6750,9 @@ static void vrend_hw_emit_streamout_targets(UNUSED struct vrend_context *ctx, st uint i; for (i = 0; i < so_obj->num_targets; i++) { - if (so_obj->so_targets[i]->buffer_offset || so_obj->so_targets[i]->buffer_size < so_obj->so_targets[i]->buffer->base.width0) + if (!so_obj->so_targets[i]) + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, 0); + else if (so_obj->so_targets[i]->buffer_offset || so_obj->so_targets[i]->buffer_size < so_obj->so_targets[i]->buffer->base.width0) glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, so_obj->so_targets[i]->buffer->id, so_obj->so_targets[i]->buffer_offset, so_obj->so_targets[i]->buffer_size); else glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, so_obj->so_targets[i]->buffer->id); @@ -6793,6 +6795,8 @@ void vrend_set_streamout_targets(struct vrend_context *ctx, obj->num_targets = num_targets; for (i = 0; i < num_targets; i++) { obj->handles[i] = handles[i]; + if (handles[i] == 0) + continue; target = vrend_object_lookup(ctx->sub->object_hash, handles[i], VIRGL_OBJECT_STREAMOUT_TARGET); if (!target) { report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_HANDLE, handles[i]); @@ -8201,6 +8205,8 @@ static void vrend_renderer_fill_caps_v2(int gl_ver, int gles_ver, union virgl_c if (has_feature(feat_texture_barrier)) caps->v2.capability_bits |= VIRGL_CAP_TEXTURE_BARRIER; + /* always enable this since it doesn't require an ext to pass tests */ + caps->v2.capability_bits |= VIRGL_CAP_TGSI_COMPONENTS; } void vrend_renderer_fill_caps(uint32_t set, UNUSED uint32_t version, diff --git a/src/vrend_shader.c b/src/vrend_shader.c index 367135e..d8b45e9 100644 --- a/src/vrend_shader.c +++ b/src/vrend_shader.c @@ -683,6 +683,12 @@ iter_declaration(struct tgsi_iterate_context *iter, switch (decl->Declaration.File) { case TGSI_FILE_INPUT: + for (uint32_t j = 0; j < ctx->num_inputs; j++) { + if (ctx->inputs[j].name == decl->Semantic.Name && + ctx->inputs[j].sid == decl->Semantic.Index && + ctx->inputs[j].first == decl->Range.First) + return TRUE; + } i = ctx->num_inputs++; indirect = ctx_indirect_inputs(ctx); if (ctx->num_inputs > ARRAY_SIZE(ctx->inputs)) { @@ -923,6 +929,12 @@ iter_declaration(struct tgsi_iterate_context *iter, } break; case TGSI_FILE_OUTPUT: + for (uint32_t j = 0; j < ctx->num_outputs; j++) { + if (ctx->outputs[j].name == decl->Semantic.Name && + ctx->outputs[j].sid == decl->Semantic.Index && + ctx->outputs[j].first == decl->Range.First) + return TRUE; + } i = ctx->num_outputs++; indirect = ctx_indirect_outputs(ctx); if (ctx->num_outputs > ARRAY_SIZE(ctx->outputs)) {