Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5563 → Rev 5564

/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/radeonsi/si_hw_context.c
0,0 → 1,166
/*
* Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
*
* 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:
* Jerome Glisse
*/
 
#include "si_pipe.h"
 
/* initialize */
void si_need_cs_space(struct si_context *ctx, unsigned num_dw,
boolean count_draw_in)
{
int i;
 
/* The number of dwords we already used in the CS so far. */
num_dw += ctx->b.rings.gfx.cs->cdw;
 
if (count_draw_in) {
for (i = 0; i < SI_NUM_ATOMS(ctx); i++) {
if (ctx->atoms.array[i]->dirty) {
num_dw += ctx->atoms.array[i]->num_dw;
}
}
 
/* The number of dwords all the dirty states would take. */
num_dw += si_pm4_dirty_dw(ctx);
 
/* The upper-bound of how much a draw command would take. */
num_dw += SI_MAX_DRAW_CS_DWORDS;
}
 
/* Count in queries_suspend. */
num_dw += ctx->b.num_cs_dw_nontimer_queries_suspend;
 
/* Count in streamout_end at the end of CS. */
if (ctx->b.streamout.begin_emitted) {
num_dw += ctx->b.streamout.num_dw_for_end;
}
 
/* Count in render_condition(NULL) at the end of CS. */
if (ctx->b.predicate_drawing) {
num_dw += 3;
}
 
/* Count in framebuffer cache flushes at the end of CS. */
num_dw += ctx->atoms.s.cache_flush->num_dw;
 
#if SI_TRACE_CS
if (ctx->screen->b.trace_bo) {
num_dw += SI_TRACE_CS_DWORDS;
}
#endif
 
/* Flush if there's not enough space. */
if (num_dw > RADEON_MAX_CMDBUF_DWORDS) {
ctx->b.rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
}
}
 
void si_context_gfx_flush(void *context, unsigned flags,
struct pipe_fence_handle **fence)
{
struct si_context *ctx = context;
struct radeon_winsys_cs *cs = ctx->b.rings.gfx.cs;
 
if (cs->cdw == ctx->b.initial_gfx_cs_size && !fence)
return;
 
ctx->b.rings.gfx.flushing = true;
 
r600_preflush_suspend_features(&ctx->b);
 
ctx->b.flags |= SI_CONTEXT_FLUSH_AND_INV_FRAMEBUFFER |
SI_CONTEXT_INV_TC_L1 |
SI_CONTEXT_INV_TC_L2 |
/* this is probably not needed anymore */
SI_CONTEXT_PS_PARTIAL_FLUSH;
si_emit_cache_flush(&ctx->b, NULL);
 
/* force to keep tiling flags */
flags |= RADEON_FLUSH_KEEP_TILING_FLAGS;
 
/* Flush the CS. */
ctx->b.ws->cs_flush(cs, flags, fence, ctx->screen->b.cs_count++);
ctx->b.rings.gfx.flushing = false;
 
#if SI_TRACE_CS
if (ctx->screen->b.trace_bo) {
struct si_screen *sscreen = ctx->screen;
unsigned i;
 
for (i = 0; i < 10; i++) {
usleep(5);
if (!ctx->b.ws->buffer_is_busy(sscreen->b.trace_bo->buf, RADEON_USAGE_READWRITE)) {
break;
}
}
if (i == 10) {
fprintf(stderr, "timeout on cs lockup likely happen at cs %d dw %d\n",
sscreen->b.trace_ptr[1], sscreen->b.trace_ptr[0]);
} else {
fprintf(stderr, "cs %d executed in %dms\n", sscreen->b.trace_ptr[1], i * 5);
}
}
#endif
 
si_begin_new_cs(ctx);
}
 
void si_begin_new_cs(struct si_context *ctx)
{
/* Flush read caches at the beginning of CS. */
ctx->b.flags |= SI_CONTEXT_INV_TC_L1 |
SI_CONTEXT_INV_TC_L2 |
SI_CONTEXT_INV_KCACHE |
SI_CONTEXT_INV_ICACHE;
 
/* set all valid group as dirty so they get reemited on
* next draw command
*/
si_pm4_reset_emitted(ctx);
 
/* The CS initialization should be emitted before everything else. */
si_pm4_emit(ctx, ctx->init_config);
 
ctx->clip_regs.dirty = true;
ctx->framebuffer.atom.dirty = true;
ctx->msaa_sample_locs.dirty = true;
ctx->msaa_config.dirty = true;
ctx->db_render_state.dirty = true;
ctx->b.streamout.enable_atom.dirty = true;
si_all_descriptors_begin_new_cs(ctx);
 
r600_postflush_resume_features(&ctx->b);
 
ctx->b.initial_gfx_cs_size = ctx->b.rings.gfx.cs->cdw;
si_invalidate_draw_sh_constants(ctx);
ctx->last_primitive_restart_en = -1;
ctx->last_restart_index = SI_RESTART_INDEX_UNKNOWN;
ctx->last_gs_out_prim = -1;
ctx->last_prim = -1;
ctx->last_multi_vgt_param = -1;
ctx->last_rast_prim = -1;
ctx->last_sc_line_stipple = ~0;
ctx->emit_scratch_reloc = true;
}