static void intel_bufferobj_copy_subdata(struct gl_context *ctx, struct gl_buffer_object *src, struct gl_buffer_object *dst, GLintptr read_offset, GLintptr write_offset, GLsizeiptr size) { struct intel_context *intel = intel_context(ctx); struct intel_buffer_object *intel_src = intel_buffer_object(src); struct intel_buffer_object *intel_dst = intel_buffer_object(dst); drm_intel_bo *src_bo, *dst_bo; GLuint src_offset; if (size == 0) return; /* If we're in system memory, just map and memcpy. */ if (intel_src->sys_buffer || intel_dst->sys_buffer || intel->gen >= 6) { /* The same buffer may be used, but note that regions copied may * not overlap. */ if (src == dst) { char *ptr = intel_bufferobj_map_range(ctx, 0, dst->Size, GL_MAP_READ_BIT, dst); memmove(ptr + write_offset, ptr + read_offset, size); intel_bufferobj_unmap(ctx, dst); } else { const char *src_ptr; char *dst_ptr; src_ptr = intel_bufferobj_map_range(ctx, 0, src->Size, GL_MAP_READ_BIT, src); dst_ptr = intel_bufferobj_map_range(ctx, 0, dst->Size, GL_MAP_WRITE_BIT, dst); memcpy(dst_ptr + write_offset, src_ptr + read_offset, size); intel_bufferobj_unmap(ctx, src); intel_bufferobj_unmap(ctx, dst); } return; } /* Otherwise, we have real BOs, so blit them. */ dst_bo = intel_bufferobj_buffer(intel, intel_dst, INTEL_WRITE_PART); src_bo = intel_bufferobj_source(intel, intel_src, 64, &src_offset); intel_emit_linear_blit(intel, dst_bo, write_offset, src_bo, read_offset + src_offset, size); /* Since we've emitted some blits to buffers that will (likely) be used * in rendering operations in other cache domains in this batch, emit a * flush. Once again, we wish for a domain tracker in libdrm to cover * usage inside of a batchbuffer. */ intel_batchbuffer_emit_mi_flush(intel); }
/** * Deallocate/free a vertex/pixel buffer object. * Called via glDeleteBuffersARB(). */ static void intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj) { struct intel_context *intel = intel_context(ctx); struct intel_buffer_object *intel_obj = intel_buffer_object(obj); assert(intel_obj); /* Buffer objects are automatically unmapped when deleting according * to the spec, but Mesa doesn't do UnmapBuffer for us at context destroy * (though it does if you call glDeleteBuffers) */ if (obj->Pointer) intel_bufferobj_unmap(ctx, 0, obj); _mesa_free(intel_obj->sys_buffer); if (intel_obj->region) { intel_bufferobj_release_region(intel, intel_obj); } else if (intel_obj->buffer) { dri_bo_unreference(intel_obj->buffer); } _mesa_free(intel_obj); }
/** * The DeleteBuffer() driver hook. * * Deletes a single OpenGL buffer object. Used by glDeleteBuffers(). */ static void intel_bufferobj_free(struct gl_context * ctx, struct gl_buffer_object *obj) { struct intel_buffer_object *intel_obj = intel_buffer_object(obj); assert(intel_obj); /* Buffer objects are automatically unmapped when deleting according * to the spec, but Mesa doesn't do UnmapBuffer for us at context destroy * (though it does if you call glDeleteBuffers) */ if (obj->Pointer) intel_bufferobj_unmap(ctx, obj); drm_intel_bo_unreference(intel_obj->buffer); free(intel_obj); }