Selaa lähdekoodia

radeonsi: move sync handling into new state handler

So we can remove all the old atom handling.

Signed-off-by: Christian König <deathsimple@vodafone.de>
tags/mesa-9.0
Christian König 13 vuotta sitten
vanhempi
commit
583c212115

+ 2
- 2
src/gallium/drivers/radeonsi/Makefile.sources Näytä tiedosto

@@ -9,8 +9,8 @@ C_SOURCES := \
r600_texture.c \
evergreen_hw_context.c \
r600_translate.c \
r600_state_common.c \
radeonsi_pm4.c \
si_state.c \
si_state_streamout.c \
si_state_draw.c
si_state_draw.c \
si_commands.c

+ 16
- 18
src/gallium/drivers/radeonsi/r600_hw_context.c Näytä tiedosto

@@ -119,17 +119,11 @@ err:
void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw,
boolean count_draw_in)
{
struct r600_atom *state;

/* The number of dwords we already used in the CS so far. */
num_dw += ctx->cs->cdw;

if (count_draw_in) {
/* The number of dwords all the dirty states would take. */
LIST_FOR_EACH_ENTRY(state, &ctx->dirty_states, head) {
num_dw += state->num_dw;
}

num_dw += ctx->pm4_dirty_cdwords;

/* The upper-bound of how much a draw command would take. */
@@ -159,20 +153,25 @@ void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw,
}
}

static void r600_flush_framebuffer(struct r600_context *ctx, bool flush_now)
static void r600_flush_framebuffer(struct r600_context *ctx)
{
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);

if (!(ctx->flags & R600_CONTEXT_DST_CACHES_DIRTY))
return;

ctx->atom_surface_sync.flush_flags |=
r600_get_cb_flush_flags(ctx) |
(ctx->framebuffer.zsbuf ? S_0085F0_DB_ACTION_ENA(1) | S_0085F0_DB_DEST_BASE_ENA(1) : 0);

if (flush_now) {
r600_emit_atom(ctx, &ctx->atom_surface_sync.atom);
} else {
r600_atom_dirty(ctx, &ctx->atom_surface_sync.atom);
}
si_cmd_surface_sync(pm4, S_0085F0_CB0_DEST_BASE_ENA(1) |
S_0085F0_CB1_DEST_BASE_ENA(1) |
S_0085F0_CB2_DEST_BASE_ENA(1) |
S_0085F0_CB3_DEST_BASE_ENA(1) |
S_0085F0_CB4_DEST_BASE_ENA(1) |
S_0085F0_CB5_DEST_BASE_ENA(1) |
S_0085F0_CB6_DEST_BASE_ENA(1) |
S_0085F0_CB7_DEST_BASE_ENA(1) |
S_0085F0_DB_ACTION_ENA(1) |
S_0085F0_DB_DEST_BASE_ENA(1));
si_pm4_emit(ctx, pm4);
si_pm4_free_state(ctx, pm4, ~0);

ctx->flags &= ~R600_CONTEXT_DST_CACHES_DIRTY;
}
@@ -180,7 +179,6 @@ static void r600_flush_framebuffer(struct r600_context *ctx, bool flush_now)
void r600_context_flush(struct r600_context *ctx, unsigned flags)
{
struct radeon_winsys_cs *cs = ctx->cs;
struct r600_block *enable_block = NULL;
bool queries_suspended = false;

#if 0
@@ -203,7 +201,7 @@ void r600_context_flush(struct r600_context *ctx, unsigned flags)
}
#endif

r600_flush_framebuffer(ctx, true);
r600_flush_framebuffer(ctx);

/* partial flush is needed to avoid lockups on some chips with user fences */
cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0);

+ 0
- 77
src/gallium/drivers/radeonsi/r600_state_common.c Näytä tiedosto

@@ -1,77 +0,0 @@
/*
* Copyright 2010 Red Hat Inc.
* 2010 Jerome Glisse
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Dave Airlie <airlied@redhat.com>
* Jerome Glisse <jglisse@redhat.com>
*/
#include "util/u_blitter.h"
#include "util/u_memory.h"
#include "util/u_format.h"
#include "pipebuffer/pb_buffer.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi/tgsi_parse.h"
#include "r600_hw_context_priv.h"
#include "radeonsi_pipe.h"
#include "sid.h"
#include "si_state.h"

static void r600_emit_surface_sync(struct r600_context *rctx, struct r600_atom *atom)
{
struct radeon_winsys_cs *cs = rctx->cs;
struct r600_atom_surface_sync *a = (struct r600_atom_surface_sync*)atom;

cs->buf[cs->cdw++] = PKT3(PKT3_SURFACE_SYNC, 3, 0);
cs->buf[cs->cdw++] = a->flush_flags; /* CP_COHER_CNTL */
cs->buf[cs->cdw++] = 0xffffffff; /* CP_COHER_SIZE */
cs->buf[cs->cdw++] = 0; /* CP_COHER_BASE */
cs->buf[cs->cdw++] = 0x0000000A; /* POLL_INTERVAL */

a->flush_flags = 0;
}

static void r600_init_atom(struct r600_atom *atom,
void (*emit)(struct r600_context *ctx, struct r600_atom *state),
unsigned num_dw,
enum r600_atom_flags flags)
{
atom->emit = emit;
atom->num_dw = num_dw;
atom->flags = flags;
}

void r600_init_common_atoms(struct r600_context *rctx)
{
r600_init_atom(&rctx->atom_surface_sync.atom, r600_emit_surface_sync, 5, EMIT_EARLY);
}

unsigned r600_get_cb_flush_flags(struct r600_context *rctx)
{
unsigned flags = 0;

if (rctx->framebuffer.nr_cbufs) {
flags |= S_0085F0_CB_ACTION_ENA(1) |
(((1 << rctx->framebuffer.nr_cbufs) - 1) << S_0085F0_CB0_DEST_BASE_ENA_SHIFT);
}

return flags;
}

+ 0
- 4
src/gallium/drivers/radeonsi/radeonsi_pipe.c Näytä tiedosto

@@ -214,8 +214,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
rctx->context.create_video_decoder = vl_create_decoder;
rctx->context.create_video_buffer = vl_video_buffer_create;

r600_init_common_atoms(rctx);

switch (rctx->chip_class) {
case TAHITI:
si_init_state_functions(rctx);
@@ -251,8 +249,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
return NULL;
}

LIST_INITHEAD(&rctx->dirty_states);

r600_get_backend_mask(rctx); /* this emits commands and must be last */

rctx->dummy_pixel_shader =

+ 0
- 52
src/gallium/drivers/radeonsi/radeonsi_pipe.h Näytä tiedosto

@@ -50,30 +50,6 @@
#define R600_BIG_ENDIAN 0
#endif

enum r600_atom_flags {
/* When set, atoms are added at the beginning of the dirty list
* instead of the end. */
EMIT_EARLY = (1 << 0)
};

/* This encapsulates a state or an operation which can emitted into the GPU
* command stream. It's not limited to states only, it can be used for anything
* that wants to write commands into the CS (e.g. cache flushes). */
struct r600_atom {
void (*emit)(struct r600_context *ctx, struct r600_atom *state);

unsigned num_dw;
enum r600_atom_flags flags;
bool dirty;

struct list_head head;
};

struct r600_atom_surface_sync {
struct r600_atom atom;
unsigned flush_flags; /* CP_COHER_CNTL */
};

struct r600_pipe_fences {
struct si_resource *bo;
unsigned *data;
@@ -171,10 +147,6 @@ struct r600_context {

unsigned default_ps_gprs, default_vs_gprs;

/* States based on r600_state. */
struct list_head dirty_states;
struct r600_atom_surface_sync atom_surface_sync;

/* Below are variables from the old r600_context.
*/
struct radeon_winsys_cs *cs;
@@ -213,26 +185,6 @@ struct r600_context {
union si_state emitted;
};

static INLINE void r600_emit_atom(struct r600_context *rctx, struct r600_atom *atom)
{
atom->emit(rctx, atom);
atom->dirty = false;
if (atom->head.next && atom->head.prev)
LIST_DELINIT(&atom->head);
}

static INLINE void r600_atom_dirty(struct r600_context *rctx, struct r600_atom *state)
{
if (!state->dirty) {
if (state->flags & EMIT_EARLY) {
LIST_ADD(&state->head, &rctx->dirty_states);
} else {
LIST_ADDTAIL(&state->head, &rctx->dirty_states);
}
state->dirty = true;
}
}

/* r600_blit.c */
void r600_init_blit_functions(struct r600_context *rctx);
void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *texture);
@@ -271,10 +223,6 @@ void r600_translate_index_buffer(struct r600_context *r600,
struct pipe_index_buffer *ib,
unsigned count);

/* r600_state_common.c */
void r600_init_common_atoms(struct r600_context *rctx);
unsigned r600_get_cb_flush_flags(struct r600_context *rctx);

/*
* common helpers
*/

+ 28
- 15
src/gallium/drivers/radeonsi/radeonsi_pm4.c Näytä tiedosto

@@ -131,7 +131,7 @@ void si_pm4_free_state(struct r600_context *rctx,
if (state == NULL)
return;

if (rctx->emitted.array[idx] == state) {
if (idx != ~0 && rctx->emitted.array[idx] == state) {
rctx->emitted.array[idx] = NULL;
}

@@ -141,10 +141,24 @@ void si_pm4_free_state(struct r600_context *rctx,
FREE(state);
}

uint32_t si_pm4_sync_flags(struct r600_context *rctx)
{
uint32_t cp_coher_cntl = 0;

for (int i = 0; i < NUMBER_OF_STATES; ++i) {
struct si_pm4_state *state = rctx->queued.array[i];

if (!state || rctx->emitted.array[i] == state)
continue;

cp_coher_cntl |= state->cp_coher_cntl;
}
return cp_coher_cntl;
}

unsigned si_pm4_dirty_dw(struct r600_context *rctx)
{
unsigned count = 0;
uint32_t cp_coher_cntl = 0;

for (int i = 0; i < NUMBER_OF_STATES; ++i) {
struct si_pm4_state *state = rctx->queued.array[i];
@@ -153,33 +167,32 @@ unsigned si_pm4_dirty_dw(struct r600_context *rctx)
continue;

count += state->ndw;
cp_coher_cntl |= state->cp_coher_cntl;
}

//TODO
rctx->atom_surface_sync.flush_flags |= cp_coher_cntl;
r600_atom_dirty(rctx, &rctx->atom_surface_sync.atom);
return count;
}

void si_pm4_emit_dirty(struct r600_context *rctx)
void si_pm4_emit(struct r600_context *rctx, struct si_pm4_state *state)
{
struct radeon_winsys_cs *cs = rctx->cs;
for (int i = 0; i < state->nbo; ++i) {
r600_context_bo_reloc(rctx, state->bo[i],
state->bo_usage[i]);
}

memcpy(&cs->buf[cs->cdw], state->pm4, state->ndw * 4);
cs->cdw += state->ndw;
}

void si_pm4_emit_dirty(struct r600_context *rctx)
{
for (int i = 0; i < NUMBER_OF_STATES; ++i) {
struct si_pm4_state *state = rctx->queued.array[i];

if (!state || rctx->emitted.array[i] == state)
continue;

for (int j = 0; j < state->nbo; ++j) {
r600_context_bo_reloc(rctx, state->bo[j],
state->bo_usage[j]);
}

memcpy(&cs->buf[cs->cdw], state->pm4, state->ndw * 4);
cs->cdw += state->ndw;

si_pm4_emit(rctx, state);
rctx->emitted.array[i] = state;
}
}

+ 3
- 0
src/gallium/drivers/radeonsi/radeonsi_pm4.h Näytä tiedosto

@@ -73,7 +73,10 @@ void si_pm4_inval_zsbuf_cache(struct si_pm4_state *state);
void si_pm4_free_state(struct r600_context *rctx,
struct si_pm4_state *state,
unsigned idx);

uint32_t si_pm4_sync_flags(struct r600_context *rctx);
unsigned si_pm4_dirty_dw(struct r600_context *rctx);
void si_pm4_emit(struct r600_context *rctx, struct si_pm4_state *state);
void si_pm4_emit_dirty(struct r600_context *rctx);
void si_pm4_reset_emitted(struct r600_context *rctx);


+ 39
- 0
src/gallium/drivers/radeonsi/si_commands.c Näytä tiedosto

@@ -0,0 +1,39 @@
/*
* Copyright 2012 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Christian König <christian.koenig@amd.com>
*/

#include "radeonsi_pipe.h"
#include "radeonsi_pm4.h"
#include "sid.h"

void si_cmd_surface_sync(struct si_pm4_state *pm4, uint32_t cp_coher_cntl)
{
si_pm4_cmd_begin(pm4, PKT3_SURFACE_SYNC);
si_pm4_cmd_add(pm4, cp_coher_cntl); /* CP_COHER_CNTL */
si_pm4_cmd_add(pm4, 0xffffffff); /* CP_COHER_SIZE */
si_pm4_cmd_add(pm4, 0); /* CP_COHER_BASE */
si_pm4_cmd_add(pm4, 0x0000000A); /* POLL_INTERVAL */
si_pm4_cmd_end(pm4, false);
}

+ 4
- 0
src/gallium/drivers/radeonsi/si_state.h Näytä tiedosto

@@ -70,6 +70,7 @@ struct si_vertex_element

union si_state {
struct {
struct si_pm4_state *sync;
struct si_pm4_state *init;
struct si_state_blend *blend;
struct si_pm4_state *blend_color;
@@ -148,4 +149,7 @@ void si_set_so_targets(struct pipe_context *ctx,
/* si_state_draw.c */
void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo);

/* si_commands.c */
void si_cmd_surface_sync(struct si_pm4_state *pm4, uint32_t cp_coher_cntl);

#endif

+ 8
- 4
src/gallium/drivers/radeonsi/si_state_draw.c Näytä tiedosto

@@ -466,7 +466,7 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
struct pipe_draw_info info = *dinfo;
struct r600_draw rdraw = {};
struct pipe_index_buffer ib = {};
struct r600_atom *state = NULL, *next_state = NULL;
uint32_t cp_coher_cntl;

if ((!info.count && (info.indexed || !info.count_from_stream_output)) ||
(info.indexed && !rctx->index_buffer.buffer)) {
@@ -524,14 +524,18 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
rdraw.db_render_override = dsa->db_render_override;
rdraw.db_render_control = dsa->db_render_control;

cp_coher_cntl = si_pm4_sync_flags(rctx);
if (cp_coher_cntl) {
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
si_cmd_surface_sync(pm4, cp_coher_cntl);
si_pm4_set_state(rctx, sync, pm4);
}

/* Emit states. */
rctx->pm4_dirty_cdwords += si_pm4_dirty_dw(rctx);

r600_need_cs_space(rctx, 0, TRUE);

LIST_FOR_EACH_ENTRY_SAFE(state, next_state, &rctx->dirty_states, head) {
r600_emit_atom(rctx, state);
}
si_pm4_emit_dirty(rctx);
rctx->pm4_dirty_cdwords = 0;


Loading…
Peruuta
Tallenna