Meta gives core state upload a set of emit overrides programming vertex fetcher without core vbo support.
Signed-off-by: Topi Pohjolainen <topi.pohjolai...@intel.com> --- src/mesa/drivers/dri/i965/brw_context.h | 3 + src/mesa/drivers/dri/i965/brw_meta_util.c | 216 ++++++++++++++++++++++++++++++ src/mesa/drivers/dri/i965/brw_meta_util.h | 5 + 3 files changed, 224 insertions(+) diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index ad69288..78f583a 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -913,6 +913,9 @@ struct brw_context /* Whether a meta-operation is in progress. */ bool meta_in_progress; + /* Custom pipeline for meta operations. */ + void (* const meta_emitters[76])(struct brw_context *, void *meta_ctx); + struct brw_meta_save_state meta; /* Whether the last depth/stencil packets were both NULL. */ diff --git a/src/mesa/drivers/dri/i965/brw_meta_util.c b/src/mesa/drivers/dri/i965/brw_meta_util.c index 90cb1ce..c9feb89 100644 --- a/src/mesa/drivers/dri/i965/brw_meta_util.c +++ b/src/mesa/drivers/dri/i965/brw_meta_util.c @@ -28,6 +28,8 @@ #include "brw_draw.h" #include "brw_context.h" #include "intel_batchbuffer.h" +#include "brw_state.h" +#include "brw_atoms.h" /** * Helper function for handling mirror image blits. @@ -293,3 +295,217 @@ brw_meta_emit_clip_disable(struct brw_context *brw) OUT_BATCH(0); ADVANCE_BATCH(); } + +static void +emit_vertex_elements(struct brw_context *brw) +{ + /* 3DSTATE_VERTEX_ELEMENTS + * + * These are instructions for VF (vertex fetcher) how the URB is to be + * filled with vertex data. + * + * There is an element containing vertex coordinates (x,y,w,z). We tell + * the VF to load X and Y from the vertex buffer and to use constant + * values of zero and one for the Z and W coordinates respectively. + * Additionally on Gen < 8 any system generated input values are + * programmed with an extra element. Newer generations have separate + * state packet for this. + */ + const bool use_system_generated_values = + brw->gen < 8 && + (brw->vs.prog_data->uses_vertexid || + brw->vs.prog_data->uses_instanceid || + brw->vs.prog_data->uses_basevertex || + brw->vs.prog_data->uses_baseinstance); + const int num_elements = 1 + use_system_generated_values; + const int batch_length = 1 + 2 * num_elements; + + BEGIN_BATCH(batch_length); + OUT_BATCH((_3DSTATE_VERTEX_ELEMENTS << 16) | (batch_length - 2)); + /* Element 0 */ + OUT_BATCH(GEN6_VE0_VALID | + BRW_SURFACEFORMAT_R32G32_FLOAT << BRW_VE0_FORMAT_SHIFT | + 0 << BRW_VE0_SRC_OFFSET_SHIFT); + OUT_BATCH(BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT | + BRW_VE1_COMPONENT_STORE_SRC << 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); + + if (use_system_generated_values) { + const uint32_t comp0 = brw->vs.prog_data->uses_basevertex ? + BRW_VE1_COMPONENT_STORE_SRC : BRW_VE1_COMPONENT_STORE_0; + const uint32_t comp1 = brw->vs.prog_data->uses_baseinstance ? + BRW_VE1_COMPONENT_STORE_SRC : BRW_VE1_COMPONENT_STORE_0; + const uint32_t comp2 = brw->vs.prog_data->uses_vertexid ? + BRW_VE1_COMPONENT_STORE_VID : BRW_VE1_COMPONENT_STORE_0; + const uint32_t comp3 = brw->vs.prog_data->uses_instanceid ? + BRW_VE1_COMPONENT_STORE_IID : BRW_VE1_COMPONENT_STORE_0; + + OUT_BATCH(GEN6_VE0_VALID | + 1 << GEN6_VE0_INDEX_SHIFT | + BRW_SURFACEFORMAT_R32G32_FLOAT << BRW_VE0_FORMAT_SHIFT); + 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)); + } + + ADVANCE_BATCH(); + + if (brw->gen < 8) + return; + + for (unsigned i = 0; i < num_elements; ++i) { + BEGIN_BATCH(3); + OUT_BATCH(_3DSTATE_VF_INSTANCING << 16 | (3 - 2)); + OUT_BATCH(i); + OUT_BATCH(0); + ADVANCE_BATCH(); + } +} + +static void +meta_setup_vertex_buffer(struct brw_context *brw, + uint32_t x0, uint32_t y0, + uint32_t x1, uint32_t y1) +{ + uint32_t vertex_offset; + + /* See gen6_blorp_emit_vertices() */ + const float vertices[] = { + /* v0 */ (float)x1, (float)y1, + /* v1 */ (float)x0, (float)y1, + /* v2 */ (float)x0, (float)y0 + }; + + float *vertex_data = (float *)brw_state_batch( + brw, AUB_TRACE_VERTEX_BUFFER, + sizeof(vertices), 32, + &vertex_offset); + memcpy(vertex_data, vertices, sizeof(vertices)); + + const unsigned num_verts = 3; + const unsigned num_elems = sizeof(vertices) / (num_verts * sizeof(float)); + + brw_meta_emit_vertex_buffer_state(brw, num_elems, sizeof(vertices), + vertex_offset); +} + +static void +meta_emit_noop(struct brw_context *brw, void *custom_ctx) +{ + (void)custom_ctx; + (void)brw; +} + +static void +meta_emit_clip_state(struct brw_context *brw, void *custom_ctx) +{ + (void)custom_ctx; + brw_meta_emit_clip_disable(brw); +} + +struct meta_custom_context { + /* Dimensions for rectangle primitive. */ + float x0, y0, x1, y1; +}; + +static void +meta_emit_vertices(struct brw_context *brw, void *custom_ctx) +{ + const struct meta_custom_context *meta_ctx = + (const struct meta_custom_context *)custom_ctx; + + if (brw->gen >= 8) { + gen8_emit_system_gen_values(brw, + brw->vs.prog_data->uses_vertexid, + brw->vs.prog_data->uses_instanceid, + 1 /* nr_vb_enabled */, + false /* uses_edge_flag */); + } + + meta_setup_vertex_buffer(brw, + meta_ctx->x0, meta_ctx->y0, + meta_ctx->x1, meta_ctx->y1); + + emit_vertex_elements(brw); +} + +static void +meta_emit_no_cut_index(struct brw_context *brw, void *custom_ctx) +{ + (void)custom_ctx; + + /* Don't trigger on Ivybridge */ + if (brw->gen < 8 && !brw->is_haswell) + return; + + BEGIN_BATCH(2); + OUT_BATCH(_3DSTATE_VF << 16 | (2 - 2)); + OUT_BATCH(0); + ADVANCE_BATCH(); +} + +void +brw_meta_pipeline_upload(struct brw_context *brw, + float x0, float y0, float x1, float y1) +{ + assert(brw->gen >= 6); + + struct meta_custom_context custom_ctx = { + .x0 = x0, .y0 = y0, .x1 = x1, .y1 = y1 }; + + brw->wm.base.sampler_count = 0; + brw->gs.base.sampler_count = 0; + brw->tes.base.sampler_count = 0; + brw->tcs.base.sampler_count = 0; + brw->vs.base.sampler_count = 0; + + if (brw->primitive != _3DPRIM_RECTLIST) { + brw->primitive = _3DPRIM_RECTLIST; + brw->ctx.NewDriverState |= BRW_NEW_PRIMITIVE; + } + + brw->ctx.NewDriverState |= BRW_NEW_VERTICES; + brw_upload_pipeline_state(brw, BRW_RENDER_PIPELINE, + brw->meta_emitters, &custom_ctx); +} + +void +brw_meta_init(struct brw_context *brw) +{ + STATIC_ASSERT(ARRAY_SIZE(brw->meta_emitters) <= + ARRAY_SIZE(brw->render_atoms)); + + /* This is to work around brw_context::meta_emitters being declared const. + * We want it to be const, but it needs to be initialized somehow! + */ + void (** emitters)(struct brw_context *, void *) = + (void (**)(struct brw_context *, void *))brw->meta_emitters; + + (void)memset(emitters, 0, sizeof(brw->meta_emitters)); + + switch (brw->gen) { + case 6: + emitters[GEN6_ATOM_CLIP_STATE] = meta_emit_clip_state; + emitters[GEN6_ATOM_INDICES] = meta_emit_noop; + emitters[GEN6_ATOM_INDEX_BUFFER] = meta_emit_noop; + emitters[GEN6_ATOM_VERTICES] = meta_emit_vertices; + break; + case 7: + emitters[GEN7_ATOM_CLIP_STATE] = meta_emit_clip_state; + emitters[GEN7_ATOM_INDICES] = meta_emit_noop; + emitters[GEN7_ATOM_INDEX_BUFFER] = meta_emit_noop; + emitters[GEN7_ATOM_VERTICES] = meta_emit_vertices; + emitters[GEN7_ATOM_HASWELL_CUT_INDEX] = meta_emit_no_cut_index; + break; + case 8: + case 9: + emitters[GEN8_ATOM_CLIP_STATE] = meta_emit_clip_state; + emitters[GEN8_ATOM_INDICES] = meta_emit_noop; + emitters[GEN8_ATOM_INDEX_BUFFER] = meta_emit_noop; + emitters[GEN8_ATOM_VERTICES] = meta_emit_vertices; + emitters[GEN8_ATOM_HASWELL_CUT_INDEX] = meta_emit_no_cut_index; + break; + } +} diff --git a/src/mesa/drivers/dri/i965/brw_meta_util.h b/src/mesa/drivers/dri/i965/brw_meta_util.h index 99c9186..91b6b41 100644 --- a/src/mesa/drivers/dri/i965/brw_meta_util.h +++ b/src/mesa/drivers/dri/i965/brw_meta_util.h @@ -58,6 +58,11 @@ void brw_meta_emit_vertex_buffer_state(struct brw_context *brw, void brw_meta_emit_clip_disable(struct brw_context *brw); +void brw_meta_pipeline_upload(struct brw_context *brw, + float x0, float y0, float x1, float y1); + +void brw_meta_init(struct brw_context *brw); + #ifdef __cplusplus } #endif -- 2.5.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev