summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-08-27 16:53:50 -0700
committerEric Anholt <eric@anholt.net>2009-08-27 17:51:29 -0700
commit60b072d49fd2a1b2bf59442ae7209379152b1500 (patch)
treef7e99174dcbdb283d57c15223aa4aed971033128
parent812ccacabcc6af300cf476d7f82ecb75d4982cd6 (diff)
intel: Add support for ARB_copy_buffer.
Passes glean's bufferObject test for this extension.
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffer_objects.c93
-rw-r--r--src/mesa/drivers/dri/intel/intel_extensions.c2
2 files changed, 93 insertions, 2 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
index 9600557f2cc..a7403979439 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
@@ -28,9 +28,11 @@
28 28
29#include "main/imports.h" 29#include "main/imports.h"
30#include "main/mtypes.h" 30#include "main/mtypes.h"
31#include "main/macros.h"
31#include "main/bufferobj.h" 32#include "main/bufferobj.h"
32 33
33#include "intel_context.h" 34#include "intel_context.h"
35#include "intel_blit.h"
34#include "intel_buffer_objects.h" 36#include "intel_buffer_objects.h"
35#include "intel_batchbuffer.h" 37#include "intel_batchbuffer.h"
36#include "intel_regions.h" 38#include "intel_regions.h"
@@ -243,8 +245,10 @@ intel_bufferobj_map(GLcontext * ctx,
243 return obj->Pointer; 245 return obj->Pointer;
244 } 246 }
245 247
246 if (!read_only) 248 /* Flush any existing batchbuffer that might have written to this
247 intelFlush(ctx); 249 * buffer.
250 */
251 intelFlush(ctx);
248 252
249 if (intel_obj->region) 253 if (intel_obj->region)
250 intel_bufferobj_cow(intel, intel_obj); 254 intel_bufferobj_cow(intel, intel_obj);
@@ -325,6 +329,90 @@ intel_bufferobj_buffer(struct intel_context *intel,
325 return intel_obj->buffer; 329 return intel_obj->buffer;
326} 330}
327 331
332static void
333intel_bufferobj_copy_subdata(GLcontext *ctx,
334 struct gl_buffer_object *src,
335 struct gl_buffer_object *dst,
336 GLintptr read_offset, GLintptr write_offset,
337 GLsizeiptr size)
338{
339 struct intel_context *intel = intel_context(ctx);
340 struct intel_buffer_object *intel_src = intel_buffer_object(src);
341 struct intel_buffer_object *intel_dst = intel_buffer_object(dst);
342 drm_intel_bo *src_bo, *dst_bo;
343 GLuint pitch, height;
344
345 if (size == 0)
346 return;
347
348 /* If we're in system memory, just map and memcpy. */
349 if (intel_src->sys_buffer || intel_dst->sys_buffer) {
350 /* The same buffer may be used, but note that regions copied may
351 * not overlap.
352 */
353 if (src == dst) {
354 char *ptr = intel_bufferobj_map(ctx, GL_COPY_WRITE_BUFFER,
355 GL_READ_WRITE, dst);
356 memcpy(ptr + write_offset, ptr + read_offset, size);
357 intel_bufferobj_unmap(ctx, GL_COPY_WRITE_BUFFER, dst);
358 } else {
359 const char *src_ptr;
360 char *dst_ptr;
361
362 src_ptr = intel_bufferobj_map(ctx, GL_COPY_READ_BUFFER,
363 GL_READ_ONLY, src);
364 dst_ptr = intel_bufferobj_map(ctx, GL_COPY_WRITE_BUFFER,
365 GL_WRITE_ONLY, dst);
366
367 memcpy(dst_ptr + write_offset, src_ptr + read_offset, size);
368
369 intel_bufferobj_unmap(ctx, GL_COPY_READ_BUFFER, src);
370 intel_bufferobj_unmap(ctx, GL_COPY_WRITE_BUFFER, dst);
371 }
372 }
373
374 /* Otherwise, we have real BOs, so blit them. We don't have a memmove-type
375 * blit like some other hardware, so we'll do a rectangular blit covering
376 * a large space, then emit a scanline blit at the end to cover the last
377 * if we need.
378 */
379
380 dst_bo = intel_bufferobj_buffer(intel, intel_dst, INTEL_WRITE_PART);
381 src_bo = intel_bufferobj_buffer(intel, intel_src, INTEL_READ);
382
383 /* The pitch is a signed value. */
384 pitch = MIN2(size, (1 << 15) - 1);
385 height = size / pitch;
386 intelEmitCopyBlit(intel, 1,
387 pitch, src_bo, read_offset, I915_TILING_NONE,
388 pitch, dst_bo, write_offset, I915_TILING_NONE,
389 0, 0, /* src x/y */
390 0, 0, /* dst x/y */
391 pitch, height, /* w, h */
392 GL_COPY);
393
394 read_offset += pitch * height;
395 write_offset += pitch * height;
396 size -= pitch * height;
397 assert (size < (1 << 15));
398 if (size != 0) {
399 intelEmitCopyBlit(intel, 1,
400 size, src_bo, read_offset, I915_TILING_NONE,
401 size, dst_bo, write_offset, I915_TILING_NONE,
402 0, 0, /* src x/y */
403 0, 0, /* dst x/y */
404 size, 1, /* w, h */
405 GL_COPY);
406 }
407
408 /* Since we've emitted some blits to buffers that will (likely) be used
409 * in rendering operations in other cache domains in this batch, emit a
410 * flush. Once again, we wish for a domain tracker in libdrm to cover
411 * usage inside of a batchbuffer.
412 */
413 intel_batchbuffer_emit_mi_flush(intel->batch);
414}
415
328void 416void
329intelInitBufferObjectFuncs(struct dd_function_table *functions) 417intelInitBufferObjectFuncs(struct dd_function_table *functions)
330{ 418{
@@ -335,4 +423,5 @@ intelInitBufferObjectFuncs(struct dd_function_table *functions)
335 functions->GetBufferSubData = intel_bufferobj_get_subdata; 423 functions->GetBufferSubData = intel_bufferobj_get_subdata;
336 functions->MapBuffer = intel_bufferobj_map; 424 functions->MapBuffer = intel_bufferobj_map;
337 functions->UnmapBuffer = intel_bufferobj_unmap; 425 functions->UnmapBuffer = intel_bufferobj_unmap;
426 functions->CopyBufferSubData = intel_bufferobj_copy_subdata;
338} 427}
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
index 9f90ef0a697..ff9ad5acced 100644
--- a/src/mesa/drivers/dri/intel/intel_extensions.c
+++ b/src/mesa/drivers/dri/intel/intel_extensions.c
@@ -30,6 +30,7 @@
30#include "intel_extensions.h" 30#include "intel_extensions.h"
31 31
32 32
33#define need_GL_ARB_copy_buffer
33#define need_GL_ARB_framebuffer_object 34#define need_GL_ARB_framebuffer_object
34#define need_GL_ARB_occlusion_query 35#define need_GL_ARB_occlusion_query
35#define need_GL_ARB_point_parameters 36#define need_GL_ARB_point_parameters
@@ -69,6 +70,7 @@
69 * i965_dri. 70 * i965_dri.
70 */ 71 */
71static const struct dri_extension card_extensions[] = { 72static const struct dri_extension card_extensions[] = {
73 { "GL_ARB_copy_buffer", GL_ARB_copy_buffer_functions },
72 { "GL_ARB_half_float_pixel", NULL }, 74 { "GL_ARB_half_float_pixel", NULL },
73 { "GL_ARB_multitexture", NULL }, 75 { "GL_ARB_multitexture", NULL },
74 { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions }, 76 { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions },