arb_gpu_shader5: add support for vertex streams.

This adds support for the transform feedback vertex streams

Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
macos/master
Dave Airlie 7 years ago
parent 0337bcd3ce
commit 2cad994e90
  1. 1
      src/gallium/include/pipe/p_state.h
  2. 2
      src/vrend_decode.c
  3. 5
      src/vrend_renderer.c
  4. 53
      src/vrend_shader.c

@ -206,6 +206,7 @@ struct pipe_stream_output_info
unsigned num_components:3; /** 1 to 4 */
unsigned output_buffer:3; /**< 0 to PIPE_MAX_SO_BUFFERS */
unsigned dst_offset:16; /**< offset into the buffer in dwords */
unsigned stream:2;
} output[PIPE_MAX_SO_OUTPUTS];
};

@ -97,6 +97,8 @@ static int vrend_decode_create_shader(struct vrend_decode_ctx *ctx,
so_info.output[i].num_components = (tmp >> 10) & 0x7;
so_info.output[i].output_buffer = (tmp >> 13) & 0x7;
so_info.output[i].dst_offset = (tmp >> 16) & 0xffff;
tmp = get_buf_entry(ctx, VIRGL_OBJ_SHADER_SO_OUTPUT0_SO(i));
so_info.output[i].stream = (tmp & 0x3);
}
}
shader_offset += 4 + (2 * num_so_outputs);

@ -771,13 +771,14 @@ static void dump_stream_out(struct pipe_stream_output_info *so)
printf("\n");
printf("outputs:\n");
for (i = 0; i < so->num_outputs; i++) {
printf("\t%d: reg: %d sc: %d, nc: %d ob: %d do: %d\n",
printf("\t%d: reg: %d sc: %d, nc: %d ob: %d do: %d st: %d\n",
i,
so->output[i].register_index,
so->output[i].start_component,
so->output[i].num_components,
so->output[i].output_buffer,
so->output[i].dst_offset);
so->output[i].dst_offset,
so->output[i].stream);
}
}

@ -55,6 +55,7 @@ struct vrend_shader_io {
bool override_no_wm;
bool is_int;
char glsl_name[64];
unsigned stream;
};
struct vrend_shader_sampler {
@ -930,6 +931,29 @@ static int emit_prescale(struct dump_ctx *ctx)
return 0;
}
static int prepare_so_movs(struct dump_ctx *ctx)
{
int i;
for (i = 0; i < ctx->so->num_outputs; i++) {
ctx->write_so_outputs[i] = true;
if (ctx->so->output[i].start_component != 0)
continue;
if (ctx->so->output[i].num_components != 4)
continue;
if (ctx->outputs[ctx->so->output[i].register_index].name == TGSI_SEMANTIC_CLIPDIST)
continue;
if (ctx->outputs[ctx->so->output[i].register_index].name == TGSI_SEMANTIC_POSITION)
continue;
ctx->outputs[ctx->so->output[i].register_index].stream = ctx->so->output[i].stream;
if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY && ctx->so->output[i].stream)
ctx->uses_gpu_shader5 = true;
ctx->write_so_outputs[i] = false;
}
return 0;
}
static int emit_so_movs(struct dump_ctx *ctx)
{
char buf[255];
@ -960,7 +984,7 @@ static int emit_so_movs(struct dump_ctx *ctx)
} else
writemask[0] = 0;
if (ctx->so->output[i].num_components == 4 && writemask[0] == 0 && !(ctx->outputs[ctx->so->output[i].register_index].name == TGSI_SEMANTIC_CLIPDIST) && !(ctx->outputs[ctx->so->output[i].register_index].name == TGSI_SEMANTIC_POSITION)) {
if (!ctx->write_so_outputs[i]) {
if (ctx->so->output[i].register_index > ctx->num_outputs)
ctx->so_names[i] = NULL;
else if (ctx->outputs[ctx->so->output[i].register_index].name == TGSI_SEMANTIC_CLIPVERTEX && ctx->has_clipvertex) {
@ -968,13 +992,10 @@ static int emit_so_movs(struct dump_ctx *ctx)
ctx->has_clipvertex_so = true;
} else
ctx->so_names[i] = strdup(ctx->outputs[ctx->so->output[i].register_index].glsl_name);
ctx->write_so_outputs[i] = false;
} else {
char ntemp[8];
snprintf(ntemp, 8, "tfout%d", i);
ctx->so_names[i] = strdup(ntemp);
ctx->write_so_outputs[i] = true;
}
if (ctx->so->output[i].num_components == 1) {
if (ctx->outputs[ctx->so->output[i].register_index].is_int)
@ -1641,6 +1662,8 @@ iter_instruction(struct tgsi_iterate_context *iter,
if (ret)
return FALSE;
}
if (ctx->so)
prepare_so_movs(ctx);
}
for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
const struct tgsi_full_dst_register *dst = &inst->Dst[i];
@ -2263,7 +2286,8 @@ iter_instruction(struct tgsi_iterate_context *iter,
snprintf(buf, 255, "break;\n");
EMIT_BUF_WITH_RET(ctx, buf);
break;
case TGSI_OPCODE_EMIT:
case TGSI_OPCODE_EMIT: {
struct immed *imd = &ctx->imm[(inst->Src[0].Register.Index)];
if (ctx->so && ctx->key->gs_present) {
emit_so_movs(ctx);
}
@ -2273,13 +2297,24 @@ iter_instruction(struct tgsi_iterate_context *iter,
ret = emit_prescale(ctx);
if (ret)
return FALSE;
if (imd->val[inst->Src[0].Register.SwizzleX].ui > 0) {
ctx->uses_gpu_shader5 = true;
snprintf(buf, 255, "EmitStreamVertex(%d);\n", imd->val[inst->Src[0].Register.SwizzleX].ui);
} else
snprintf(buf, 255, "EmitVertex();\n");
EMIT_BUF_WITH_RET(ctx, buf);
break;
case TGSI_OPCODE_ENDPRIM:
}
case TGSI_OPCODE_ENDPRIM: {
struct immed *imd = &ctx->imm[(inst->Src[0].Register.Index)];
if (imd->val[inst->Src[0].Register.SwizzleX].ui > 0) {
ctx->uses_gpu_shader5 = true;
snprintf(buf, 255, "EndStreamPrimitive(%d);\n", imd->val[inst->Src[0].Register.SwizzleX].ui);
} else
snprintf(buf, 255, "EndPrimitive();\n");
EMIT_BUF_WITH_RET(ctx, buf);
break;
}
default:
fprintf(stderr,"failed to convert opcode %d\n", inst->Instruction.Opcode);
break;
@ -2510,6 +2545,9 @@ static char *emit_ios(struct dump_ctx *ctx, char *glsl_hdr)
} else
prefix = "";
/* ugly leave spaces to patch interp in later */
if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY && ctx->outputs[i].stream)
snprintf(buf, 255, "layout (stream = %d) %s%sout vec4 %s;\n", ctx->outputs[i].stream, prefix, ctx->outputs[i].invariant ? "invariant " : "", ctx->outputs[i].glsl_name);
else
snprintf(buf, 255, "%s%sout vec4 %s;\n", prefix, ctx->outputs[i].invariant ? "invariant " : "", ctx->outputs[i].glsl_name);
STRCAT_WITH_RET(glsl_hdr, buf);
} else if (ctx->outputs[i].invariant) {
@ -2632,6 +2670,9 @@ static char *emit_ios(struct dump_ctx *ctx, char *glsl_hdr)
snprintf(outtype, 6, "float");
else
snprintf(outtype, 6, "vec%d", ctx->so->output[i].num_components);
if (ctx->so->output[i].stream && ctx->prog_type == TGSI_PROCESSOR_GEOMETRY)
snprintf(buf, 255, "layout (stream=%d) out %s tfout%d;\n", ctx->so->output[i].stream, outtype, i);
else
snprintf(buf, 255, "out %s tfout%d;\n", outtype, i);
STRCAT_WITH_RET(glsl_hdr, buf);
}

Loading…
Cancel
Save