anv: don't reserve a particular register for draw count

By using the same mi_builder throughout the draw call, we can just
allocate a register from the mi_builder and unref it when we're done.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Rafael Antognolli <rafael.antognolli@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/2775>
This commit is contained in:
Lionel Landwerlin
2020-02-05 09:50:16 +02:00
parent 796fccce63
commit a96d92a689
2 changed files with 46 additions and 40 deletions

View File

@@ -34,8 +34,8 @@
#include "genxml/gen_macros.h" #include "genxml/gen_macros.h"
#include "genxml/genX_pack.h" #include "genxml/genX_pack.h"
/* We reserve GPR 14 and 15 for conditional rendering */ /* We reserve GPR 15 for conditional rendering */
#define GEN_MI_BUILDER_NUM_ALLOC_GPRS 14 #define GEN_MI_BUILDER_NUM_ALLOC_GPRS 15
#define __gen_get_batch_dwords anv_batch_emit_dwords #define __gen_get_batch_dwords anv_batch_emit_dwords
#define __gen_address_offset anv_address_add #define __gen_address_offset anv_address_add
#include "common/gen_mi_builder.h" #include "common/gen_mi_builder.h"
@@ -3855,41 +3855,39 @@ void genX(CmdDrawIndexedIndirect)(
} }
} }
#define TMP_DRAW_COUNT_REG 0x2670 /* MI_ALU_REG14 */ static struct gen_mi_value
static void
prepare_for_draw_count_predicate(struct anv_cmd_buffer *cmd_buffer, prepare_for_draw_count_predicate(struct anv_cmd_buffer *cmd_buffer,
struct gen_mi_builder *b,
struct anv_address count_address, struct anv_address count_address,
const bool conditional_render_enabled) const bool conditional_render_enabled)
{ {
struct gen_mi_builder b; struct gen_mi_value ret = gen_mi_imm(0);
gen_mi_builder_init(&b, &cmd_buffer->batch);
if (conditional_render_enabled) { if (conditional_render_enabled) {
#if GEN_GEN >= 8 || GEN_IS_HASWELL #if GEN_GEN >= 8 || GEN_IS_HASWELL
gen_mi_store(&b, gen_mi_reg64(TMP_DRAW_COUNT_REG), ret = gen_mi_new_gpr(b);
gen_mi_mem32(count_address)); gen_mi_store(b, gen_mi_value_ref(b, ret), gen_mi_mem32(count_address));
#endif #endif
} else { } else {
/* Upload the current draw count from the draw parameters buffer to /* Upload the current draw count from the draw parameters buffer to
* MI_PREDICATE_SRC0. * MI_PREDICATE_SRC0.
*/ */
gen_mi_store(&b, gen_mi_reg64(MI_PREDICATE_SRC0), gen_mi_store(b, gen_mi_reg64(MI_PREDICATE_SRC0),
gen_mi_mem32(count_address)); gen_mi_mem32(count_address));
gen_mi_store(&b, gen_mi_reg32(MI_PREDICATE_SRC1 + 4), gen_mi_imm(0)); gen_mi_store(b, gen_mi_reg32(MI_PREDICATE_SRC1 + 4), gen_mi_imm(0));
} }
return ret;
} }
static void static void
emit_draw_count_predicate(struct anv_cmd_buffer *cmd_buffer, emit_draw_count_predicate(struct anv_cmd_buffer *cmd_buffer,
struct gen_mi_builder *b,
uint32_t draw_index) uint32_t draw_index)
{ {
struct gen_mi_builder b;
gen_mi_builder_init(&b, &cmd_buffer->batch);
/* Upload the index of the current primitive to MI_PREDICATE_SRC1. */ /* Upload the index of the current primitive to MI_PREDICATE_SRC1. */
gen_mi_store(&b, gen_mi_reg32(MI_PREDICATE_SRC1), gen_mi_imm(draw_index)); gen_mi_store(b, gen_mi_reg32(MI_PREDICATE_SRC1), gen_mi_imm(draw_index));
if (draw_index == 0) { if (draw_index == 0) {
anv_batch_emit(&cmd_buffer->batch, GENX(MI_PREDICATE), mip) { anv_batch_emit(&cmd_buffer->batch, GENX(MI_PREDICATE), mip) {
@@ -3917,24 +3915,22 @@ emit_draw_count_predicate(struct anv_cmd_buffer *cmd_buffer,
static void static void
emit_draw_count_predicate_with_conditional_render( emit_draw_count_predicate_with_conditional_render(
struct anv_cmd_buffer *cmd_buffer, struct anv_cmd_buffer *cmd_buffer,
uint32_t draw_index) struct gen_mi_builder *b,
uint32_t draw_index,
struct gen_mi_value max)
{ {
struct gen_mi_builder b; struct gen_mi_value pred = gen_mi_ult(b, gen_mi_imm(draw_index), max);
gen_mi_builder_init(&b, &cmd_buffer->batch); pred = gen_mi_iand(b, pred, gen_mi_reg64(ANV_PREDICATE_RESULT_REG));
struct gen_mi_value pred = gen_mi_ult(&b, gen_mi_imm(draw_index),
gen_mi_reg64(TMP_DRAW_COUNT_REG));
pred = gen_mi_iand(&b, pred, gen_mi_reg64(ANV_PREDICATE_RESULT_REG));
#if GEN_GEN >= 8 #if GEN_GEN >= 8
gen_mi_store(&b, gen_mi_reg64(MI_PREDICATE_RESULT), pred); gen_mi_store(b, gen_mi_reg64(MI_PREDICATE_RESULT), pred);
#else #else
/* MI_PREDICATE_RESULT is not whitelisted in i915 command parser /* MI_PREDICATE_RESULT is not whitelisted in i915 command parser
* so we emit MI_PREDICATE to set it. * so we emit MI_PREDICATE to set it.
*/ */
gen_mi_store(&b, gen_mi_reg64(MI_PREDICATE_SRC0), pred); gen_mi_store(b, gen_mi_reg64(MI_PREDICATE_SRC0), pred);
gen_mi_store(&b, gen_mi_reg64(MI_PREDICATE_SRC1), gen_mi_imm(0)); gen_mi_store(b, gen_mi_reg64(MI_PREDICATE_SRC1), gen_mi_imm(0));
anv_batch_emit(&cmd_buffer->batch, GENX(MI_PREDICATE), mip) { anv_batch_emit(&cmd_buffer->batch, GENX(MI_PREDICATE), mip) {
mip.LoadOperation = LOAD_LOADINV; mip.LoadOperation = LOAD_LOADINV;
@@ -3966,23 +3962,26 @@ void genX(CmdDrawIndirectCount)(
genX(cmd_buffer_flush_state)(cmd_buffer); genX(cmd_buffer_flush_state)(cmd_buffer);
struct gen_mi_builder b;
gen_mi_builder_init(&b, &cmd_buffer->batch);
struct anv_address count_address = struct anv_address count_address =
anv_address_add(count_buffer->address, countBufferOffset); anv_address_add(count_buffer->address, countBufferOffset);
struct gen_mi_value max =
prepare_for_draw_count_predicate(cmd_buffer, count_address, prepare_for_draw_count_predicate(cmd_buffer, &b, count_address,
cmd_state->conditional_render_enabled); cmd_state->conditional_render_enabled);
for (uint32_t i = 0; i < maxDrawCount; i++) { for (uint32_t i = 0; i < maxDrawCount; i++) {
struct anv_address draw = anv_address_add(buffer->address, offset); struct anv_address draw = anv_address_add(buffer->address, offset);
#if GEN_GEN >= 8 || GEN_IS_HASWELL #if GEN_GEN >= 8 || GEN_IS_HASWELL
if (cmd_state->conditional_render_enabled) { if (cmd_state->conditional_render_enabled) {
emit_draw_count_predicate_with_conditional_render(cmd_buffer, i); emit_draw_count_predicate_with_conditional_render(
cmd_buffer, &b, i, gen_mi_value_ref(&b, max));
} else { } else {
emit_draw_count_predicate(cmd_buffer, i); emit_draw_count_predicate(cmd_buffer, &b, i);
} }
#else #else
emit_draw_count_predicate(cmd_buffer, i); emit_draw_count_predicate(cmd_buffer, &b, i);
#endif #endif
if (vs_prog_data->uses_firstvertex || if (vs_prog_data->uses_firstvertex ||
@@ -4009,6 +4008,8 @@ void genX(CmdDrawIndirectCount)(
offset += stride; offset += stride;
} }
gen_mi_value_unref(&b, max);
} }
void genX(CmdDrawIndexedIndirectCount)( void genX(CmdDrawIndexedIndirectCount)(
@@ -4032,23 +4033,26 @@ void genX(CmdDrawIndexedIndirectCount)(
genX(cmd_buffer_flush_state)(cmd_buffer); genX(cmd_buffer_flush_state)(cmd_buffer);
struct gen_mi_builder b;
gen_mi_builder_init(&b, &cmd_buffer->batch);
struct anv_address count_address = struct anv_address count_address =
anv_address_add(count_buffer->address, countBufferOffset); anv_address_add(count_buffer->address, countBufferOffset);
struct gen_mi_value max =
prepare_for_draw_count_predicate(cmd_buffer, count_address, prepare_for_draw_count_predicate(cmd_buffer, &b, count_address,
cmd_state->conditional_render_enabled); cmd_state->conditional_render_enabled);
for (uint32_t i = 0; i < maxDrawCount; i++) { for (uint32_t i = 0; i < maxDrawCount; i++) {
struct anv_address draw = anv_address_add(buffer->address, offset); struct anv_address draw = anv_address_add(buffer->address, offset);
#if GEN_GEN >= 8 || GEN_IS_HASWELL #if GEN_GEN >= 8 || GEN_IS_HASWELL
if (cmd_state->conditional_render_enabled) { if (cmd_state->conditional_render_enabled) {
emit_draw_count_predicate_with_conditional_render(cmd_buffer, i); emit_draw_count_predicate_with_conditional_render(
cmd_buffer, &b, i, gen_mi_value_ref(&b, max));
} else { } else {
emit_draw_count_predicate(cmd_buffer, i); emit_draw_count_predicate(cmd_buffer, &b, i);
} }
#else #else
emit_draw_count_predicate(cmd_buffer, i); emit_draw_count_predicate(cmd_buffer, &b, i);
#endif #endif
/* TODO: We need to stomp base vertex to 0 somehow */ /* TODO: We need to stomp base vertex to 0 somehow */
@@ -4076,6 +4080,8 @@ void genX(CmdDrawIndexedIndirectCount)(
offset += stride; offset += stride;
} }
gen_mi_value_unref(&b, max);
} }
void genX(CmdBeginTransformFeedbackEXT)( void genX(CmdBeginTransformFeedbackEXT)(

View File

@@ -32,8 +32,8 @@
#include "genxml/gen_macros.h" #include "genxml/gen_macros.h"
#include "genxml/genX_pack.h" #include "genxml/genX_pack.h"
/* We reserve GPR 14 and 15 for conditional rendering */ /* We reserve GPR 15 for conditional rendering */
#define GEN_MI_BUILDER_NUM_ALLOC_GPRS 14 #define GEN_MI_BUILDER_NUM_ALLOC_GPRS 15
#define __gen_get_batch_dwords anv_batch_emit_dwords #define __gen_get_batch_dwords anv_batch_emit_dwords
#define __gen_address_offset anv_address_add #define __gen_address_offset anv_address_add
#include "common/gen_mi_builder.h" #include "common/gen_mi_builder.h"