iris: Implement DrawTransformFeedback()
We get the count by dividing the offset by the stride.
This commit is contained in:
@@ -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;
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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);
|
||||
// ...
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user