summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2013-12-20 12:58:41 -0800
committerIan Romanick <[email protected]>2014-01-20 11:40:41 -0800
commit8468f437e880a0eeed94d79650ecb9b680fdeb02 (patch)
treefd6aeaaf021cdf6695a7c5fbf02d9522abc1502b
parent1ec663ab193e3dc87eb8729de4f0ecee7027961b (diff)
i915: Ensure that intel_bufferobj_map_range meets alignment guarantees
Not actually tested, but the changes are identical to the i965 changes that are tested. v2: Remove MAX2(64, ...). Suggested by Ken (in the i965 version of this patch). Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Eric Anholt <[email protected]> Cc: Siavash Eliasi <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i915/intel_buffer_objects.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/src/mesa/drivers/dri/i915/intel_buffer_objects.c b/src/mesa/drivers/dri/i915/intel_buffer_objects.c
index 1e794e15123..a470e1ac405 100644
--- a/src/mesa/drivers/dri/i915/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/i915/intel_buffer_objects.c
@@ -336,20 +336,28 @@ intel_bufferobj_map_range(struct gl_context * ctx,
*/
if ((access & GL_MAP_INVALIDATE_RANGE_BIT) &&
drm_intel_bo_busy(intel_obj->buffer)) {
+ /* Ensure that the base alignment of the allocation meets the alignment
+ * guarantees the driver has advertised to the application.
+ */
+ const unsigned alignment = ctx->Const.MinMapBufferAlignment;
+ const unsigned extra = (uintptr_t) offset % alignment;
+
if (access & GL_MAP_FLUSH_EXPLICIT_BIT) {
- intel_obj->range_map_buffer = malloc(length);
- obj->Pointer = intel_obj->range_map_buffer;
+ intel_obj->range_map_buffer = _mesa_align_malloc(length + extra,
+ alignment);
+ obj->Pointer = intel_obj->range_map_buffer + extra;
} else {
intel_obj->range_map_bo = drm_intel_bo_alloc(intel->bufmgr,
"range map",
- length, 64);
+ length + extra,
+ alignment);
if (!(access & GL_MAP_READ_BIT)) {
drm_intel_gem_bo_map_gtt(intel_obj->range_map_bo);
} else {
drm_intel_bo_map(intel_obj->range_map_bo,
(access & GL_MAP_WRITE_BIT) != 0);
}
- obj->Pointer = intel_obj->range_map_bo->virtual;
+ obj->Pointer = intel_obj->range_map_bo->virtual + extra;
}
return obj->Pointer;
}
@@ -391,7 +399,11 @@ intel_bufferobj_flush_mapped_range(struct gl_context *ctx,
temp_bo = drm_intel_bo_alloc(intel->bufmgr, "range map flush", length, 64);
- drm_intel_bo_subdata(temp_bo, 0, length, intel_obj->range_map_buffer);
+ /* Use obj->Pointer instead of intel_obj->range_map_buffer because the
+ * former points to the actual mapping while the latter may be offset to
+ * meet alignment guarantees.
+ */
+ drm_intel_bo_subdata(temp_bo, 0, length, obj->Pointer);
intel_emit_linear_blit(intel,
intel_obj->buffer, obj->Offset + offset,
@@ -422,14 +434,16 @@ intel_bufferobj_unmap(struct gl_context * ctx, struct gl_buffer_object *obj)
* usage inside of a batchbuffer.
*/
intel_batchbuffer_emit_mi_flush(intel);
- free(intel_obj->range_map_buffer);
+ _mesa_align_free(intel_obj->range_map_buffer);
intel_obj->range_map_buffer = NULL;
} else if (intel_obj->range_map_bo != NULL) {
+ const unsigned extra = obj->Pointer - intel_obj->range_map_bo->virtual;
+
drm_intel_bo_unmap(intel_obj->range_map_bo);
intel_emit_linear_blit(intel,
intel_obj->buffer, obj->Offset,
- intel_obj->range_map_bo, 0,
+ intel_obj->range_map_bo, extra,
obj->Length);
/* Since we've emitted some blits to buffers that will (likely) be used