/** * Store the SO_NUM_PRIMS_WRITTEN counters for each stream (4 uint64_t values) * to prim_count_bo. */ static void save_prim_start_values(struct brw_context *brw, struct brw_transform_feedback_object *obj) { /* Flush any drawing so that the counters have the right values. */ brw_emit_mi_flush(brw); /* Emit MI_STORE_REGISTER_MEM commands to write the values. */ for (int i = 0; i < BRW_MAX_XFB_STREAMS; i++) { brw_store_register_mem64(brw, obj->prim_count_bo, GEN7_SO_NUM_PRIMS_WRITTEN(i), START_OFFSET + i * sizeof(uint64_t)); } }
/** * Compute the number of primitives written during our most recent * transform feedback activity (the current SO_NUM_PRIMS_WRITTEN value * minus the stashed "start" value), and add it to our running tally. * * If \p finalize is true, also compute the number of vertices written * (by multiplying by the number of vertices per primitive), and store * that to the "final" location. * * Otherwise, just overwrite the old tally with the new one. */ static void tally_prims_written(struct brw_context *brw, struct brw_transform_feedback_object *obj, bool finalize) { /* Flush any drawing so that the counters have the right values. */ brw_emit_mi_flush(brw); for (int i = 0; i < BRW_MAX_XFB_STREAMS; i++) { /* GPR0 = Tally */ brw_load_register_imm32(brw, HSW_CS_GPR(0) + 4, 0); brw_load_register_mem(brw, HSW_CS_GPR(0), obj->prim_count_bo, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, TALLY_OFFSET + i * sizeof(uint32_t)); if (!obj->base.Paused) { /* GPR1 = Start Snapshot */ brw_load_register_mem64(brw, HSW_CS_GPR(1), obj->prim_count_bo, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, START_OFFSET + i * sizeof(uint64_t)); /* GPR2 = Ending Snapshot */ brw_load_register_reg64(brw, GEN7_SO_NUM_PRIMS_WRITTEN(i), HSW_CS_GPR(2)); BEGIN_BATCH(9); OUT_BATCH(HSW_MI_MATH | (9 - 2)); /* GPR1 = GPR2 (End) - GPR1 (Start) */ OUT_BATCH(MI_MATH_ALU2(LOAD, SRCA, R2)); OUT_BATCH(MI_MATH_ALU2(LOAD, SRCB, R1)); OUT_BATCH(MI_MATH_ALU0(SUB)); OUT_BATCH(MI_MATH_ALU2(STORE, R1, ACCU)); /* GPR0 = GPR0 (Tally) + GPR1 (Diff) */ OUT_BATCH(MI_MATH_ALU2(LOAD, SRCA, R0)); OUT_BATCH(MI_MATH_ALU2(LOAD, SRCB, R1)); OUT_BATCH(MI_MATH_ALU0(ADD)); OUT_BATCH(MI_MATH_ALU2(STORE, R0, ACCU)); ADVANCE_BATCH(); } if (!finalize) { /* Write back the new tally */ brw_store_register_mem32(brw, obj->prim_count_bo, HSW_CS_GPR(0), TALLY_OFFSET + i * sizeof(uint32_t)); } else { /* Convert the number of primitives to the number of vertices. */ if (obj->primitive_mode == GL_LINES) { /* Double R0 (R0 = R0 + R0) */ BEGIN_BATCH(5); OUT_BATCH(HSW_MI_MATH | (5 - 2)); OUT_BATCH(MI_MATH_ALU2(LOAD, SRCA, R0)); OUT_BATCH(MI_MATH_ALU2(LOAD, SRCB, R0)); OUT_BATCH(MI_MATH_ALU0(ADD)); OUT_BATCH(MI_MATH_ALU2(STORE, R0, ACCU)); ADVANCE_BATCH(); } else if (obj->primitive_mode == GL_TRIANGLES) { /* Triple R0 (R1 = R0 + R0, R0 = R0 + R1) */ BEGIN_BATCH(9); OUT_BATCH(HSW_MI_MATH | (9 - 2)); OUT_BATCH(MI_MATH_ALU2(LOAD, SRCA, R0)); OUT_BATCH(MI_MATH_ALU2(LOAD, SRCB, R0)); OUT_BATCH(MI_MATH_ALU0(ADD)); OUT_BATCH(MI_MATH_ALU2(STORE, R1, ACCU)); OUT_BATCH(MI_MATH_ALU2(LOAD, SRCA, R0)); OUT_BATCH(MI_MATH_ALU2(LOAD, SRCB, R1)); OUT_BATCH(MI_MATH_ALU0(ADD)); OUT_BATCH(MI_MATH_ALU2(STORE, R0, ACCU)); ADVANCE_BATCH(); } /* Store it to the final result */ brw_store_register_mem32(brw, obj->prim_count_bo, HSW_CS_GPR(0), i * sizeof(uint32_t)); } } }
REG64(IA_PRIMITIVES_COUNT), REG64(VS_INVOCATION_COUNT), REG64(GS_INVOCATION_COUNT), REG64(GS_PRIMITIVES_COUNT), REG64(CL_INVOCATION_COUNT), REG64(CL_PRIMITIVES_COUNT), REG64(PS_INVOCATION_COUNT), REG64(PS_DEPTH_COUNT), OACONTROL, /* Only allowed for LRI and SRM. See below. */ GEN7_3DPRIM_END_OFFSET, GEN7_3DPRIM_START_VERTEX, GEN7_3DPRIM_VERTEX_COUNT, GEN7_3DPRIM_INSTANCE_COUNT, GEN7_3DPRIM_START_INSTANCE, GEN7_3DPRIM_BASE_VERTEX, REG64(GEN7_SO_NUM_PRIMS_WRITTEN(0)), REG64(GEN7_SO_NUM_PRIMS_WRITTEN(1)), REG64(GEN7_SO_NUM_PRIMS_WRITTEN(2)), REG64(GEN7_SO_NUM_PRIMS_WRITTEN(3)), REG64(GEN7_SO_PRIM_STORAGE_NEEDED(0)), REG64(GEN7_SO_PRIM_STORAGE_NEEDED(1)), REG64(GEN7_SO_PRIM_STORAGE_NEEDED(2)), REG64(GEN7_SO_PRIM_STORAGE_NEEDED(3)), GEN7_SO_WRITE_OFFSET(0), GEN7_SO_WRITE_OFFSET(1), GEN7_SO_WRITE_OFFSET(2), GEN7_SO_WRITE_OFFSET(3), GEN7_L3SQCREG1, GEN7_L3CNTLREG2, GEN7_L3CNTLREG3, };