summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-05-15 13:48:58 +1000
committerDave Airlie <airlied@redhat.com>2018-05-15 13:54:01 +1000
commit8f054b8b45ba3e3d2572e60405ebe8690a2870cb (patch)
treee89f9899bcc984ed0dc51cb2ea58673732af355a
parent7176481ccc53f74c00beab601055c4872ed21593 (diff)
arb_gpu_shader5: add support for vertex streams.
This adds support for the transform feedback vertex streams
-rw-r--r--src/gallium/include/pipe/p_state.h1
-rw-r--r--src/vrend_decode.c2
-rw-r--r--src/vrend_renderer.c5
-rw-r--r--src/vrend_shader.c61
4 files changed, 57 insertions, 12 deletions
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 2b4d9e4..80be1b5 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -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];
};
diff --git a/src/vrend_decode.c b/src/vrend_decode.c
index 96f6077..1e31573 100644
--- a/src/vrend_decode.c
+++ b/src/vrend_decode.c
@@ -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);
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 82188d8..1f677ed 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -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);
}
}
diff --git a/src/vrend_shader.c b/src/vrend_shader.c
index b2573d5..3ded04c 100644
--- a/src/vrend_shader.c
+++ b/src/vrend_shader.c
@@ -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;
- snprintf(buf, 255, "EmitVertex();\n");
+ 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:
- snprintf(buf, 255, "EndPrimitive();\n");
+ }
+ 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,7 +2545,10 @@ static char *emit_ios(struct dump_ctx *ctx, char *glsl_hdr)
} else
prefix = "";
/* ugly leave spaces to patch interp in later */
- snprintf(buf, 255, "%s%sout vec4 %s;\n", prefix, ctx->outputs[i].invariant ? "invariant " : "", ctx->outputs[i].glsl_name);
+ 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) {
snprintf(buf, 255, "invariant %s;\n", ctx->outputs[i].glsl_name);
@@ -2632,7 +2670,10 @@ 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);
- snprintf(buf, 255, "out %s tfout%d;\n", outtype, i);
+ 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);
}
}