summaryrefslogtreecommitdiff
path: root/src/uxa/intel_batchbuffer.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/uxa/intel_batchbuffer.h')
-rw-r--r--src/uxa/intel_batchbuffer.h226
1 files changed, 226 insertions, 0 deletions
diff --git a/src/uxa/intel_batchbuffer.h b/src/uxa/intel_batchbuffer.h
new file mode 100644
index 00000000..b2bb390c
--- /dev/null
+++ b/src/uxa/intel_batchbuffer.h
@@ -0,0 +1,226 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright © 2002 David Dawes
+
+All Rights Reserved.
+
+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 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 PRECISION INSIGHT AND/OR ITS 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.
+
+**************************************************************************/
+
+#ifndef _INTEL_BATCHBUFFER_H
+#define _INTEL_BATCHBUFFER_H
+
+#define BATCH_RESERVED 16
+
+
+void intel_batch_init(ScrnInfoPtr scrn);
+void intel_batch_teardown(ScrnInfoPtr scrn);
+void intel_batch_emit_flush(ScrnInfoPtr scrn);
+void intel_batch_submit(ScrnInfoPtr scrn);
+
+static inline int intel_batch_space(intel_screen_private *intel)
+{
+ return (intel->batch_bo->size - BATCH_RESERVED) - (4*intel->batch_used);
+}
+
+static inline int intel_vertex_space(intel_screen_private *intel)
+{
+ return intel->vertex_bo ? intel->vertex_bo->size - (4*intel->vertex_used) : 0;
+}
+
+static inline void
+intel_batch_require_space(ScrnInfoPtr scrn, intel_screen_private *intel, int sz)
+{
+ assert(sz < intel->batch_bo->size - 8);
+ if (intel_batch_space(intel) < sz)
+ intel_batch_submit(scrn);
+}
+
+static inline void intel_batch_start_atomic(ScrnInfoPtr scrn, int sz)
+{
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+
+ assert(!intel->in_batch_atomic);
+
+ if (intel->current_batch != RENDER_BATCH) {
+ if (intel->current_batch && intel->context_switch)
+ intel->context_switch(intel, RENDER_BATCH);
+ }
+
+ intel_batch_require_space(scrn, intel, sz * 4);
+ intel->current_batch = RENDER_BATCH;
+
+ intel->in_batch_atomic = TRUE;
+ intel->batch_atomic_limit = intel->batch_used + sz;
+}
+
+static inline void intel_batch_end_atomic(ScrnInfoPtr scrn)
+{
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+
+ assert(intel->in_batch_atomic);
+ assert(intel->batch_used <= intel->batch_atomic_limit);
+ intel->in_batch_atomic = FALSE;
+}
+
+static inline void intel_batch_emit_dword(intel_screen_private *intel, uint32_t dword)
+{
+ intel->batch_ptr[intel->batch_used++] = dword;
+}
+
+static inline void intel_batch_align(intel_screen_private *intel, uint32_t align)
+{
+ uint32_t delta;
+
+ align /= 4;
+ assert(align);
+
+ if ((delta = intel->batch_used & (align - 1))) {
+ delta = align - delta;
+ memset (intel->batch_ptr + intel->batch_used, 0, 4*delta);
+ intel->batch_used += delta;
+ }
+}
+
+static inline void
+intel_batch_emit_reloc(intel_screen_private *intel,
+ dri_bo * bo,
+ uint32_t read_domains,
+ uint32_t write_domains, uint32_t delta, int needs_fence)
+{
+ if (needs_fence)
+ drm_intel_bo_emit_reloc_fence(intel->batch_bo,
+ intel->batch_used * 4,
+ bo, delta,
+ read_domains, write_domains);
+ else
+ drm_intel_bo_emit_reloc(intel->batch_bo, intel->batch_used * 4,
+ bo, delta,
+ read_domains, write_domains);
+
+ intel_batch_emit_dword(intel, bo->offset + delta);
+}
+
+static inline void
+intel_batch_mark_pixmap_domains(intel_screen_private *intel,
+ struct intel_pixmap *priv,
+ uint32_t read_domains, uint32_t write_domain)
+{
+ assert (read_domains);
+ assert (write_domain == 0 || write_domain == read_domains);
+
+ if (list_is_empty(&priv->batch))
+ list_add(&priv->batch, &intel->batch_pixmaps);
+
+ priv->dirty |= write_domain != 0;
+ priv->busy = 1;
+
+ intel->needs_flush |= write_domain != 0;
+}
+
+static inline void
+intel_batch_emit_reloc_pixmap(intel_screen_private *intel, PixmapPtr pixmap,
+ uint32_t read_domains, uint32_t write_domain,
+ uint32_t delta, int needs_fence)
+{
+ struct intel_pixmap *priv = intel_get_pixmap_private(pixmap);
+
+ intel_batch_mark_pixmap_domains(intel, priv, read_domains, write_domain);
+
+ intel_batch_emit_reloc(intel, priv->bo,
+ read_domains, write_domain,
+ delta, needs_fence);
+}
+
+#define ALIGN_BATCH(align) intel_batch_align(intel, align);
+#define OUT_BATCH(dword) intel_batch_emit_dword(intel, dword)
+
+#define OUT_RELOC(bo, read_domains, write_domains, delta) \
+ intel_batch_emit_reloc(intel, bo, read_domains, write_domains, delta, 0)
+
+#define OUT_RELOC_FENCED(bo, read_domains, write_domains, delta) \
+ intel_batch_emit_reloc(intel, bo, read_domains, write_domains, delta, 1)
+
+#define OUT_RELOC_PIXMAP(pixmap, reads, write, delta) \
+ intel_batch_emit_reloc_pixmap(intel, pixmap, reads, write, delta, 0)
+
+#define OUT_RELOC_PIXMAP_FENCED(pixmap, reads, write, delta) \
+ intel_batch_emit_reloc_pixmap(intel, pixmap, reads, write, delta, 1)
+
+union intfloat {
+ float f;
+ unsigned int ui;
+};
+
+#define OUT_BATCH_F(x) do { \
+ union intfloat tmp; \
+ tmp.f = (float)(x); \
+ OUT_BATCH(tmp.ui); \
+} while(0)
+
+#define __BEGIN_BATCH(n,batch_idx) \
+do { \
+ if (intel->batch_emitting != 0) \
+ FatalError("%s: BEGIN_BATCH called without closing " \
+ "ADVANCE_BATCH\n", __FUNCTION__); \
+ assert(!intel->in_batch_atomic); \
+ if (intel->current_batch != batch_idx) { \
+ if (intel->current_batch && intel->context_switch) \
+ intel->context_switch(intel, batch_idx); \
+ } \
+ intel_batch_require_space(scrn, intel, (n) * 4); \
+ intel->current_batch = batch_idx; \
+ intel->batch_emitting = (n); \
+ intel->batch_emit_start = intel->batch_used; \
+} while (0)
+
+#define BEGIN_BATCH(n) __BEGIN_BATCH(n,RENDER_BATCH)
+#define BEGIN_BATCH_BLT(n) __BEGIN_BATCH(n,BLT_BATCH)
+
+#define ADVANCE_BATCH() do { \
+ if (intel->batch_emitting == 0) \
+ FatalError("%s: ADVANCE_BATCH called with no matching " \
+ "BEGIN_BATCH\n", __FUNCTION__); \
+ if (intel->batch_used > \
+ intel->batch_emit_start + intel->batch_emitting) \
+ FatalError("%s: ADVANCE_BATCH: exceeded allocation %d/%d\n ", \
+ __FUNCTION__, \
+ intel->batch_used - intel->batch_emit_start, \
+ intel->batch_emitting); \
+ if (intel->batch_used < intel->batch_emit_start + \
+ intel->batch_emitting) \
+ FatalError("%s: ADVANCE_BATCH: under-used allocation %d/%d\n ", \
+ __FUNCTION__, \
+ intel->batch_used - intel->batch_emit_start, \
+ intel->batch_emitting); \
+ intel->batch_emitting = 0; \
+} while (0)
+
+void intel_next_vertex(intel_screen_private *intel);
+static inline void intel_vertex_emit(intel_screen_private *intel, float v)
+{
+ intel->vertex_ptr[intel->vertex_used++] = v;
+}
+#define OUT_VERTEX(v) intel_vertex_emit(intel, v)
+
+#endif /* _INTEL_BATCHBUFFER_H */