#include <sys/ioctl.h>
#include <errno.h>
+#include "main/hash.h"
#include "intel_context.h"
#include "intel_regions.h"
#include "intel_blit.h"
#include "intel_buffer_objects.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_chipset.h"
#define FILE_DEBUG_FLAG DEBUG_REGION
if (region->pbo)
intel_region_cow(intel, region);
- if (region->tiling != I915_TILING_NONE &&
- intel->intelScreen->kernel_exec_fencing)
+ if (region->tiling != I915_TILING_NONE)
drm_intel_gem_bo_map_gtt(region->buffer);
else
dri_bo_map(region->buffer, GL_TRUE);
{
_DBG("%s %p\n", __FUNCTION__, region);
if (!--region->map_refcount) {
- if (region->tiling != I915_TILING_NONE &&
- intel->intelScreen->kernel_exec_fencing)
+ if (region->tiling != I915_TILING_NONE)
drm_intel_gem_bo_unmap_gtt(region->buffer);
else
dri_bo_unmap(region->buffer);
/* Default to no tiling */
region->tiling = I915_TILING_NONE;
- region->bit_6_swizzle = I915_BIT_6_SWIZZLE_NONE;
_DBG("%s <-- %p\n", __FUNCTION__, region);
return region;
struct intel_region *
intel_region_alloc(struct intel_context *intel,
uint32_t tiling,
- GLuint cpp, GLuint width, GLuint height, GLuint pitch,
+ GLuint cpp, GLuint width, GLuint height,
GLboolean expect_accelerated_upload)
{
dri_bo *buffer;
struct intel_region *region;
+ unsigned long flags = 0;
+ unsigned long aligned_pitch;
- /* If we're tiled, our allocations are in 8 or 32-row blocks, so
- * failure to align our height means that we won't allocate enough pages.
- *
- * If we're untiled, we still have to align to 2 rows high because the
- * data port accesses 2x2 blocks even if the bottom row isn't to be
- * rendered, so failure to align means we could walk off the end of the
- * GTT and fault.
- */
- if (tiling == I915_TILING_X)
- height = ALIGN(height, 8);
- else if (tiling == I915_TILING_Y)
- height = ALIGN(height, 32);
- else
- height = ALIGN(height, 2);
-
- /* If we're untiled, we have to align to 2 rows high because the
- * data port accesses 2x2 blocks even if the bottom row isn't to be
- * rendered, so failure to align means we could walk off the end of the
- * GTT and fault.
- */
- height = ALIGN(height, 2);
-
- if (expect_accelerated_upload) {
- buffer = drm_intel_bo_alloc_for_render(intel->bufmgr, "region",
- pitch * cpp * height, 64);
- } else {
- buffer = drm_intel_bo_alloc(intel->bufmgr, "region",
- pitch * cpp * height, 64);
- }
+ if (expect_accelerated_upload)
+ flags |= BO_ALLOC_FOR_RENDER;
- region = intel_region_alloc_internal(intel, cpp, width, height,
- pitch, buffer);
+ buffer = drm_intel_bo_alloc_tiled(intel->bufmgr, "region",
+ width, height, cpp,
+ &tiling, &aligned_pitch, flags);
- if (tiling != I915_TILING_NONE) {
- assert(((pitch * cpp) & 127) == 0);
- drm_intel_bo_set_tiling(buffer, &tiling, pitch * cpp);
- drm_intel_bo_get_tiling(buffer, ®ion->tiling, ®ion->bit_6_swizzle);
- }
+ region = intel_region_alloc_internal(intel, cpp, width, height,
+ aligned_pitch / cpp, buffer);
+ region->tiling = tiling;
return region;
}
GLuint width, GLuint height, GLuint pitch,
GLuint handle, const char *name)
{
- struct intel_region *region;
+ struct intel_region *region, *dummy;
dri_bo *buffer;
int ret;
+ uint32_t bit_6_swizzle;
+
+ region = _mesa_HashLookup(intel->intelScreen->named_regions, handle);
+ if (region != NULL) {
+ dummy = NULL;
+ if (region->width != width || region->height != height ||
+ region->cpp != cpp || region->pitch != pitch) {
+ fprintf(stderr,
+ "Region for name %d already exists but is not compatible\n",
+ handle);
+ return NULL;
+ }
+ intel_region_reference(&dummy, region);
+ return dummy;
+ }
buffer = intel_bo_gem_create_from_name(intel->bufmgr, name, handle);
return region;
ret = dri_bo_get_tiling(region->buffer, ®ion->tiling,
- ®ion->bit_6_swizzle);
+ &bit_6_swizzle);
if (ret != 0) {
fprintf(stderr, "Couldn't get tiling of buffer %d (%s): %s\n",
handle, name, strerror(-ret));
return NULL;
}
+ region->name = handle;
+ region->screen = intel->intelScreen;
+ _mesa_HashInsert(intel->intelScreen->named_regions, handle, region);
+
return region;
}
region->pbo = NULL;
dri_bo_unreference(region->buffer);
- if (region->classic_map != NULL) {
- drmUnmap(region->classic_map,
- region->pitch * region->cpp * region->height);
- }
+ if (region->name > 0)
+ _mesa_HashRemove(region->screen->named_regions, region->name);
free(region);
}
dst += dst_x * cpp;
src += src_x * cpp;
dst += dst_y * dst_pitch;
- src += src_y * dst_pitch;
+ src += src_y * src_pitch;
width *= cpp;
if (width == dst_pitch && width == src_pitch)
intel_region_cow(intel, dst);
}
+ intel_prepare_render(intel);
+
_mesa_copy_rect(intel_region_map(intel, dst) + dst_offset,
dst->cpp,
dst->pitch,
struct intel_region *src,
GLuint src_offset,
GLuint srcx, GLuint srcy, GLuint width, GLuint height,
+ GLboolean flip,
GLenum logicop)
{
+ uint32_t src_pitch = src->pitch;
+
_DBG("%s\n", __FUNCTION__);
if (intel == NULL)
assert(src->cpp == dst->cpp);
+ if (flip)
+ src_pitch = -src_pitch;
+
return intelEmitCopyBlit(intel,
dst->cpp,
- src->pitch, src->buffer, src_offset, src->tiling,
+ src_pitch, src->buffer, src_offset, src->tiling,
dst->pitch, dst->buffer, dst_offset, dst->tiling,
srcx, srcy, dstx, dsty, width, height,
logicop);
region->pbo->region = region;
dri_bo_reference(buffer);
region->buffer = buffer;
+ region->tiling = I915_TILING_NONE;
}
/* Now blit from the texture buffer to the new buffer:
*/
+ intel_prepare_render(intel);
ok = intelEmitCopyBlit(intel,
region->cpp,
region->pitch, pbo->buffer, 0, region->tiling,