iris: Implement DrawTransformFeedback()

We get the count by dividing the offset by the stride.
This commit is contained in:
Kenneth Graunke
2018-12-04 22:19:33 -08:00
parent 2e103fff63
commit 5307ff6a5f
5 changed files with 61 additions and 21 deletions

View File

@@ -314,6 +314,9 @@ struct iris_stream_output_target {
/** Storage holding the offset where we're writing in the buffer */
struct iris_state_ref offset;
/** Stride (dwords-per-vertex) during this transform feedback operation */
uint16_t stride;
};
/**
@@ -513,6 +516,9 @@ struct iris_context {
/** 3DSTATE_STREAMOUT and 3DSTATE_SO_DECL_LIST packets */
uint32_t *streamout;
/** Current strides for each streamout buffer */
uint16_t *streamout_strides;
/** The SURFACE_STATE for a 1x1x1 null surface. */
struct iris_state_ref unbound_tex;

View File

@@ -50,6 +50,8 @@
#define MI_PREDICATE_RESULT_1 0x241C
#define MI_PREDICATE_RESULT_2 0x2214
#define CS_GPR(n) (0x2600 + (n) * 8)
/* The number of bits in our TIMESTAMP queries. */
#define TIMESTAMP_BITS 36

View File

@@ -1253,16 +1253,16 @@ iris_update_compiled_fs(struct iris_context *ice)
*
* This stage is the one which will feed stream output and the rasterizer.
*/
static struct iris_compiled_shader *
last_vue_shader(struct iris_context *ice)
static gl_shader_stage
last_vue_stage(struct iris_context *ice)
{
if (ice->shaders.prog[MESA_SHADER_GEOMETRY])
return ice->shaders.prog[MESA_SHADER_GEOMETRY];
return MESA_SHADER_GEOMETRY;
if (ice->shaders.prog[MESA_SHADER_TESS_EVAL])
return ice->shaders.prog[MESA_SHADER_TESS_EVAL];
return MESA_SHADER_TESS_EVAL;
return ice->shaders.prog[MESA_SHADER_VERTEX];
return MESA_SHADER_VERTEX;
}
/**
@@ -1355,13 +1355,24 @@ iris_update_compiled_shaders(struct iris_context *ice)
if (dirty & IRIS_DIRTY_UNCOMPILED_GS)
iris_update_compiled_gs(ice);
struct iris_compiled_shader *shader = last_vue_shader(ice);
gl_shader_stage last_stage = last_vue_stage(ice);
struct iris_compiled_shader *shader = ice->shaders.prog[last_stage];
struct iris_uncompiled_shader *ish = ice->shaders.uncompiled[last_stage];
update_last_vue_map(ice, shader->prog_data);
if (ice->state.streamout != shader->streamout) {
ice->state.streamout = shader->streamout;
ice->state.dirty |= IRIS_DIRTY_SO_DECL_LIST | IRIS_DIRTY_STREAMOUT;
}
if (ice->state.streamout_active) {
for (int i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
struct iris_stream_output_target *so =
(void *) ice->state.so_target[i];
if (so)
so->stride = ish->stream_output.stride[i];
}
}
if (dirty & IRIS_DIRTY_UNCOMPILED_FS)
iris_update_compiled_fs(ice);
// ...

View File

@@ -58,8 +58,6 @@
#define SO_NUM_PRIMS_WRITTEN(n) (0x5200 + (n) * 8)
#define CS_GPR(n) (0x2600 + (n) * 8)
#define MI_MATH (0x1a << 23)
#define MI_ALU_LOAD 0x080

View File

@@ -101,6 +101,7 @@
#include "intel/common/gen_sample_positions.h"
#include "iris_batch.h"
#include "iris_context.h"
#include "iris_defines.h"
#include "iris_pipe.h"
#include "iris_resource.h"
@@ -4583,21 +4584,42 @@ iris_upload_render_state(struct iris_context *ice,
lri.DataDWord = 0;
}
}
} else if (draw->count_from_stream_output) {
struct iris_stream_output_target *so =
(void *) draw->count_from_stream_output;
// XXX: avoid if possible
iris_emit_pipe_control_flush(batch, PIPE_CONTROL_CS_STALL);
iris_emit_cmd(batch, GENX(MI_LOAD_REGISTER_MEM), lrm) {
lrm.RegisterAddress = CS_GPR(0);
lrm.MemoryAddress =
ro_bo(iris_resource_bo(so->offset.res), so->offset.offset);
}
iris_math_div32_gpr0(ice, batch, so->stride);
_iris_emit_lrr(batch, _3DPRIM_VERTEX_COUNT, CS_GPR(0));
_iris_emit_lri(batch, _3DPRIM_START_VERTEX, 0);
_iris_emit_lri(batch, _3DPRIM_BASE_VERTEX, 0);
_iris_emit_lri(batch, _3DPRIM_START_INSTANCE, 0);
_iris_emit_lri(batch, _3DPRIM_INSTANCE_COUNT, draw->instance_count);
}
iris_emit_cmd(batch, GENX(3DPRIMITIVE), prim) {
prim.StartInstanceLocation = draw->start_instance;
prim.InstanceCount = draw->instance_count;
prim.VertexCountPerInstance = draw->count;
prim.VertexAccessType = draw->index_size > 0 ? RANDOM : SEQUENTIAL;
prim.PredicateEnable =
ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT;
if (draw->indirect || draw->count_from_stream_output) {
prim.IndirectParameterEnable = true;
} else {
prim.StartInstanceLocation = draw->start_instance;
prim.InstanceCount = draw->instance_count;
prim.VertexCountPerInstance = draw->count;
// XXX: this is probably bonkers.
prim.StartVertexLocation = draw->start;
prim.IndirectParameterEnable = draw->indirect != NULL;
if (draw->index_size) {
prim.BaseVertexLocation += draw->index_bias;
} else {
@@ -4607,6 +4629,7 @@ iris_upload_render_state(struct iris_context *ice,
//prim.BaseVertexLocation = ...;
}
}
}
static void
iris_upload_compute_state(struct iris_context *ice,