summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/intel_buffer_objects.c
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2013-12-20 12:42:33 -0800
committerIan Romanick <ian.d.romanick@intel.com>2014-01-20 11:40:34 -0800
commit1ec663ab193e3dc87eb8729de4f0ecee7027961b (patch)
treecd50f4a85a4d5563e6f5360402d4f5c5e4a1f8f7 /src/mesa/drivers/dri/i965/intel_buffer_objects.c
parentc2352a88ed6595f1138de23a96f3152cf7a76778 (diff)
downloadexternal_mesa3d-1ec663ab193e3dc87eb8729de4f0ecee7027961b.zip
external_mesa3d-1ec663ab193e3dc87eb8729de4f0ecee7027961b.tar.gz
external_mesa3d-1ec663ab193e3dc87eb8729de4f0ecee7027961b.tar.bz2
i965: Ensure that intel_bufferobj_map_range meets alignment guarantees
No piglit regressions on IVB. With minor tweaks to the arb_map_buffer_alignment-map-invalidate-range test (disable the extension check, set alignment to 64 instead of querying), the i965 driver would fail the test without this patch (as predicted by Eric). With this patch, it passes. v2: Remove MAX2(64, ...). Suggested by Ken. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Eric Anholt <eric@anholt.net> Cc: Siavash Eliasi <siavashserver@gmail.com>
Diffstat (limited to 'src/mesa/drivers/dri/i965/intel_buffer_objects.c')
-rw-r--r--src/mesa/drivers/dri/i965/intel_buffer_objects.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.c b/src/mesa/drivers/dri/i965/intel_buffer_objects.c
index 30cd82c..4d7044a 100644
--- a/src/mesa/drivers/dri/i965/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.c
@@ -360,20 +360,28 @@ intel_bufferobj_map_range(struct gl_context * ctx,
if (!(access & GL_MAP_UNSYNCHRONIZED_BIT) &&
(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(brw->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;
}
@@ -425,7 +433,11 @@ intel_bufferobj_flush_mapped_range(struct gl_context *ctx,
temp_bo = drm_intel_bo_alloc(brw->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(brw,
intel_obj->buffer, obj->Offset + offset,
@@ -457,14 +469,16 @@ intel_bufferobj_unmap(struct gl_context * ctx, struct gl_buffer_object *obj)
* usage inside of a batchbuffer.
*/
intel_batchbuffer_emit_mi_flush(brw);
- 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(brw,
intel_obj->buffer, obj->Offset,
- intel_obj->range_map_bo, 0,
+ intel_obj->range_map_bo, extra,
obj->Length);
intel_bufferobj_mark_gpu_usage(intel_obj, obj->Offset, obj->Length);