*
**************************************************************************/
+#include "glapi/glapi.h"
+#include "main/texformat.h"
#include "i830_context.h"
#include "i830_reg.h"
#include "intel_batchbuffer.h"
#include "intel_regions.h"
+#include "intel_tris.h"
+#include "intel_fbo.h"
#include "tnl/t_context.h"
#include "tnl/t_vertex.h"
{
BATCH_LOCALS;
- BEGIN_BATCH(40, 0);
+ BEGIN_BATCH(30, IGNORE_CLIPRECTS);
OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
OUT_BATCH(0);
#define emit( intel, state, size ) \
-do { \
- int k; \
- BEGIN_BATCH(size / sizeof(GLuint), 0); \
- for (k = 0 ; k < size / sizeof(GLuint) ; k++) { \
- if (0) _mesa_printf(" 0x%08x\n", state[k]); \
- OUT_BATCH(state[k]); \
- } \
- ADVANCE_BATCH(); \
-} while (0)
+ intel_batchbuffer_data(intel->batch, state, size, IGNORE_CLIPRECTS )
static GLuint
get_dirty(struct i830_hw_state *state)
/* Push the state into the sarea and/or texture memory.
*/
static void
-i830_do_emit_state(struct intel_context *intel)
+i830_emit_state(struct intel_context *intel)
{
struct i830_context *i830 = i830_context(&intel->ctx);
struct i830_hw_state *state = i830->current;
- int i;
+ int i, count;
GLuint dirty;
+ dri_bo *aper_array[3 + I830_TEX_UNITS];
+ int aper_count;
+ GET_CURRENT_CONTEXT(ctx);
BATCH_LOCALS;
/* We don't hold the lock at this point, so want to make sure that
- * there won't be a buffer wrap.
+ * there won't be a buffer wrap between the state emits and the primitive
+ * emit header.
*
* It might be better to talk about explicit places where
* scheduling is allowed, rather than assume that it is whenever a
* batchbuffer fills up.
- */
- intel_batchbuffer_require_space(intel->batch, get_state_size(state), 0);
-
- /* Workaround. There are cases I haven't been able to track down
- * where we aren't emitting a full state at the start of a new
- * batchbuffer. This code spots that we are on a new batchbuffer
- * and forces a full state emit no matter what.
*
- * In the normal case state->emitted is already zero, this code is
- * another set of checks to make sure it really is.
+ * Set the space as LOOP_CLIPRECTS now, since that's what our primitives
+ * will be emitted under.
*/
- if (intel->batch->id != intel->last_state_batch_id ||
- intel->batch->map == intel->batch->ptr)
- {
- state->emitted = 0;
- intel_batchbuffer_require_space(intel->batch, get_state_size(state), 0);
+ intel_batchbuffer_require_space(intel->batch,
+ get_state_size(state) + INTEL_PRIM_EMIT_SIZE,
+ LOOP_CLIPRECTS);
+ count = 0;
+ again:
+ aper_count = 0;
+ dirty = get_dirty(state);
+
+ aper_array[aper_count++] = intel->batch->buf;
+ if (dirty & I830_UPLOAD_BUFFERS) {
+ aper_array[aper_count++] = state->draw_region->buffer;
+ if (state->depth_region)
+ aper_array[aper_count++] = state->depth_region->buffer;
+ }
+
+ for (i = 0; i < I830_TEX_UNITS; i++)
+ if (dirty & I830_UPLOAD_TEX(i)) {
+ if (state->tex_buffer[i]) {
+ aper_array[aper_count++] = state->tex_buffer[i];
+ }
+ }
+
+ if (dri_bufmgr_check_aperture_space(aper_array, aper_count)) {
+ if (count == 0) {
+ count++;
+ intel_batchbuffer_flush(intel->batch);
+ goto again;
+ } else {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "i830 emit state");
+ assert(0);
+ }
}
+
/* Do this here as we may have flushed the batchbuffer above,
* causing more state to be dirty!
*/
state->emitted |= dirty;
assert(get_dirty(state) == 0);
- if (intel->batch->id != intel->last_state_batch_id) {
- assert(dirty & I830_UPLOAD_CTX);
- intel->last_state_batch_id = intel->batch->id;
- }
-
if (dirty & I830_UPLOAD_INVARIENT) {
DBG("I830_UPLOAD_INVARIENT:\n");
i830_emit_invarient_state(intel);
if (dirty & I830_UPLOAD_CTX) {
DBG("I830_UPLOAD_CTX:\n");
- emit(i830, state->Ctx, sizeof(state->Ctx));
+ emit(intel, state->Ctx, sizeof(state->Ctx));
}
if (dirty & I830_UPLOAD_BUFFERS) {
+ GLuint count = 9;
+
DBG("I830_UPLOAD_BUFFERS:\n");
- BEGIN_BATCH(I830_DEST_SETUP_SIZE + 2, 0);
+
+ if (state->depth_region)
+ count += 3;
+
+ if (intel->constant_cliprect)
+ count += 6;
+
+ BEGIN_BATCH(count, IGNORE_CLIPRECTS);
OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR0]);
OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR1]);
OUT_RELOC(state->draw_region->buffer,
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
state->draw_region->draw_offset);
if (state->depth_region) {
OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR0]);
OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR1]);
OUT_RELOC(state->depth_region->buffer,
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
state->depth_region->draw_offset);
}
OUT_BATCH(state->Buffer[I830_DESTREG_SR0]);
OUT_BATCH(state->Buffer[I830_DESTREG_SR1]);
OUT_BATCH(state->Buffer[I830_DESTREG_SR2]);
+
+ if (intel->constant_cliprect) {
+ assert(state->Buffer[I830_DESTREG_DRAWRECT0] != MI_NOOP);
+ OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT0]);
+ OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT1]);
+ OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT2]);
+ OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT3]);
+ OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT4]);
+ OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT5]);
+ }
ADVANCE_BATCH();
}
if (dirty & I830_UPLOAD_STIPPLE) {
DBG("I830_UPLOAD_STIPPLE:\n");
- emit(i830, state->Stipple, sizeof(state->Stipple));
+ emit(intel, state->Stipple, sizeof(state->Stipple));
}
for (i = 0; i < I830_TEX_UNITS; i++) {
if ((dirty & I830_UPLOAD_TEX(i))) {
DBG("I830_UPLOAD_TEX(%d):\n", i);
- BEGIN_BATCH(I830_TEX_SETUP_SIZE + 1, 0);
+ BEGIN_BATCH(I830_TEX_SETUP_SIZE + 1, IGNORE_CLIPRECTS);
OUT_BATCH(state->Tex[i][I830_TEXREG_TM0LI]);
if (state->tex_buffer[i]) {
OUT_RELOC(state->tex_buffer[i],
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
+ I915_GEM_DOMAIN_SAMPLER, 0,
state->tex_offset[i] | TM0S0_USE_FENCE);
}
else if (state == &i830->meta) {
OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S4]);
OUT_BATCH(state->Tex[i][I830_TEXREG_MCS]);
OUT_BATCH(state->Tex[i][I830_TEXREG_CUBE]);
+
+ ADVANCE_BATCH();
}
if (dirty & I830_UPLOAD_TEXBLEND(i)) {
DBG("I830_UPLOAD_TEXBLEND(%d): %d words\n", i,
state->TexBlendWordsUsed[i]);
- emit(i830, state->TexBlend[i], state->TexBlendWordsUsed[i] * 4);
+ emit(intel, state->TexBlend[i], state->TexBlendWordsUsed[i] * 4);
}
}
intel->batch->dirty_state &= ~dirty;
assert(get_dirty(state) == 0);
-}
-
-static void
-i830_emit_state(struct intel_context *intel)
-{
- struct i830_context *i830 = i830_context(&intel->ctx);
-
- i830_do_emit_state( intel );
-
- /* Second chance - catch batchbuffer wrap in the middle of state
- * emit. This shouldn't happen but it has been observed in
- * testing.
- */
- if (get_dirty( i830->current )) {
- /* Force a full re-emit if this happens.
- */
- i830->current->emitted = 0;
- i830_do_emit_state( intel );
- }
-
- assert(get_dirty(i830->current) == 0);
assert((intel->batch->dirty_state & (1<<1)) == 0);
}
GLuint i;
struct i830_context *i830 = i830_context(&intel->ctx);
+ intel_region_release(&i830->state.draw_region);
+ intel_region_release(&i830->state.depth_region);
+ intel_region_release(&i830->meta.draw_region);
+ intel_region_release(&i830->meta.depth_region);
+ intel_region_release(&i830->initial.draw_region);
+ intel_region_release(&i830->initial.depth_region);
+
for (i = 0; i < I830_TEX_UNITS; i++) {
if (i830->state.tex_buffer[i] != NULL) {
dri_bo_unreference(i830->state.tex_buffer[i]);
struct intel_region *depth_region)
{
struct i830_context *i830 = i830_context(&intel->ctx);
+ GLcontext *ctx = &intel->ctx;
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
+ struct intel_renderbuffer *irb = intel_renderbuffer(rb);
GLuint value;
ASSERT(state == &i830->state || state == &i830->meta);
*/
value = (DSTORG_HORT_BIAS(0x8) | /* .5 */
DSTORG_VERT_BIAS(0x8) | DEPTH_IS_Z); /* .5 */
-
- if (color_region && color_region->cpp == 4) {
- value |= DV_PF_8888;
- }
- else {
- value |= DV_PF_565;
+
+ if (irb != NULL) {
+ switch (irb->texformat->MesaFormat) {
+ case MESA_FORMAT_ARGB8888:
+ value |= DV_PF_8888;
+ break;
+ case MESA_FORMAT_RGB565:
+ value |= DV_PF_565;
+ break;
+ case MESA_FORMAT_ARGB1555:
+ value |= DV_PF_1555;
+ break;
+ case MESA_FORMAT_ARGB4444:
+ value |= DV_PF_4444;
+ break;
+ default:
+ _mesa_problem(ctx, "Bad renderbuffer format: %d\n",
+ irb->texformat->MesaFormat);
+ }
}
+
if (depth_region && depth_region->cpp == 4) {
value |= DEPTH_FRMT_24_FIXED_8_OTHER;
}
}
state->Buffer[I830_DESTREG_DV1] = value;
+ if (intel->constant_cliprect) {
+ state->Buffer[I830_DESTREG_DRAWRECT0] = _3DSTATE_DRAWRECT_INFO;
+ state->Buffer[I830_DESTREG_DRAWRECT1] = 0;
+ state->Buffer[I830_DESTREG_DRAWRECT2] = 0; /* xmin, ymin */
+ state->Buffer[I830_DESTREG_DRAWRECT3] =
+ (ctx->DrawBuffer->Width & 0xffff) |
+ (ctx->DrawBuffer->Height << 16);
+ state->Buffer[I830_DESTREG_DRAWRECT4] = 0; /* xoff, yoff */
+ state->Buffer[I830_DESTREG_DRAWRECT5] = 0;
+ } else {
+ state->Buffer[I830_DESTREG_DRAWRECT0] = MI_NOOP;
+ state->Buffer[I830_DESTREG_DRAWRECT1] = MI_NOOP;
+ state->Buffer[I830_DESTREG_DRAWRECT2] = MI_NOOP;
+ state->Buffer[I830_DESTREG_DRAWRECT3] = MI_NOOP;
+ state->Buffer[I830_DESTREG_DRAWRECT4] = MI_NOOP;
+ state->Buffer[I830_DESTREG_DRAWRECT5] = MI_NOOP;
+ }
+
I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS);
static void
i830_set_draw_region(struct intel_context *intel,
- struct intel_region *color_region,
- struct intel_region *depth_region)
+ struct intel_region *color_regions[],
+ struct intel_region *depth_region,
+ GLuint num_regions)
{
struct i830_context *i830 = i830_context(&intel->ctx);
- i830_state_draw_region(intel, &i830->state, color_region, depth_region);
+ i830_state_draw_region(intel, &i830->state, color_regions[0], depth_region);
}
#if 0
{
struct i830_context *i830 = i830_context(&intel->ctx);
i830->state.emitted = 0;
+
+ /* Check that we didn't just wrap our batchbuffer at a bad time. */
+ assert(!intel->no_batch_wrap);
}
assert(!get_dirty(state));
}
+static void
+i830_note_unlock( struct intel_context *intel )
+{
+ /* nothing */
+}
void
i830InitVtbl(struct i830_context *i830)
i830->intel.vtbl.render_start = i830_render_start;
i830->intel.vtbl.render_prevalidate = i830_render_prevalidate;
i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty;
+ i830->intel.vtbl.note_unlock = i830_note_unlock;
+ i830->intel.vtbl.finish_batch = intel_finish_vb;
}