diff options
author | Dave Airlie <[email protected]> | 2018-11-27 09:03:16 +1000 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2019-02-21 10:26:10 -0800 |
commit | 7bbf3ff4a98c861a208e5a19005d35c93507aa39 (patch) | |
tree | e1a814e6a67054da6cb9486720867677650d03e6 /src/gallium/drivers/iris/iris_query.c | |
parent | dbe198d6bad2f7162e1dc082da3337278bf79c2d (diff) |
iris: add conditional render support
Diffstat (limited to 'src/gallium/drivers/iris/iris_query.c')
-rw-r--r-- | src/gallium/drivers/iris/iris_query.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/gallium/drivers/iris/iris_query.c b/src/gallium/drivers/iris/iris_query.c index 62862927adc..27126d7f7bc 100644 --- a/src/gallium/drivers/iris/iris_query.c +++ b/src/gallium/drivers/iris/iris_query.c @@ -724,6 +724,103 @@ iris_set_active_query_state(struct pipe_context *ctx, boolean enable) IRIS_DIRTY_WM; } +static void +set_predicate_enable(struct iris_context *ice, + bool value) +{ + if (value) + ice->predicate = IRIS_PREDICATE_STATE_RENDER; + else + ice->predicate = IRIS_PREDICATE_STATE_DONT_RENDER; +} + +static void +set_predicate_for_overflow(struct iris_context *ice, + struct iris_query *q) +{ + struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER]; + ice->predicate = IRIS_PREDICATE_STATE_USE_BIT; + + /* Needed to ensure the memory is coherent for the MI_LOAD_REGISTER_MEM + * command when loading the values into the predicate source registers for + * conditional rendering. + */ + iris_emit_pipe_control_flush(batch, PIPE_CONTROL_FLUSH_ENABLE); + + overflow_result_to_gpr0(ice, q); + ice->vtbl.load_register_reg64(batch, CS_GPR(0), MI_PREDICATE_SRC0); + ice->vtbl.load_register_imm64(batch, MI_PREDICATE_SRC1, 0ull); +} + +static void +set_predicate_for_occlusion(struct iris_context *ice, + struct iris_query *q) +{ + struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER]; + ice->predicate = IRIS_PREDICATE_STATE_USE_BIT; + + /* Needed to ensure the memory is coherent for the MI_LOAD_REGISTER_MEM + * command when loading the values into the predicate source registers for + * conditional rendering. + */ + iris_emit_pipe_control_flush(batch, PIPE_CONTROL_FLUSH_ENABLE); + + ice->vtbl.load_register_mem64(batch, MI_PREDICATE_SRC0, q->bo, offsetof(struct iris_query_snapshots, start)); + ice->vtbl.load_register_mem64(batch, MI_PREDICATE_SRC1, q->bo, offsetof(struct iris_query_snapshots, end)); +} + +static void +set_predicate_for_result(struct iris_context *ice, + struct iris_query *q, + bool condition) +{ + struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER]; + int load_op; + + switch (q->type) { + case PIPE_QUERY_SO_OVERFLOW_PREDICATE: + case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: + set_predicate_for_overflow(ice, q); + break; + default: + set_predicate_for_occlusion(ice, q); + break; + } + + if (ice->predicate == IRIS_PREDICATE_STATE_USE_BIT) { + if (condition) + load_op = MI_PREDICATE_LOADOP_LOAD; + else + load_op = MI_PREDICATE_LOADOP_LOADINV; + + // batch emit + uint32_t predicate = MI_PREDICATE | load_op | + MI_PREDICATE_COMBINEOP_SET | + MI_PREDICATE_COMPAREOP_SRCS_EQUAL; + iris_batch_emit(batch, &predicate, sizeof(uint32_t)); + } +} + +static void +iris_render_condition(struct pipe_context *ctx, + struct pipe_query *query, + boolean condition, + enum pipe_render_cond_flag mode) +{ + struct iris_context *ice = (void *) ctx; + struct iris_query *q = (void *) query; + + if (!q) { + ice->predicate = IRIS_PREDICATE_STATE_RENDER; + return; + } + + if (q->result || q->ready) + set_predicate_enable(ice, (q->result != 0) ^ condition); + else + set_predicate_for_result(ice, q, condition); +} + void iris_init_query_functions(struct pipe_context *ctx) { @@ -734,4 +831,5 @@ iris_init_query_functions(struct pipe_context *ctx) ctx->get_query_result = iris_get_query_result; ctx->get_query_result_resource = iris_get_query_result_resource; ctx->set_active_query_state = iris_set_active_query_state; + ctx->render_condition = iris_render_condition; } |