/* Break the COW tie to the pbo. Both the pbo and the region end up * with a copy of the data. */ void intel_region_cow(struct intel_context *intel, struct intel_region *region) { struct intel_buffer_object *pbo = region->pbo; GLboolean was_locked = intel->locked; if (intel == NULL) return; intel_region_release_pbo(intel, region); assert(region->cpp * region->pitch * region->height == pbo->Base.Size); DBG("%s (%d bytes)\n", __FUNCTION__, pbo->Base.Size); /* Now blit from the texture buffer to the new buffer: */ was_locked = intel->locked; if (!was_locked) LOCK_HARDWARE(intel); intelEmitCopyBlit(intel, region->cpp, region->pitch, region->buffer, 0, region->tiling, region->pitch, pbo->buffer, 0, region->tiling, 0, 0, 0, 0, region->pitch, region->height, GL_COPY); if (!was_locked) UNLOCK_HARDWARE(intel); }
/* Fill a rectangular sub-region. Need better logic about when to * push buffers into AGP - will currently do so whenever possible. */ void intel_region_fill(struct intel_context *intel, struct intel_region *dst, GLuint dst_offset, GLuint dstx, GLuint dsty, GLuint width, GLuint height, GLuint color) { DBG("%s\n", __FUNCTION__); if (intel == NULL) return; if (dst->pbo) { if (dstx == 0 && dsty == 0 && width == dst->pitch && height == dst->height) intel_region_release_pbo(intel, dst); else intel_region_cow(intel, dst); } intelEmitFillBlit(intel, dst->cpp, dst->pitch, dst->buffer, dst_offset, dst->tiling, dstx, dsty, width, height, color); }
/* Copy rectangular sub-regions. Need better logic about when to * push buffers into AGP - will currently do so whenever possible. */ void intel_region_copy(struct intel_context *intel, struct intel_region *dst, GLuint dst_offset, GLuint dstx, GLuint dsty, struct intel_region *src, GLuint src_offset, GLuint srcx, GLuint srcy, GLuint width, GLuint height) { DBG("%s\n", __FUNCTION__); if (intel == NULL) return; if (dst->pbo) { if (dstx == 0 && dsty == 0 && width == dst->pitch && height == dst->height) intel_region_release_pbo(intel, dst); else intel_region_cow(intel, dst); } assert(src->cpp == dst->cpp); intelEmitCopyBlit(intel, dst->cpp, src->pitch, src->buffer, src_offset, src->tiling, dst->pitch, dst->buffer, dst_offset, dst->tiling, srcx, srcy, dstx, dsty, width, height, GL_COPY); }
/* Break the COW tie to the pbo. Both the pbo and the region end up * with a copy of the data. */ void intel_region_cow(struct intel_context *intel, struct intel_region *region) { struct intel_buffer_object *pbo = region->pbo; GLboolean ok; intel_region_release_pbo(intel, region); assert(region->cpp * region->pitch * region->height == pbo->Base.Size); _DBG("%s %p (%d bytes)\n", __FUNCTION__, region, pbo->Base.Size); /* Now blit from the texture buffer to the new buffer: */ LOCK_HARDWARE(intel); ok = intelEmitCopyBlit(intel, region->cpp, region->pitch, pbo->buffer, 0, region->tiling, region->pitch, region->buffer, 0, region->tiling, 0, 0, 0, 0, region->pitch, region->height, GL_COPY); assert(ok); UNLOCK_HARDWARE(intel); }
/* Upload data to a rectangular sub-region. Lots of choices how to do this: * * - memcpy by span to current destination * - upload data as new buffer and blit * * Currently always memcpy. */ void intel_region_data(struct intel_context *intel, struct intel_region *dst, GLuint dst_offset, GLuint dstx, GLuint dsty, const void *src, GLuint src_pitch, GLuint srcx, GLuint srcy, GLuint width, GLuint height) { _DBG("%s\n", __FUNCTION__); if (intel == NULL) return; if (dst->pbo) { if (dstx == 0 && dsty == 0 && width == dst->pitch && height == dst->height) intel_region_release_pbo(intel, dst); else intel_region_cow(intel, dst); } LOCK_HARDWARE(intel); _mesa_copy_rect(intel_region_map(intel, dst) + dst_offset, dst->cpp, dst->pitch, dstx, dsty, width, height, src, src_pitch, srcx, srcy); intel_region_unmap(intel, dst); UNLOCK_HARDWARE(intel); }
dri_bo * intel_region_buffer(struct intel_context *intel, struct intel_region *region, GLuint flag) { if (region->pbo) { if (flag == INTEL_WRITE_PART) intel_region_cow(intel, region); else if (flag == INTEL_WRITE_FULL) intel_region_release_pbo(intel, region); } return region->buffer; }