All pastes #1916342 Raw Edit

Unnamed

public text v1 · immutable
#1916342 ·published 2010-08-13 11:33 UTC
rendered paste body
diff --git a/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c b/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c
index 0897daf..4bdf36d 100644
--- a/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c
+++ b/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c
@@ -199,6 +199,115 @@ radeonMapBuffer(GLcontext * ctx,
     return obj->Pointer;
 }
 
+/**
+ * Called via glMapBufferRange().
+ *
+ * The goal of this extension is to allow apps to accumulate their rendering
+ * at the same time as they accumulate their buffer object. Without it,
+ * you'd end up blocking on execution of rendering every time you mapped
+ * the buffer to put new data in.
+ *
+ * We support it in 3 ways: If unsynchronized, then don't bother
+ * flushing the batchbuffer before mapping the buffer, which can save blocking
+ * in many cases. If we would still block, and they allow the whole buffer
+ * to be invalidated, then just allocate a new buffer to replace the old one.
+ * If not, and we'd block, and they allow the subrange of the buffer to be
+ * invalidated, then we can make a new little BO, let them write into that,
+ * and blit it into the real BO at unmap time.
+ */
+static void *
+radeon_bufferobj_map_range(GLcontext * ctx,
+ GLenum target, GLsizei offset, GLsizeiptr length,
+ GLbitfield access, struct gl_buffer_object *obj)
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
+
+ assert(radeon_obj);
+
+ if (radeon_obj->sys_buffer) {
+ obj->Pointer = radeon_obj->sys_buffer + offset;
+ return obj->Pointer;
+ }
+
+ if (radeon_obj->region)
+ radeon_bufferobj_cow(radeon, radeon_obj); // implement this?
+
+ /* If the mapping is synchronized with other GL operations, flush
+ * the batchbuffer so that GEM knows about the buffer access for later
+ * syncing.
+ */
+ if ((access & GL_MAP_WRITE_BIT) && !(access & GL_MAP_UNSYNCHRONIZED_BIT))
+ RadeonFlush(ctx);
+
+ /* _mesa_MapBufferRange (GL entrypoint) sets these, but the vbo module also
+ * internally uses our functions directly.
+ */
+ obj->Offset = offset;
+ obj->Length = length;
+ obj->AccessFlags = access;
+
+ if (radeon_buffer == NULL) {
+ obj->Pointer = NULL;
+ return NULL;
+ }
+
+ /* If the user doesn't care about existing buffer contents and mapping
+ * would cause us to block, then throw out the old buffer.
+ */
+ if (!(access & GL_MAP_UNSYNCHRONIZED_BIT) &&
+ (access & GL_MAP_INVALIDATE_BUFFER_BIT) &&
+ drm_radeon_bo_busy(radeon_obj->buffer)) {
+ drm_radeon_bo_unreference(radeon_obj->buffer);
+ radeon_obj->buffer = dri_bo_alloc(radeon->bufmgr, "bufferobj",
+ radeon_obj->Base.Size, 64);
+ }
+ 
+ /* sigh . Radeon uses different bufmanager */
+
+ /* If the user is mapping a range of an active buffer object but
+ * doesn't require the current contents of that range, make a new
+ * BO, and we'll copy what they put in there out at unmap or
+ * FlushRange time.
+ */
+ 
+ /* How to check busy-ness  for radeons ? */
+ if ((access & GL_MAP_INVALIDATE_RANGE_BIT) &&
+ drm_radeon_bo_busy(radeon_obj->buffer)) {
+ radeon_obj->range_map_bo = drm_radeon_bo_alloc(radeon->bufmgr,
+ "range map",
+ length, 64);
+ if (!(access & GL_MAP_READ_BIT) &&
+ radeon->RadeonScreen->kernel_exec_fencing) {
+ drm_radeon_gem_bo_map_gtt(radeon_obj->range_map_bo);
+ radeon_obj->mapped_gtt = GL_TRUE;
+ } else {
+ drm_radeon_bo_map(radeon_obj->range_map_bo,
+ (access & GL_MAP_WRITE_BIT) != 0);
+ radeon_obj->mapped_gtt = GL_FALSE;
+ }
+ obj->Pointer = radeon_obj->range_map_bo->virtual;
+ return obj->Pointer;
+ }
+
+/* Guess Radeon has its own fencing, 
+ what is equvalent of this kernel_exec_fencing ? */
+ 
+ /* Also, does radeon track mapped_to_gtt status for it's BOs ? */
+ if (!(access & GL_MAP_READ_BIT) &&
+ radeon->RadeonScreen->kernel_exec_fencing) {
+ drm_radeon_gem_bo_map_gtt(radeon_obj->buffer);
+ radeon_obj->mapped_gtt = GL_TRUE;
+ } else {
+ drm_radeon_bo_map(radeon_obj->buffer, (access & GL_MAP_WRITE_BIT) != 0);
+ radeon_obj->mapped_gtt = GL_FALSE;
+ }
+
+ obj->Pointer = radeon_obj->buffer->virtual + offset;
+ return obj->Pointer;
+}
+
+
 
 /**
  * Called via glUnmapBufferARB()