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:
@@ -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,10 +3962,12 @@ 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++) {
|
||||||
@@ -3977,12 +3975,13 @@ void genX(CmdDrawIndirectCount)(
|
|||||||
|
|
||||||
#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,10 +4033,12 @@ 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++) {
|
||||||
@@ -4043,12 +4046,13 @@ void genX(CmdDrawIndexedIndirectCount)(
|
|||||||
|
|
||||||
#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)(
|
||||||
|
@@ -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"
|
||||||
|
Reference in New Issue
Block a user