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 <jakob@collabora.com>
Signed-off-by: Jakob Bornecrantz <jakob@collabora.com>
macos/master
Dave Airlie 6 years ago committed by Jakob Bornecrantz
parent 4553faf23a
commit 2d6713c6cd
  1. 1
      src/virgl_hw.h
  2. 8
      src/vrend_renderer.c
  3. 12
      src/vrend_shader.c

@ -230,6 +230,7 @@ enum virgl_formats {
#define VIRGL_CAP_TGSI_FBFETCH (1 << 10) #define VIRGL_CAP_TGSI_FBFETCH (1 << 10)
#define VIRGL_CAP_SHADER_CLOCK (1 << 11) #define VIRGL_CAP_SHADER_CLOCK (1 << 11)
#define VIRGL_CAP_TEXTURE_BARRIER (1 << 12) #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. /* virgl bind flags - these are compatible with mesa 10.5 gallium.
* but are fixed, no other should be passed to virgl either. * but are fixed, no other should be passed to virgl either.

@ -6750,7 +6750,9 @@ static void vrend_hw_emit_streamout_targets(UNUSED struct vrend_context *ctx, st
uint i; uint i;
for (i = 0; i < so_obj->num_targets; 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); 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 else
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, so_obj->so_targets[i]->buffer->id); 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; obj->num_targets = num_targets;
for (i = 0; i < num_targets; i++) { for (i = 0; i < num_targets; i++) {
obj->handles[i] = handles[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); target = vrend_object_lookup(ctx->sub->object_hash, handles[i], VIRGL_OBJECT_STREAMOUT_TARGET);
if (!target) { if (!target) {
report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_HANDLE, handles[i]); 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)) if (has_feature(feat_texture_barrier))
caps->v2.capability_bits |= VIRGL_CAP_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, void vrend_renderer_fill_caps(uint32_t set, UNUSED uint32_t version,

@ -683,6 +683,12 @@ iter_declaration(struct tgsi_iterate_context *iter,
switch (decl->Declaration.File) { switch (decl->Declaration.File) {
case TGSI_FILE_INPUT: 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++; i = ctx->num_inputs++;
indirect = ctx_indirect_inputs(ctx); indirect = ctx_indirect_inputs(ctx);
if (ctx->num_inputs > ARRAY_SIZE(ctx->inputs)) { if (ctx->num_inputs > ARRAY_SIZE(ctx->inputs)) {
@ -923,6 +929,12 @@ iter_declaration(struct tgsi_iterate_context *iter,
} }
break; break;
case TGSI_FILE_OUTPUT: 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++; i = ctx->num_outputs++;
indirect = ctx_indirect_outputs(ctx); indirect = ctx_indirect_outputs(ctx);
if (ctx->num_outputs > ARRAY_SIZE(ctx->outputs)) { if (ctx->num_outputs > ARRAY_SIZE(ctx->outputs)) {

Loading…
Cancel
Save