- intel_upload_data(brw, &brw->draw.params, sizeof(brw->draw.params), 4,
- &brw->draw.draw_params_bo,
- &brw->draw.draw_params_offset);
- }
-
- if (vs_prog_data->uses_drawid) {
- intel_upload_data(brw, &brw->draw.gl_drawid, sizeof(brw->draw.gl_drawid), 4,
- &brw->draw.draw_id_bo,
- &brw->draw.draw_id_offset);
- }
-}
-
-/**
- * Emit a VERTEX_BUFFER_STATE entry (part of 3DSTATE_VERTEX_BUFFERS).
- */
-uint32_t *
-brw_emit_vertex_buffer_state(struct brw_context *brw,
- unsigned buffer_nr,
- drm_intel_bo *bo,
- unsigned start_offset,
- unsigned end_offset,
- unsigned stride,
- unsigned step_rate,
- uint32_t *__map)
-{
- struct gl_context *ctx = &brw->ctx;
- uint32_t dw0;
-
- if (brw->gen >= 8) {
- dw0 = buffer_nr << GEN6_VB0_INDEX_SHIFT;
- } else if (brw->gen >= 6) {
- dw0 = (buffer_nr << GEN6_VB0_INDEX_SHIFT) |
- (step_rate ? GEN6_VB0_ACCESS_INSTANCEDATA
- : GEN6_VB0_ACCESS_VERTEXDATA);
- } else {
- dw0 = (buffer_nr << BRW_VB0_INDEX_SHIFT) |
- (step_rate ? BRW_VB0_ACCESS_INSTANCEDATA
- : BRW_VB0_ACCESS_VERTEXDATA);
- }
-
- if (brw->gen >= 7)
- dw0 |= GEN7_VB0_ADDRESS_MODIFYENABLE;
-
- switch (brw->gen) {
- case 7:
- dw0 |= GEN7_MOCS_L3 << 16;
- break;
- case 8:
- dw0 |= BDW_MOCS_WB << 16;
- break;
- case 9:
- dw0 |= SKL_MOCS_WB << 16;
- break;
- }
-
- WARN_ONCE(stride >= (brw->gen >= 5 ? 2048 : 2047),
- "VBO stride %d too large, bad rendering may occur\n",
- stride);
- OUT_BATCH(dw0 | (stride << BRW_VB0_PITCH_SHIFT));
- if (brw->gen >= 8) {
- OUT_RELOC64(bo, I915_GEM_DOMAIN_VERTEX, 0, start_offset);
- /* From the BSpec: 3D Pipeline Stages - 3D Pipeline Geometry -
- * Vertex Fetch (VF) Stage - State
- *
- * Instead of "VBState.StartingBufferAddress + VBState.MaxIndex x
- * VBState.BufferPitch", the address of the byte immediately beyond the
- * last valid byte of the buffer is determined by
- * "VBState.StartingBufferAddress + VBState.BufferSize".
- */
- OUT_BATCH(end_offset - start_offset);
- } else if (brw->gen >= 5) {
- OUT_RELOC(bo, I915_GEM_DOMAIN_VERTEX, 0, start_offset);
- /* From the BSpec: 3D Pipeline Stages - 3D Pipeline Geometry -
- * Vertex Fetch (VF) Stage - State
- *
- * Instead of "VBState.StartingBufferAddress + VBState.MaxIndex x
- * VBState.BufferPitch", the address of the byte immediately beyond the
- * last valid byte of the buffer is determined by
- * "VBState.EndAddress + 1".
- */
- OUT_RELOC(bo, I915_GEM_DOMAIN_VERTEX, 0, end_offset - 1);
- OUT_BATCH(step_rate);
- } else {
- OUT_RELOC(bo, I915_GEM_DOMAIN_VERTEX, 0, start_offset);
- OUT_BATCH(0);
- OUT_BATCH(step_rate);
- }
-
- return __map;
-}
-
-static void
-brw_emit_vertices(struct brw_context *brw)
-{
- GLuint i;
-
- brw_prepare_vertices(brw);
- brw_prepare_shader_draw_parameters(brw);
-
- brw_emit_query_begin(brw);
-
- const struct brw_vs_prog_data *vs_prog_data =
- brw_vs_prog_data(brw->vs.base.prog_data);
-
- unsigned nr_elements = brw->vb.nr_enabled;
- if (vs_prog_data->uses_vertexid || vs_prog_data->uses_instanceid ||
- vs_prog_data->uses_basevertex || vs_prog_data->uses_baseinstance)
- ++nr_elements;
- if (vs_prog_data->uses_drawid)
- nr_elements++;
-
- /* If the VS doesn't read any inputs (calculating vertex position from
- * a state variable for some reason, for example), emit a single pad
- * VERTEX_ELEMENT struct and bail.
- *
- * The stale VB state stays in place, but they don't do anything unless
- * a VE loads from them.
- */
- if (nr_elements == 0) {
- BEGIN_BATCH(3);
- OUT_BATCH((_3DSTATE_VERTEX_ELEMENTS << 16) | 1);
- if (brw->gen >= 6) {
- OUT_BATCH((0 << GEN6_VE0_INDEX_SHIFT) |
- GEN6_VE0_VALID |
- (BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT) |
- (0 << BRW_VE0_SRC_OFFSET_SHIFT));
- } else {
- OUT_BATCH((0 << BRW_VE0_INDEX_SHIFT) |
- BRW_VE0_VALID |
- (BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT) |
- (0 << BRW_VE0_SRC_OFFSET_SHIFT));
- }
- OUT_BATCH((BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_0_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_1_FLT << BRW_VE1_COMPONENT_3_SHIFT));
- ADVANCE_BATCH();
- return;
- }
-
- /* Now emit VB and VEP state packets.
- */
-
- const bool uses_draw_params =
- vs_prog_data->uses_basevertex ||
- vs_prog_data->uses_baseinstance;
- const unsigned nr_buffers = brw->vb.nr_buffers +
- uses_draw_params + vs_prog_data->uses_drawid;
-
- if (nr_buffers) {
- if (brw->gen >= 6) {
- assert(nr_buffers <= 33);
- } else {
- assert(nr_buffers <= 17);
- }
-
- BEGIN_BATCH(1 + 4 * nr_buffers);
- OUT_BATCH((_3DSTATE_VERTEX_BUFFERS << 16) | (4 * nr_buffers - 1));
- for (i = 0; i < brw->vb.nr_buffers; i++) {
- struct brw_vertex_buffer *buffer = &brw->vb.buffers[i];
- /* Prior to Haswell and Bay Trail we have to use 4-component formats
- * to fake 3-component ones. In particular, we do this for
- * half-float and 8 and 16-bit integer formats. This means that the
- * vertex element may poke over the end of the buffer by 2 bytes.
- */
- unsigned padding =
- (brw->gen <= 7 && !brw->is_baytrail && !brw->is_haswell) * 2;
- EMIT_VERTEX_BUFFER_STATE(brw, i, buffer->bo, buffer->offset,
- buffer->offset + buffer->size + padding,
- buffer->stride, buffer->step_rate);
-
- }
-
- if (uses_draw_params) {
- EMIT_VERTEX_BUFFER_STATE(brw, brw->vb.nr_buffers,
- brw->draw.draw_params_bo,
- brw->draw.draw_params_offset,
- brw->draw.draw_params_bo->size,
- 0, /* stride */
- 0); /* step rate */
- }
-
- if (vs_prog_data->uses_drawid) {
- EMIT_VERTEX_BUFFER_STATE(brw, brw->vb.nr_buffers + 1,
- brw->draw.draw_id_bo,
- brw->draw.draw_id_offset,
- brw->draw.draw_id_bo->size,
- 0, /* stride */
- 0); /* step rate */
- }
-
- ADVANCE_BATCH();
- }
-
- /* The hardware allows one more VERTEX_ELEMENTS than VERTEX_BUFFERS, presumably
- * for VertexID/InstanceID.
- */
- if (brw->gen >= 6) {
- assert(nr_elements <= 34);
- } else {
- assert(nr_elements <= 18);
- }
-
- struct brw_vertex_element *gen6_edgeflag_input = NULL;
-
- BEGIN_BATCH(1 + nr_elements * 2);
- OUT_BATCH((_3DSTATE_VERTEX_ELEMENTS << 16) | (2 * nr_elements - 1));
- for (i = 0; i < brw->vb.nr_enabled; i++) {
- struct brw_vertex_element *input = brw->vb.enabled[i];
- uint32_t format = brw_get_vertex_surface_type(brw, input->glarray);
- uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC;
- uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC;
- uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC;
- uint32_t comp3 = BRW_VE1_COMPONENT_STORE_SRC;
-
- if (input == &brw->vb.inputs[VERT_ATTRIB_EDGEFLAG]) {
- /* Gen6+ passes edgeflag as sideband along with the vertex, instead
- * of in the VUE. We have to upload it sideband as the last vertex
- * element according to the B-Spec.
- */
- if (brw->gen >= 6) {
- gen6_edgeflag_input = input;
- continue;
- }
- }
-
- switch (input->glarray->Size) {
- case 0: comp0 = BRW_VE1_COMPONENT_STORE_0;
- case 1: comp1 = BRW_VE1_COMPONENT_STORE_0;
- case 2: comp2 = BRW_VE1_COMPONENT_STORE_0;
- case 3: comp3 = input->glarray->Integer ? BRW_VE1_COMPONENT_STORE_1_INT
- : BRW_VE1_COMPONENT_STORE_1_FLT;
- break;
- }
-
- if (brw->gen >= 6) {
- OUT_BATCH((input->buffer << GEN6_VE0_INDEX_SHIFT) |
- GEN6_VE0_VALID |
- (format << BRW_VE0_FORMAT_SHIFT) |
- (input->offset << BRW_VE0_SRC_OFFSET_SHIFT));
- } else {
- OUT_BATCH((input->buffer << BRW_VE0_INDEX_SHIFT) |
- BRW_VE0_VALID |
- (format << BRW_VE0_FORMAT_SHIFT) |
- (input->offset << BRW_VE0_SRC_OFFSET_SHIFT));
- }
-
- if (brw->gen >= 5)
- OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
- (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
- (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
- (comp3 << BRW_VE1_COMPONENT_3_SHIFT));
- else
- OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
- (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
- (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
- (comp3 << BRW_VE1_COMPONENT_3_SHIFT) |
- ((i * 4) << BRW_VE1_DST_OFFSET_SHIFT));
- }
-
- if (vs_prog_data->uses_vertexid || vs_prog_data->uses_instanceid ||
- vs_prog_data->uses_basevertex || vs_prog_data->uses_baseinstance) {
- uint32_t dw0 = 0, dw1 = 0;
- uint32_t comp0 = BRW_VE1_COMPONENT_STORE_0;
- uint32_t comp1 = BRW_VE1_COMPONENT_STORE_0;
- uint32_t comp2 = BRW_VE1_COMPONENT_STORE_0;
- uint32_t comp3 = BRW_VE1_COMPONENT_STORE_0;
-
- if (vs_prog_data->uses_basevertex)
- comp0 = BRW_VE1_COMPONENT_STORE_SRC;
-
- if (vs_prog_data->uses_baseinstance)
- comp1 = BRW_VE1_COMPONENT_STORE_SRC;
-
- if (vs_prog_data->uses_vertexid)
- comp2 = BRW_VE1_COMPONENT_STORE_VID;
-
- if (vs_prog_data->uses_instanceid)
- comp3 = BRW_VE1_COMPONENT_STORE_IID;
-
- dw1 = (comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
- (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
- (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
- (comp3 << BRW_VE1_COMPONENT_3_SHIFT);
-
- if (brw->gen >= 6) {
- dw0 |= GEN6_VE0_VALID |
- brw->vb.nr_buffers << GEN6_VE0_INDEX_SHIFT |
- BRW_SURFACEFORMAT_R32G32_UINT << BRW_VE0_FORMAT_SHIFT;
- } else {
- dw0 |= BRW_VE0_VALID |
- brw->vb.nr_buffers << BRW_VE0_INDEX_SHIFT |
- BRW_SURFACEFORMAT_R32G32_UINT << BRW_VE0_FORMAT_SHIFT;
- dw1 |= (i * 4) << BRW_VE1_DST_OFFSET_SHIFT;
- }
-
- /* Note that for gl_VertexID, gl_InstanceID, and gl_PrimitiveID values,
- * the format is ignored and the value is always int.
- */
-
- OUT_BATCH(dw0);
- OUT_BATCH(dw1);
- }
-
- if (vs_prog_data->uses_drawid) {
- uint32_t dw0 = 0, dw1 = 0;
-
- dw1 = (BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT);
-
- if (brw->gen >= 6) {
- dw0 |= GEN6_VE0_VALID |
- ((brw->vb.nr_buffers + 1) << GEN6_VE0_INDEX_SHIFT) |
- (BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT);
- } else {
- dw0 |= BRW_VE0_VALID |
- ((brw->vb.nr_buffers + 1) << BRW_VE0_INDEX_SHIFT) |
- (BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT);
-
- dw1 |= (i * 4) << BRW_VE1_DST_OFFSET_SHIFT;
- }
-
- OUT_BATCH(dw0);
- OUT_BATCH(dw1);