char *error_str = NULL;
const unsigned *program =
brw_compile_gs(compiler, dbg, mem_ctx, &brw_key, gs_prog_data,
- nir, NULL, -1, NULL, &error_str);
+ nir, -1, NULL, &error_str);
if (program == NULL) {
dbg_printf("Failed to compile geometry shader: %s\n", error_str);
ralloc_free(mem_ctx);
const struct brw_gs_prog_key *key,
struct brw_gs_prog_data *prog_data,
nir_shader *nir,
- struct gl_program *prog,
int shader_time_index,
struct brw_compile_stats *stats,
char **error_str);
const struct brw_gs_prog_key *key,
struct brw_gs_prog_data *prog_data,
nir_shader *nir,
- struct gl_program *prog,
int shader_time_index,
struct brw_compile_stats *stats,
char **error_str)
nir, mem_ctx, false /* no_spills */,
shader_time_index, debug_enabled);
else
- gs = new brw::gfx6_gs_visitor(compiler, log_data, &c, prog_data, prog,
+ gs = new brw::gfx6_gs_visitor(compiler, log_data, &c, prog_data,
nir, mem_ctx, false /* no_spills */,
shader_time_index, debug_enabled);
this->prim_count = src_reg(this, glsl_type::uint_type);
emit(MOV(dst_reg(this->prim_count), brw_imm_ud(0u)));
- if (prog->info.has_transform_feedback_varyings) {
+ if (gs_prog_data->num_transform_feedback_bindings) {
/* Create a virtual register to hold destination indices in SOL */
this->destination_indices = src_reg(this, glsl_type::uvec4_type);
/* Create a virtual register to hold number of written primitives */
this->max_svbi = src_reg(this, glsl_type::uvec4_type);
emit(MOV(dst_reg(this->max_svbi),
src_reg(retype(brw_vec1_grf(1, 4), BRW_REGISTER_TYPE_UD))));
-
- xfb_setup();
}
/* PrimitveID is delivered in r0.1 of the thread payload. If the program
this->current_annotation = "gfx6 thread end: ff_sync";
vec4_instruction *inst = NULL;
- if (prog->info.has_transform_feedback_varyings) {
+ if (gs_prog_data->num_transform_feedback_bindings) {
src_reg sol_temp(this, glsl_type::uvec4_type);
emit(GS_OPCODE_FF_SYNC_SET_PRIMITIVES,
dst_reg(this->svbi),
}
emit(BRW_OPCODE_WHILE);
- if (prog->info.has_transform_feedback_varyings)
+ if (gs_prog_data->num_transform_feedback_bindings)
xfb_write();
}
emit(BRW_OPCODE_ENDIF);
*/
this->current_annotation = "gfx6 thread end: EOT";
- if (prog->info.has_transform_feedback_varyings) {
+ if (gs_prog_data->num_transform_feedback_bindings) {
/* When emitting EOT, set SONumPrimsWritten Increment Value. */
src_reg data(this, glsl_type::uint_type);
emit(AND(dst_reg(data), this->sol_prim_written, brw_imm_ud(0xffffu)));
}
void
-gfx6_gs_visitor::xfb_setup()
-{
- static const unsigned swizzle_for_offset[4] = {
- BRW_SWIZZLE4(0, 1, 2, 3),
- BRW_SWIZZLE4(1, 2, 3, 3),
- BRW_SWIZZLE4(2, 3, 3, 3),
- BRW_SWIZZLE4(3, 3, 3, 3)
- };
-
- const struct gl_transform_feedback_info *linked_xfb_info =
- this->prog->sh.LinkedTransformFeedback;
- int i;
-
- /* Make sure that the VUE slots won't overflow the unsigned chars in
- * prog_data->transform_feedback_bindings[].
- */
- STATIC_ASSERT(BRW_VARYING_SLOT_COUNT <= 256);
-
- /* Make sure that we don't need more binding table entries than we've
- * set aside for use in transform feedback. (We shouldn't, since we
- * set aside enough binding table entries to have one per component).
- */
- assert(linked_xfb_info->NumOutputs <= BRW_MAX_SOL_BINDINGS);
-
- gs_prog_data->num_transform_feedback_bindings = linked_xfb_info->NumOutputs;
- for (i = 0; i < gs_prog_data->num_transform_feedback_bindings; i++) {
- gs_prog_data->transform_feedback_bindings[i] =
- linked_xfb_info->Outputs[i].OutputRegister;
- gs_prog_data->transform_feedback_swizzles[i] =
- swizzle_for_offset[linked_xfb_info->Outputs[i].ComponentOffset];
- }
-}
-
-void
gfx6_gs_visitor::xfb_write()
{
unsigned num_verts;
- if (!gs_prog_data->num_transform_feedback_bindings)
- return;
-
switch (gs_prog_data->output_topology) {
case _3DPRIM_POINTLIST:
num_verts = 1;
void *log_data,
struct brw_gs_compile *c,
struct brw_gs_prog_data *prog_data,
- struct gl_program *prog,
const nir_shader *shader,
void *mem_ctx,
bool no_spills,
int shader_time_index,
bool debug_enabled) :
vec4_gs_visitor(comp, log_data, c, prog_data, shader, mem_ctx, no_spills,
- shader_time_index, debug_enabled),
- prog(prog)
+ shader_time_index, debug_enabled)
{
}
private:
void xfb_write();
void xfb_program(unsigned vertex, unsigned num_verts);
- void xfb_setup();
int get_vertex_output_offset_for_varying(int vertex, int varying);
- const struct gl_program *prog;
-
src_reg vertex_output;
src_reg vertex_output_offset;
src_reg temp;
gs_stage->code = brw_compile_gs(compiler, device, mem_ctx,
&gs_stage->key.gs,
&gs_stage->prog_data.gs,
- gs_stage->nir, NULL, -1,
+ gs_stage->nir, -1,
gs_stage->stats, NULL);
}
&prog_data->base.base, reserved);
}
+static void
+brw_gfx6_xfb_setup(const struct gl_transform_feedback_info *linked_xfb_info,
+ struct brw_gs_prog_data *gs_prog_data)
+{
+ static const unsigned swizzle_for_offset[4] = {
+ BRW_SWIZZLE4(0, 1, 2, 3),
+ BRW_SWIZZLE4(1, 2, 3, 3),
+ BRW_SWIZZLE4(2, 3, 3, 3),
+ BRW_SWIZZLE4(3, 3, 3, 3)
+ };
+
+ int i;
+
+ /* Make sure that the VUE slots won't overflow the unsigned chars in
+ * prog_data->transform_feedback_bindings[].
+ */
+ STATIC_ASSERT(BRW_VARYING_SLOT_COUNT <= 256);
+
+ /* Make sure that we don't need more binding table entries than we've
+ * set aside for use in transform feedback. (We shouldn't, since we
+ * set aside enough binding table entries to have one per component).
+ */
+ assert(linked_xfb_info->NumOutputs <= BRW_MAX_SOL_BINDINGS);
+
+ gs_prog_data->num_transform_feedback_bindings = linked_xfb_info->NumOutputs;
+ for (i = 0; i < gs_prog_data->num_transform_feedback_bindings; i++) {
+ gs_prog_data->transform_feedback_bindings[i] =
+ linked_xfb_info->Outputs[i].OutputRegister;
+ gs_prog_data->transform_feedback_swizzles[i] =
+ swizzle_for_offset[linked_xfb_info->Outputs[i].ComponentOffset];
+ }
+}
static bool
brw_codegen_gs_prog(struct brw_context *brw,
struct brw_program *gp,
&prog_data.base.vue_map, outputs_written,
gp->program.info.separate_shader, 1);
+ if (devinfo->ver == 6)
+ brw_gfx6_xfb_setup(gp->program.sh.LinkedTransformFeedback,
+ &prog_data);
+
int st_index = -1;
if (INTEL_DEBUG & DEBUG_SHADER_TIME)
st_index = brw_get_shader_time_index(brw, &gp->program, ST_GS, true);
char *error_str;
const unsigned *program =
brw_compile_gs(brw->screen->compiler, brw, mem_ctx, key,
- &prog_data, nir, &gp->program, st_index,
+ &prog_data, nir, st_index,
NULL, &error_str);
if (program == NULL) {
ralloc_strcat(&gp->program.sh.data->InfoLog, error_str);