nv2a: Squash repeated draw arrays

This commit is contained in:
Matt Borgerson 2021-03-11 02:01:14 -07:00 committed by mborgerson
parent 33f8d3c88c
commit 5756a8892c
3 changed files with 37 additions and 15 deletions

View File

@ -489,9 +489,9 @@ void *nv_dma_map(NV2AState *d, hwaddr dma_obj_address, hwaddr *len);
void pgraph_init(NV2AState *d);
void pgraph_destroy(PGRAPHState *pg);
void pgraph_context_switch(NV2AState *d, unsigned int channel_id);
int pgraph_method(NV2AState *d, unsigned int subchannel,
unsigned int method, uint32_t parameter,
uint32_t *parameters, size_t num_words_available);
int pgraph_method(NV2AState *d, unsigned int subchannel, unsigned int method,
uint32_t parameter, uint32_t *parameters,
size_t num_words_available, size_t max_lookahead_words);
void pgraph_gl_sync(NV2AState *d);
void pgraph_process_pending_downloads(NV2AState *d);

View File

@ -146,7 +146,8 @@ static bool pfifo_puller_should_stall(NV2AState *d)
static ssize_t pfifo_run_puller(NV2AState *d, uint32_t method_entry,
uint32_t parameter, uint32_t *parameters,
size_t num_words_available)
size_t num_words_available,
size_t max_lookahead_words)
{
if (pfifo_puller_should_stall(d)) {
return -1;
@ -188,8 +189,9 @@ static ssize_t pfifo_run_puller(NV2AState *d, uint32_t method_entry,
if (pgraph_can_fifo_access(d)) {
pgraph_context_switch(d, entry.channel_id);
if (!d->pgraph.waiting_for_context_switch) {
num_proc = pgraph_method(d, subchannel, 0, entry.instance,
parameters, num_words_available);
num_proc =
pgraph_method(d, subchannel, 0, entry.instance, parameters,
num_words_available, max_lookahead_words);
}
}
@ -219,8 +221,9 @@ static ssize_t pfifo_run_puller(NV2AState *d, uint32_t method_entry,
qemu_mutex_lock(&d->pgraph.lock);
if (pgraph_can_fifo_access(d)) {
num_proc = pgraph_method(d, subchannel, method, parameter,
parameters, num_words_available);
num_proc =
pgraph_method(d, subchannel, method, parameter, parameters,
num_words_available, max_lookahead_words);
}
qemu_mutex_unlock(&d->pgraph.lock);
@ -331,7 +334,8 @@ static void pfifo_run_pusher(NV2AState *d)
ssize_t num_words_processed =
pfifo_run_puller(d, method_entry, word, word_ptr,
MIN(method_count, num_words_available));
MIN(method_count, num_words_available),
num_words_available);
if (num_words_processed < 0) {
break;
}
@ -343,7 +347,7 @@ static void pfifo_run_pusher(NV2AState *d)
(method + 4*num_words_processed) >> 2);
}
SET_MASK(*dma_state, NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT,
method_count - num_words_processed);
method_count - MIN(method_count, num_words_processed));
(*dma_dcount) += num_words_processed;
} else {

View File

@ -709,7 +709,8 @@ static const MethodFunc pgraph_kelvin_method_handlers[0x800] = {
int pgraph_method(NV2AState *d, unsigned int subchannel,
unsigned int method, uint32_t parameter,
uint32_t *parameters, size_t num_words_available)
uint32_t *parameters, size_t num_words_available,
size_t max_lookahead_words)
{
int num_processed = 1;
@ -924,10 +925,27 @@ int pgraph_method(NV2AState *d, unsigned int subchannel,
graphics_class, method);
} else {
size_t num_words_consumed = 1;
handler(d, pg,
subchannel, method,
parameter, parameters,
num_words_available, &num_words_consumed);
handler(d, pg, subchannel, method, parameter, parameters,
num_words_available, &num_words_consumed);
/* Squash repeated BEGIN,DRAW_ARRAYS,END */
#define LAM(i, mthd) ((parameters[i*2+1] & 0x31fff) == (mthd))
#define LAP(i, prm) (parameters[i*2+2] == (prm))
#define LAMP(i, mthd, prm) (LAM(i, mthd) && LAP(i, prm))
if (method == NV097_DRAW_ARRAYS && (max_lookahead_words >= 7) &&
pg->draw_arrays_length <
(ARRAY_SIZE(pg->gl_draw_arrays_start) - 1) &&
LAMP(0, NV097_SET_BEGIN_END, NV097_SET_BEGIN_END_OP_END) &&
LAMP(1, NV097_SET_BEGIN_END, pg->primitive_mode) &&
LAM(2, NV097_DRAW_ARRAYS)) {
num_words_consumed += 4;
}
#undef LAM
#undef LAP
#undef LAMP
num_processed = num_words_consumed;
}
}