dri_bo * intel_bufferobj_buffer(struct intel_context *intel, struct intel_buffer_object *intel_obj, GLuint flag) { if (intel_obj->region) { if (flag == INTEL_WRITE_PART) intel_bufferobj_cow(intel, intel_obj); else if (flag == INTEL_WRITE_FULL) { intel_bufferobj_release_region(intel, intel_obj); intel_bufferobj_alloc_buffer(intel, intel_obj); } } if (intel_obj->buffer == NULL) { void *sys_buffer = intel_obj->sys_buffer; /* only one of buffer and sys_buffer could be non-NULL */ intel_bufferobj_alloc_buffer(intel, intel_obj); intel_obj->sys_buffer = NULL; intel_bufferobj_subdata(&intel->ctx, GL_ARRAY_BUFFER_ARB, 0, intel_obj->Base.Size, sys_buffer, &intel_obj->Base); _mesa_free(sys_buffer); intel_obj->sys_buffer = NULL; } return intel_obj->buffer; }
drm_intel_bo * intel_bufferobj_buffer(struct intel_context *intel, struct intel_buffer_object *intel_obj, GLuint flag) { if (intel_obj->region) { if (flag == INTEL_WRITE_PART) intel_bufferobj_cow(intel, intel_obj); else if (flag == INTEL_WRITE_FULL) { intel_bufferobj_release_region(intel, intel_obj); intel_bufferobj_alloc_buffer(intel, intel_obj); } } if (intel_obj->source) release_buffer(intel_obj); if (intel_obj->buffer == NULL) { intel_bufferobj_alloc_buffer(intel, intel_obj); drm_intel_bo_subdata(intel_obj->buffer, 0, intel_obj->Base.Size, intel_obj->sys_buffer); free(intel_obj->sys_buffer); intel_obj->sys_buffer = NULL; intel_obj->offset = 0; } return intel_obj->buffer; }
/** * 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); }
/** * Allocate space for and store data in a buffer object. Any data that was * previously stored in the buffer object is lost. If data is NULL, * memory will be allocated, but no copy will occur. * Called via ctx->Driver.BufferData(). * \return GL_TRUE for success, GL_FALSE if out of memory */ static GLboolean intel_bufferobj_data(struct gl_context * ctx, GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage, struct gl_buffer_object *obj) { struct intel_context *intel = intel_context(ctx); struct intel_buffer_object *intel_obj = intel_buffer_object(obj); intel_obj->Base.Size = size; intel_obj->Base.Usage = usage; assert(!obj->Pointer); /* Mesa should have unmapped it */ if (intel_obj->region) intel_bufferobj_release_region(intel, intel_obj); if (intel_obj->buffer != NULL) release_buffer(intel_obj); free(intel_obj->sys_buffer); intel_obj->sys_buffer = NULL; if (size != 0) { if (usage == GL_DYNAMIC_DRAW #ifdef I915 /* On pre-965, stick VBOs in system memory, as we're always doing * swtnl with their contents anyway. */ || target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER #endif ) { intel_obj->sys_buffer = malloc(size); if (intel_obj->sys_buffer != NULL) { if (data != NULL) memcpy(intel_obj->sys_buffer, data, size); return GL_TRUE; } } intel_bufferobj_alloc_buffer(intel, intel_obj); if (!intel_obj->buffer) return GL_FALSE; if (data != NULL) drm_intel_bo_subdata(intel_obj->buffer, 0, size, data); } return GL_TRUE; }