i965: Remove ring switching entirely

Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Jason Ekstrand 2018-05-11 18:16:48 -07:00
parent b499b85b0f
commit a347a5a12c
11 changed files with 61 additions and 105 deletions

View file

@ -182,7 +182,7 @@ brw_dispatch_compute_common(struct gl_context *ctx)
/* Flush the batch if the batch/state buffers are nearly full. We can
* grow them if needed, but this is not free, so we'd like to avoid it.
*/
intel_batchbuffer_require_space(brw, 600, RENDER_RING);
intel_batchbuffer_require_space(brw, 600);
brw_require_statebuffer_space(brw, 2500);
intel_batchbuffer_save_state(brw);

View file

@ -461,12 +461,6 @@ struct brw_query_object {
bool flushed;
};
enum brw_gpu_ring {
UNKNOWN_RING,
RENDER_RING,
BLT_RING,
};
struct brw_reloc_list {
struct drm_i915_gem_relocation_entry *relocs;
int reloc_count;
@ -497,7 +491,6 @@ struct intel_batchbuffer {
uint32_t *map_next;
uint32_t state_used;
enum brw_gpu_ring ring;
bool use_shadow_copy;
bool use_batch_first;
bool needs_sol_reset;

View file

@ -798,7 +798,7 @@ brw_draw_single_prim(struct gl_context *ctx,
/* Flush the batch if the batch/state buffers are nearly full. We can
* grow them if needed, but this is not free, so we'd like to avoid it.
*/
intel_batchbuffer_require_space(brw, 1500, RENDER_RING);
intel_batchbuffer_require_space(brw, 1500);
brw_require_statebuffer_space(brw, 2400);
intel_batchbuffer_save_state(brw);

View file

@ -348,7 +348,7 @@ brw_emit_depthbuffer(struct brw_context *brw)
brw_emit_depth_stall_flushes(brw);
const unsigned ds_dwords = brw->isl_dev.ds.size / 4;
intel_batchbuffer_begin(brw, ds_dwords, RENDER_RING);
intel_batchbuffer_begin(brw, ds_dwords);
uint32_t *ds_map = brw->batch.map_next;
const uint32_t ds_offset = (char *)ds_map - (char *)brw->batch.batch.map;

View file

@ -544,29 +544,17 @@ brw_emit_mi_flush(struct brw_context *brw)
{
const struct gen_device_info *devinfo = &brw->screen->devinfo;
if (brw->batch.ring == BLT_RING && devinfo->gen >= 6) {
const unsigned n_dwords = devinfo->gen >= 8 ? 5 : 4;
BEGIN_BATCH_BLT(n_dwords);
OUT_BATCH(MI_FLUSH_DW | (n_dwords - 2));
OUT_BATCH(0);
OUT_BATCH(0);
OUT_BATCH(0);
if (n_dwords == 5)
OUT_BATCH(0);
ADVANCE_BATCH();
} else {
int flags = PIPE_CONTROL_RENDER_TARGET_FLUSH;
if (devinfo->gen >= 6) {
flags |= PIPE_CONTROL_INSTRUCTION_INVALIDATE |
PIPE_CONTROL_CONST_CACHE_INVALIDATE |
PIPE_CONTROL_DATA_CACHE_FLUSH |
PIPE_CONTROL_DEPTH_CACHE_FLUSH |
PIPE_CONTROL_VF_CACHE_INVALIDATE |
PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE |
PIPE_CONTROL_CS_STALL;
}
brw_emit_pipe_control_flush(brw, flags);
int flags = PIPE_CONTROL_RENDER_TARGET_FLUSH;
if (devinfo->gen >= 6) {
flags |= PIPE_CONTROL_INSTRUCTION_INVALIDATE |
PIPE_CONTROL_CONST_CACHE_INVALIDATE |
PIPE_CONTROL_DATA_CACHE_FLUSH |
PIPE_CONTROL_DEPTH_CACHE_FLUSH |
PIPE_CONTROL_VF_CACHE_INVALIDATE |
PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE |
PIPE_CONTROL_CS_STALL;
}
brw_emit_pipe_control_flush(brw, flags);
}
int

View file

@ -264,5 +264,5 @@ void brw_upload_urb_fence(struct brw_context *brw)
while (--pad);
}
intel_batchbuffer_data(brw, &uf, sizeof(uf), RENDER_RING);
intel_batchbuffer_data(brw, &uf, sizeof(uf));
}

View file

@ -44,7 +44,7 @@ blorp_emit_dwords(struct blorp_batch *batch, unsigned n)
assert(batch->blorp->driver_ctx == batch->driver_batch);
struct brw_context *brw = batch->driver_batch;
intel_batchbuffer_begin(brw, n, RENDER_RING);
intel_batchbuffer_begin(brw, n);
uint32_t *map = brw->batch.map_next;
brw->batch.map_next += n;
intel_batchbuffer_advance(brw);
@ -277,7 +277,7 @@ genX(blorp_exec)(struct blorp_batch *batch,
brw_select_pipeline(brw, BRW_RENDER_PIPELINE);
retry:
intel_batchbuffer_require_space(brw, 1400, RENDER_RING);
intel_batchbuffer_require_space(brw, 1400);
brw_require_statebuffer_space(brw, 600);
intel_batchbuffer_save_state(brw);
brw->batch.no_wrap = true;

View file

@ -59,7 +59,7 @@
UNUSED static void *
emit_dwords(struct brw_context *brw, unsigned n)
{
intel_batchbuffer_begin(brw, n, RENDER_RING);
intel_batchbuffer_begin(brw, n);
uint32_t *map = brw->batch.map_next;
brw->batch.map_next += n;
intel_batchbuffer_advance(brw);

View file

@ -274,11 +274,6 @@ intel_batchbuffer_reset(struct brw_context *brw)
batch->needs_sol_reset = false;
batch->state_base_address_emitted = false;
/* We don't know what ring the new batch will be sent to until we see the
* first BEGIN_BATCH or BEGIN_BATCH_BLT. Mark it as unknown.
*/
batch->ring = UNKNOWN_RING;
if (batch->state_batch_sizes)
_mesa_hash_table_clear(batch->state_batch_sizes, NULL);
}
@ -311,8 +306,6 @@ intel_batchbuffer_reset_to_saved(struct brw_context *brw)
brw->batch.exec_count = brw->batch.saved.exec_count;
brw->batch.map_next = brw->batch.saved.map_next;
if (USED_BATCH(brw->batch) == 0)
brw->batch.ring = UNKNOWN_RING;
}
void
@ -507,18 +500,10 @@ grow_buffer(struct brw_context *brw,
}
void
intel_batchbuffer_require_space(struct brw_context *brw, GLuint sz,
enum brw_gpu_ring ring)
intel_batchbuffer_require_space(struct brw_context *brw, GLuint sz)
{
const struct gen_device_info *devinfo = &brw->screen->devinfo;
struct intel_batchbuffer *batch = &brw->batch;
/* If we're switching rings, implicitly flush the batch. */
if (unlikely(ring != brw->batch.ring) && brw->batch.ring != UNKNOWN_RING &&
devinfo->gen >= 6) {
intel_batchbuffer_flush(brw);
}
const unsigned batch_used = USED_BATCH(*batch) * 4;
if (batch_used + sz >= BATCH_SZ && !batch->no_wrap) {
intel_batchbuffer_flush(brw);
@ -530,11 +515,6 @@ intel_batchbuffer_require_space(struct brw_context *brw, GLuint sz,
batch->map_next = (void *) batch->batch.map + batch_used;
assert(batch_used + sz < batch->batch.bo->size);
}
/* The intel_batchbuffer_flush() calls above might have changed
* brw->batch.ring to UNKNOWN_RING, so we need to set it here at the end.
*/
brw->batch.ring = ring;
}
/**
@ -601,46 +581,44 @@ brw_finish_batch(struct brw_context *brw)
*/
brw_emit_query_end(brw);
if (brw->batch.ring == RENDER_RING) {
/* Work around L3 state leaks into contexts set MI_RESTORE_INHIBIT which
* assume that the L3 cache is configured according to the hardware
* defaults. On Kernel 4.16+, we no longer need to do this.
/* Work around L3 state leaks into contexts set MI_RESTORE_INHIBIT which
* assume that the L3 cache is configured according to the hardware
* defaults. On Kernel 4.16+, we no longer need to do this.
*/
if (devinfo->gen >= 7 &&
!(brw->screen->kernel_features & KERNEL_ALLOWS_CONTEXT_ISOLATION))
gen7_restore_default_l3_config(brw);
if (devinfo->is_haswell) {
/* From the Haswell PRM, Volume 2b, Command Reference: Instructions,
* 3DSTATE_CC_STATE_POINTERS > "Note":
*
* "SW must program 3DSTATE_CC_STATE_POINTERS command at the end of every
* 3D batch buffer followed by a PIPE_CONTROL with RC flush and CS stall."
*
* From the example in the docs, it seems to expect a regular pipe control
* flush here as well. We may have done it already, but meh.
*
* See also WaAvoidRCZCounterRollover.
*/
if (devinfo->gen >= 7 &&
!(brw->screen->kernel_features & KERNEL_ALLOWS_CONTEXT_ISOLATION))
gen7_restore_default_l3_config(brw);
if (devinfo->is_haswell) {
/* From the Haswell PRM, Volume 2b, Command Reference: Instructions,
* 3DSTATE_CC_STATE_POINTERS > "Note":
*
* "SW must program 3DSTATE_CC_STATE_POINTERS command at the end of every
* 3D batch buffer followed by a PIPE_CONTROL with RC flush and CS stall."
*
* From the example in the docs, it seems to expect a regular pipe control
* flush here as well. We may have done it already, but meh.
*
* See also WaAvoidRCZCounterRollover.
*/
brw_emit_mi_flush(brw);
BEGIN_BATCH(2);
OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (2 - 2));
OUT_BATCH(brw->cc.state_offset | 1);
ADVANCE_BATCH();
brw_emit_pipe_control_flush(brw, PIPE_CONTROL_RENDER_TARGET_FLUSH |
PIPE_CONTROL_CS_STALL);
}
/* Do not restore push constant packets during context restore. */
if (devinfo->gen >= 7)
gen10_emit_isp_disable(brw);
brw_emit_mi_flush(brw);
BEGIN_BATCH(2);
OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (2 - 2));
OUT_BATCH(brw->cc.state_offset | 1);
ADVANCE_BATCH();
brw_emit_pipe_control_flush(brw, PIPE_CONTROL_RENDER_TARGET_FLUSH |
PIPE_CONTROL_CS_STALL);
}
/* Do not restore push constant packets during context restore. */
if (devinfo->gen >= 7)
gen10_emit_isp_disable(brw);
/* Emit MI_BATCH_BUFFER_END to finish our batch. Note that execbuf2
* requires our batch size to be QWord aligned, so we pad it out if
* necessary by emitting an extra MI_NOOP after the end.
*/
intel_batchbuffer_require_space(brw, 8, brw->batch.ring);
intel_batchbuffer_require_space(brw, 8);
*brw->batch.map_next++ = MI_BATCH_BUFFER_END;
if (USED_BATCH(brw->batch) & 1) {
*brw->batch.map_next++ = MI_NOOP;
@ -747,7 +725,6 @@ execbuffer(int fd,
static int
submit_batch(struct brw_context *brw, int in_fence_fd, int *out_fence_fd)
{
const struct gen_device_info *devinfo = &brw->screen->devinfo;
__DRIscreen *dri_screen = brw->screen->driScrnPriv;
struct intel_batchbuffer *batch = &brw->batch;
int ret = 0;
@ -776,7 +753,6 @@ submit_batch(struct brw_context *brw, int in_fence_fd, int *out_fence_fd)
* To avoid stalling, execobject.offset should match the current
* address of that object within the active context.
*/
assert(devinfo->gen < 6 || batch->ring == RENDER_RING);
int flags = I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
if (batch->needs_sol_reset)
@ -1045,10 +1021,10 @@ brw_state_batch(struct brw_context *brw,
void
intel_batchbuffer_data(struct brw_context *brw,
const void *data, GLuint bytes, enum brw_gpu_ring ring)
const void *data, GLuint bytes)
{
assert((bytes & 3) == 0);
intel_batchbuffer_require_space(brw, bytes, ring);
intel_batchbuffer_require_space(brw, bytes);
memcpy(brw->batch.map_next, data, bytes);
brw->batch.map_next += bytes >> 2;
}

View file

@ -25,8 +25,7 @@ void intel_batchbuffer_init(struct brw_context *brw);
void intel_batchbuffer_free(struct intel_batchbuffer *batch);
void intel_batchbuffer_save_state(struct brw_context *brw);
void intel_batchbuffer_reset_to_saved(struct brw_context *brw);
void intel_batchbuffer_require_space(struct brw_context *brw, GLuint sz,
enum brw_gpu_ring ring);
void intel_batchbuffer_require_space(struct brw_context *brw, GLuint sz);
int _intel_batchbuffer_flush_fence(struct brw_context *brw,
int in_fence_fd, int *out_fence_fd,
const char *file, int line);
@ -43,8 +42,7 @@ int _intel_batchbuffer_flush_fence(struct brw_context *brw,
* intel_buffer_dword() calls.
*/
void intel_batchbuffer_data(struct brw_context *brw,
const void *data, GLuint bytes,
enum brw_gpu_ring ring);
const void *data, GLuint bytes);
bool brw_batch_has_aperture_space(struct brw_context *brw,
unsigned extra_space_in_bytes);
@ -81,9 +79,9 @@ static inline uint32_t float_as_int(float f)
}
static inline void
intel_batchbuffer_begin(struct brw_context *brw, int n, enum brw_gpu_ring ring)
intel_batchbuffer_begin(struct brw_context *brw, int n)
{
intel_batchbuffer_require_space(brw, n * 4, ring);
intel_batchbuffer_require_space(brw, n * 4);
#ifdef DEBUG
brw->batch.emit = USED_BATCH(brw->batch);
@ -117,12 +115,13 @@ brw_ptr_in_state_buffer(struct intel_batchbuffer *batch, void *p)
}
#define BEGIN_BATCH(n) do { \
intel_batchbuffer_begin(brw, (n), RENDER_RING); \
intel_batchbuffer_begin(brw, (n)); \
uint32_t *__map = brw->batch.map_next; \
brw->batch.map_next += (n)
#define BEGIN_BATCH_BLT(n) do { \
intel_batchbuffer_begin(brw, (n), BLT_RING); \
assert(brw->screen->devinfo.gen < 6); \
intel_batchbuffer_begin(brw, (n)); \
uint32_t *__map = brw->batch.map_next; \
brw->batch.map_next += (n)

View file

@ -288,7 +288,7 @@ emit_copy_blit(struct brw_context *brw,
unsigned length = devinfo->gen >= 8 ? 10 : 8;
intel_batchbuffer_require_space(brw, length * 4, BLT_RING);
intel_batchbuffer_require_space(brw, length * 4);
DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
__func__,
src_buffer, src_pitch, src_offset, src_x, src_y,
@ -661,7 +661,7 @@ intelEmitImmediateColorExpandBlit(struct brw_context *brw,
unsigned xy_setup_blt_length = devinfo->gen >= 8 ? 10 : 8;
intel_batchbuffer_require_space(brw, (xy_setup_blt_length * 4) +
(3 * 4) + dwords * 4, BLT_RING);
(3 * 4) + dwords * 4);
opcode = XY_SETUP_BLT_CMD;
if (cpp == 4)
@ -699,7 +699,7 @@ intelEmitImmediateColorExpandBlit(struct brw_context *brw,
OUT_BATCH(SET_FIELD(y + h, BLT_Y) | SET_FIELD(x + w, BLT_X));
ADVANCE_BATCH();
intel_batchbuffer_data(brw, src_bits, dwords * 4, BLT_RING);
intel_batchbuffer_data(brw, src_bits, dwords * 4);
brw_emit_mi_flush(brw);