/* XXX: Thread safety?
*/
-GLubyte *
-intel_region_map(struct intel_context *intel, struct intel_region *region)
+void *
+intel_region_map(struct intel_context *intel, struct intel_region *region,
+ GLbitfield mode)
{
/* We have the region->map_refcount controlling mapping of the BO because
* in software fallbacks we may end up mapping the same buffer multiple
* flush is only needed on first map of the buffer.
*/
+ if (unlikely(INTEL_DEBUG & DEBUG_PERF)) {
+ if (drm_intel_bo_busy(region->bo)) {
+ perf_debug("Mapping a busy BO, causing a stall on the GPU.\n");
+ }
+ }
+
_DBG("%s %p\n", __FUNCTION__, region);
- if (!region->map_refcount++) {
+ if (!region->map_refcount) {
intel_flush(&intel->ctx);
if (region->tiling != I915_TILING_NONE)
drm_intel_gem_bo_map_gtt(region->bo);
else
- drm_intel_bo_map(region->bo, GL_TRUE);
+ drm_intel_bo_map(region->bo, true);
region->map = region->bo->virtual;
- ++intel->num_mapped_regions;
+ }
+ if (region->map) {
+ intel->num_mapped_regions++;
+ region->map_refcount++;
}
return region->map;
intel_region_alloc(struct intel_screen *screen,
uint32_t tiling,
GLuint cpp, GLuint width, GLuint height,
- GLboolean expect_accelerated_upload)
+ bool expect_accelerated_upload)
{
drm_intel_bo *buffer;
unsigned long flags = 0;
return region;
}
-GLboolean
+bool
intel_region_flink(struct intel_region *region, uint32_t *name)
{
if (region->name == 0) {
if (drm_intel_bo_flink(region->bo, ®ion->name))
- return GL_FALSE;
+ return false;
_mesa_HashInsert(region->screen->named_regions,
region->name, region);
*name = region->name;
- return GL_TRUE;
+ return true;
}
struct intel_region *
/* Copy rectangular sub-regions. Need better logic about when to
* push buffers into AGP - will currently do so whenever possible.
*/
-GLboolean
+bool
intel_region_copy(struct intel_context *intel,
struct intel_region *dst,
GLuint dst_offset,
struct intel_region *src,
GLuint src_offset,
GLuint srcx, GLuint srcy, GLuint width, GLuint height,
- GLboolean flip,
+ bool flip,
GLenum logicop)
{
uint32_t src_pitch = src->pitch;
_DBG("%s\n", __FUNCTION__);
if (intel == NULL)
- return GL_FALSE;
+ return false;
assert(src->cpp == dst->cpp);
srcx, srcy, dstx, dsty, width, height,
logicop);
}
+
+/**
+ * This function computes masks that may be used to select the bits of the X
+ * and Y coordinates that indicate the offset within a tile. If the region is
+ * untiled, the masks are set to 0.
+ */
+void
+intel_region_get_tile_masks(struct intel_region *region,
+ uint32_t *mask_x, uint32_t *mask_y)
+{
+ int cpp = region->cpp;
+
+ switch (region->tiling) {
+ default:
+ assert(false);
+ case I915_TILING_NONE:
+ *mask_x = *mask_y = 0;
+ break;
+ case I915_TILING_X:
+ *mask_x = 512 / cpp - 1;
+ *mask_y = 7;
+ break;
+ case I915_TILING_Y:
+ *mask_x = 128 / cpp - 1;
+ *mask_y = 31;
+ break;
+ }
+}
+
+/**
+ * Compute the offset (in bytes) from the start of the region to the given x
+ * and y coordinate. For tiled regions, caller must ensure that x and y are
+ * multiples of the tile size.
+ */
+uint32_t
+intel_region_get_aligned_offset(struct intel_region *region, uint32_t x,
+ uint32_t y)
+{
+ int cpp = region->cpp;
+ uint32_t pitch = region->pitch * cpp;
+
+ switch (region->tiling) {
+ default:
+ assert(false);
+ case I915_TILING_NONE:
+ return y * pitch + x * cpp;
+ case I915_TILING_X:
+ assert((x % (512 / cpp)) == 0);
+ assert((y % 8) == 0);
+ return y * pitch + x / (512 / cpp) * 4096;
+ case I915_TILING_Y:
+ assert((x % (128 / cpp)) == 0);
+ assert((y % 32) == 0);
+ return y * pitch + x / (128 / cpp) * 4096;
+ }
+}