Exemplo n.º 1
0
static void
radeon_unmap_texture_image(struct gl_context *ctx,
                           struct gl_texture_image *texImage, GLuint slice)
{
    radeon_texture_image *image = get_radeon_texture_image(texImage);

    if (image->bo)
        radeon_bo_unmap(image->bo);
    else if (image->mt)
        radeon_bo_unmap(image->mt->bo);
}
Exemplo n.º 2
0
compute_shader::compute_shader(r800_state* state, std::string fname)
{
  FILE *f = fopen(fname.c_str(), "r");

  assert(f);

  fseek(f, 0, SEEK_END);
  long size = ftell(f);
  fseek(f, 0, SEEK_SET);

  char* buf = new char[size];
  fread(buf, 1, size, f);

  fclose(f);

  lds_alloc = 0;
  num_gprs = 10;
  temp_gprs = 0;
  global_gprs = 0;
  stack_size = 16;
  thread_num = 4; //TODO: how to configure it?
  dyn_gpr_limit = 0;

  alloc_size = size;

  binary_code_bo = state->bo_open(0, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);

  assert(binary_code_bo != NULL);

  assert(radeon_bo_map(binary_code_bo, 1) == 0);

  memcpy(binary_code_bo->ptr, buf, size);

  radeon_bo_unmap(binary_code_bo);
}
Exemplo n.º 3
0
static cairo_surface_t *
radeon_surface_map_to_image (radeon_surface_t *surface)
{
    if (surface->base.fallback == NULL) {
	cairo_surface_t *image;
	cairo_status_t status;
	void *ptr;

	if (surface->base.base.backend->flush != NULL) {
	    status = surface->base.base.backend->flush (surface);
	    if (unlikely (status))
		return _cairo_surface_create_in_error (status);
	}

	ptr = radeon_bo_map (to_radeon_device (surface->base.base.device),
			    to_radeon_bo (surface->base.bo));
	if (unlikely (ptr == NULL))
	    return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);

	image = cairo_image_surface_create_for_data (ptr,
						     surface->base.format,
						     surface->base.width,
						     surface->base.height,
						     surface->base.stride);
	if (unlikely (image->status)) {
	    radeon_bo_unmap (to_radeon_bo (surface->base.bo));
	    return image;
	}

	surface->base.fallback = image;
    }

    return surface->base.fallback;
}
Exemplo n.º 4
0
static void r700SendQueryBegin(GLcontext *ctx, struct radeon_state_atom *atom)
{
	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
	struct radeon_query_object *query = radeon->query.current;
	BATCH_LOCALS(radeon);
	radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);

	/* clear the buffer */
	radeon_bo_map(query->bo, GL_FALSE);
	memset(query->bo->ptr, 0, 4 * 2 * sizeof(uint64_t)); /* 4 DBs, 2 qwords each */
	radeon_bo_unmap(query->bo);

	radeon_cs_space_check_with_bo(radeon->cmdbuf.cs,
				      query->bo,
				      0, RADEON_GEM_DOMAIN_GTT);

	BEGIN_BATCH_NO_AUTOSTATE(4 + 2);
	R600_OUT_BATCH(CP_PACKET3(R600_IT_EVENT_WRITE, 2));
	R600_OUT_BATCH(ZPASS_DONE);
	R600_OUT_BATCH(query->curr_offset); /* hw writes qwords */
	R600_OUT_BATCH(0x00000000);
	R600_OUT_BATCH_RELOC(VGT_EVENT_INITIATOR, query->bo, 0, 0, RADEON_GEM_DOMAIN_GTT, 0);
	END_BATCH();
	query->emitted_begin = GL_TRUE;
}
Exemplo n.º 5
0
void r200FlushElts(struct gl_context *ctx)
{
   r200ContextPtr rmesa = R200_CONTEXT(ctx);
   int nr, elt_used = rmesa->tcl.elt_used;

   radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %x %d\n", __FUNCTION__, rmesa->tcl.hw_primitive, elt_used);

   assert( rmesa->radeon.dma.flush == r200FlushElts );
   rmesa->radeon.dma.flush = NULL;

   nr = elt_used / 2;

   radeon_bo_unmap(rmesa->radeon.tcl.elt_dma_bo);

   r200FireEB(rmesa, nr, rmesa->tcl.hw_primitive);

   radeon_bo_unref(rmesa->radeon.tcl.elt_dma_bo);
   rmesa->radeon.tcl.elt_dma_bo = NULL;

   if (R200_ELT_BUF_SZ > elt_used)
     radeonReturnDmaRegion(&rmesa->radeon, R200_ELT_BUF_SZ - elt_used);

   if (radeon_is_debug_enabled(RADEON_SYNC, RADEON_CRITICAL)
         && !rmesa->radeon.radeonScreen->kernel_mm) {
      radeon_print(RADEON_SYNC, RADEON_NORMAL, "%s: Syncing\n", __FUNCTION__);
      radeonFinish( rmesa->radeon.glCtx );
   }
}
Exemplo n.º 6
0
/**
 * Ensure that the given image is stored in the given miptree from now on.
 */
static void migrate_image_to_miptree(radeon_mipmap_tree *mt,
									 radeon_texture_image *image,
									 int face, int level)
{
	radeon_mipmap_level *dstlvl = &mt->levels[level];
	unsigned char *dest;

	assert(image->mt != mt);
	assert(dstlvl->valid);
	assert(dstlvl->width == image->base.Base.Width);
	assert(dstlvl->height == image->base.Base.Height);
	assert(dstlvl->depth == image->base.Base.Depth);

	radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
			"%s miptree %p, image %p, face %d, level %d.\n",
			__func__, mt, image, face, level);

	radeon_bo_map(mt->bo, GL_TRUE);
	dest = mt->bo->ptr + dstlvl->faces[face].offset;

	if (image->mt) {
		/* Format etc. should match, so we really just need a memcpy().
		 * In fact, that memcpy() could be done by the hardware in many
		 * cases, provided that we have a proper memory manager.
		 */
		assert(mt->mesaFormat == image->base.Base.TexFormat);

		radeon_mipmap_level *srclvl = &image->mt->levels[image->base.Base.Level];

		assert(image->base.Base.Level == level);
		assert(srclvl->size == dstlvl->size);
		assert(srclvl->rowstride == dstlvl->rowstride);

		radeon_bo_map(image->mt->bo, GL_FALSE);

		memcpy(dest,
			image->mt->bo->ptr + srclvl->faces[face].offset,
			dstlvl->size);
		radeon_bo_unmap(image->mt->bo);

		radeon_miptree_unreference(&image->mt);
	}

	radeon_bo_unmap(mt->bo);

	radeon_miptree_reference(mt, &image->mt);
}
Exemplo n.º 7
0
static void unmap_override(GLcontext *ctx, radeonTexObj *t)
{
	radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);

	radeon_bo_unmap(t->bo);

	img->base.Data = NULL;
}
Exemplo n.º 8
0
static void
radeon_swrast_unmap_image(radeonContextPtr rmesa,
                          radeon_texture_image *image)
{
    if (image && image->mt) {
        image->base.Map = NULL;
        radeon_bo_unmap(image->mt->bo);
    }
}
Exemplo n.º 9
0
struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle,
			unsigned size, unsigned alignment, void *ptr)
{
	struct radeon_bo *bo;
	int r;

	bo = calloc(1, sizeof(*bo));
	if (bo == NULL) {
		return NULL;
	}
	bo->size = size;
	bo->handle = handle;
	bo->refcount = 1;
	bo->alignment = alignment;

	if (handle) {
		struct drm_gem_open open_arg;

		memset(&open_arg, 0, sizeof(open_arg));
		open_arg.name = handle;
		r = drmIoctl(radeon->fd, DRM_IOCTL_GEM_OPEN, &open_arg);
		if (r != 0) {
			free(bo);
			return NULL;
		}
		bo->handle = open_arg.handle;
		bo->size = open_arg.size;
	} else {
		struct drm_radeon_gem_create args;

		args.size = size;
		args.alignment = alignment;
		args.initial_domain = RADEON_GEM_DOMAIN_CPU;
		args.flags = 0;
		args.handle = 0;
		r = drmCommandWriteRead(radeon->fd, DRM_RADEON_GEM_CREATE,
					&args, sizeof(args));
		bo->handle = args.handle;
		if (r) {
			fprintf(stderr, "Failed to allocate :\n");
			fprintf(stderr, "   size      : %d bytes\n", size);
			fprintf(stderr, "   alignment : %d bytes\n", alignment);
			free(bo);
			return NULL;
		}
	}
	if (ptr) {
		if (radeon_bo_map(radeon, bo)) {
			fprintf(stderr, "%s failed to copy data into bo\n", __func__);
			return radeon_bo_decref(radeon, bo);
		}
		memcpy(bo->data, ptr, size);
		radeon_bo_unmap(radeon, bo);
	}
	return bo;
}
Exemplo n.º 10
0
void radeon_teximage_unmap(radeon_texture_image *image)
{
    radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
                 "%s(img %p)\n",
                 __func__, image);
    if (image->mt) {
        assert(image->base.Map);

        image->base.Map = 0;
        radeon_bo_unmap(image->mt->bo);
    }
}
Exemplo n.º 11
0
static void evergreenSetupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
{
    context_t *context = EVERGREEN_CONTEXT(ctx);

    if (!mesa_ind_buf) {
        context->ind_buf.bo = NULL;
        return;
    }

#if MESA_BIG_ENDIAN
    if (mesa_ind_buf->type == GL_UNSIGNED_INT)
#else
    if (mesa_ind_buf->type != GL_UNSIGNED_BYTE)
#endif
    {
        const GLvoid *src_ptr;
        GLvoid *dst_ptr;
        GLboolean mapped_named_bo = GL_FALSE;

        if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer)
        {
	        ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, mesa_ind_buf->obj);
	        assert(mesa_ind_buf->obj->Pointer != NULL);
	        mapped_named_bo = GL_TRUE;
        }

        src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr);

        const GLuint size = mesa_ind_buf->count * getTypeSize(mesa_ind_buf->type);

	radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo,
			     &context->ind_buf.bo_offset, size, 4);
	radeon_bo_map(context->ind_buf.bo, 1);
	assert(context->ind_buf.bo->ptr != NULL);
	dst_ptr = ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);

        memcpy(dst_ptr, src_ptr, size);

	radeon_bo_unmap(context->ind_buf.bo);
        context->ind_buf.is_32bit = (mesa_ind_buf->type == GL_UNSIGNED_INT);
        context->ind_buf.count = mesa_ind_buf->count;

        if (mapped_named_bo)
        {
	        ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj);
        }
    }
    else
    {
	    evergreenFixupIndexBuffer(ctx, mesa_ind_buf);
    }
}
Exemplo n.º 12
0
/**
 * Called via glGetBufferSubDataARB()
 */
static void
radeonGetBufferSubData(struct gl_context * ctx,
                       GLintptrARB offset,
                       GLsizeiptrARB size,
                       GLvoid * data,
                       struct gl_buffer_object *obj)
{
    struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);

    radeon_bo_map(radeon_obj->bo, GL_FALSE);

    memcpy(data, radeon_obj->bo->ptr + offset, size);

    radeon_bo_unmap(radeon_obj->bo);
}
Exemplo n.º 13
0
/**
 * Called via glDeleteBuffersARB().
 */
static void
radeonDeleteBufferObject(struct gl_context * ctx,
                         struct gl_buffer_object *obj)
{
    struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);

    if (obj->Pointer) {
        radeon_bo_unmap(radeon_obj->bo);
    }

    if (radeon_obj->bo) {
        radeon_bo_unref(radeon_obj->bo);
    }

    free(radeon_obj);
}
Exemplo n.º 14
0
/**
 * Called via glUnmapBufferARB()
 */
static GLboolean
radeonUnmapBuffer(struct gl_context * ctx,
                  struct gl_buffer_object *obj)
{
    struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);

    if (radeon_obj->bo != NULL) {
        radeon_bo_unmap(radeon_obj->bo);
    }

    obj->Pointer = NULL;
    obj->Offset = 0;
    obj->Length = 0;

    return GL_TRUE;
}
static Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap)
{
	if (pixmap->refcnt == 1) {
		if (pixmap->devPrivate.ptr) {
			struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap);

			if (bo)
				radeon_bo_unmap(bo);
		}

		glamor_egl_destroy_textured_pixmap(pixmap);
		radeon_set_pixmap_bo(pixmap, NULL);
	}
	fbDestroyPixmap(pixmap);
	return TRUE;
}
Exemplo n.º 16
0
static void radeonQueryGetResult(struct gl_context *ctx, struct gl_query_object *q)
{
	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
	struct radeon_query_object *query = (struct radeon_query_object *)q;
        uint32_t *result;
	int i;

	radeon_print(RADEON_STATE, RADEON_VERBOSE,
			"%s: query id %d, result %d\n",
			__FUNCTION__, query->Base.Id, (int) query->Base.Result);

	radeon_bo_map(query->bo, GL_FALSE);
        result = query->bo->ptr;

	query->Base.Result = 0;
	if (IS_R600_CLASS(radeon->radeonScreen)) {
		/* ZPASS EVENT writes alternating qwords
		 * At query start we set the start offset to 0 and
		 * hw writes zpass start counts to qwords 0, 2, 4, 6.
		 * At query end we set the start offset to 8 and
		 * hw writes zpass end counts to qwords 1, 3, 5, 7.
		 * then we substract. MSB is the valid bit.
		 */
		for (i = 0; i < 32; i += 4) {
			uint64_t start = (uint64_t)LE32_TO_CPU(result[i]) |
					 (uint64_t)LE32_TO_CPU(result[i + 1]) << 32;
			uint64_t end = (uint64_t)LE32_TO_CPU(result[i + 2]) |
				       (uint64_t)LE32_TO_CPU(result[i + 3]) << 32;
			if ((start & 0x8000000000000000) && (end & 0x8000000000000000)) {
				uint64_t query_count = end - start;
				query->Base.Result += query_count;

			}
			radeon_print(RADEON_STATE, RADEON_TRACE,
				     "%d start: %" PRIu64 ", end: %" PRIu64 " %" PRIu64 "\n", i, start, end, end - start);
		}
	} else {
		for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) {
			query->Base.Result += LE32_TO_CPU(result[i]);
			radeon_print(RADEON_STATE, RADEON_TRACE, "result[%d] = %d\n", i, LE32_TO_CPU(result[i]));
		}
	}

	radeon_bo_unmap(query->bo);
}
Exemplo n.º 17
0
compute_shader::compute_shader(r800_state* state, const std::vector<char>& binary)
{
  const cs_image_header* header = (const cs_image_header*)&binary[0];

  assert(binary.size()%4 == 0);
  assert(header->magic == 0x42424242);

  uint32_t sum = 0;

  for (int i = 8; i < binary.size(); i++)
  {
    sum = sum + binary[i];
  }

  assert(header->chksum == sum);

  lds_alloc = header->lds_alloc;
  num_gprs = header->num_gprs;
  temp_gprs = header->temp_gprs;
  global_gprs = header->global_gprs;
  stack_size = header->stack_size;
  thread_num = header->thread_num;
  dyn_gpr_limit = header->dyn_gpr_limit;

  int shader_start = sizeof(cs_image_header);

  alloc_size = binary.size() - shader_start;

  if (alloc_size % 16)
  {
    alloc_size += (16 - alloc_size % 16);
  }

  binary_code_bo = state->bo_open(0, alloc_size, 0, RADEON_GEM_DOMAIN_VRAM, 0);

  assert(binary_code_bo != NULL);

  assert(radeon_bo_map(binary_code_bo, 1) == 0);

  memcpy(binary_code_bo->ptr, &binary[0] + shader_start, binary.size() - shader_start);

  radeon_bo_unmap(binary_code_bo);
}
Exemplo n.º 18
0
/**
 * Replace data in a subrange of buffer object.  If the data range
 * specified by size + offset extends beyond the end of the buffer or
 * if data is NULL, no copy is performed.
 * Called via glBufferSubDataARB().
 */
static void
radeonBufferSubData(struct gl_context * ctx,
                    GLintptrARB offset,
                    GLsizeiptrARB size,
                    const GLvoid * data,
                    struct gl_buffer_object *obj)
{
    radeonContextPtr radeon = RADEON_CONTEXT(ctx);
    struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);

    if (radeon_bo_is_referenced_by_cs(radeon_obj->bo, radeon->cmdbuf.cs)) {
        radeon_firevertices(radeon);
    }

    radeon_bo_map(radeon_obj->bo, GL_TRUE);

    memcpy(radeon_obj->bo->ptr + offset, data, size);

    radeon_bo_unmap(radeon_obj->bo);
}
Exemplo n.º 19
0
void r600_texture_transfer_unmap(struct pipe_context *ctx,
				 struct pipe_transfer* transfer)
{
	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
	struct r600_screen *rscreen = r600_screen(ctx->screen);
	struct r600_resource_texture *rtex;
	struct radeon_bo *bo;

	if (rtransfer->linear_texture) {
		bo = ((struct r600_resource *)rtransfer->linear_texture)->bo;
	} else {
		rtex = (struct r600_resource_texture*)transfer->resource;
		if (rtex->depth) {
			bo = rtex->uncompressed;
		} else {
			bo = ((struct r600_resource *)transfer->resource)->bo;
		}
	}
	radeon_bo_unmap(rscreen->rw, bo);
}
Exemplo n.º 20
0
static void evergreenAlignDataToDword(GLcontext *ctx, 
                                 const struct gl_client_array *input, 
                                 int count, 
                                 struct StreamDesc *attr)
{
    context_t *context = EVERGREEN_CONTEXT(ctx);
    const int dst_stride = (input->StrideB + 3) & ~3;
    const int size = getTypeSize(input->Type) * input->Size * count;
    GLboolean mapped_named_bo = GL_FALSE;

    radeonAllocDmaRegion(&context->radeon, &attr->bo, &attr->bo_offset, size, 32);

    radeon_bo_map(attr->bo, 1);

    if (!input->BufferObj->Pointer) 
    {
        ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj);
        mapped_named_bo = GL_TRUE;
    }

    {
        GLvoid *src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr);
        GLvoid *dst_ptr = ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
        int i;

        for (i = 0; i < count; ++i) 
        {
            memcpy(dst_ptr, src_ptr, input->StrideB);
            src_ptr += input->StrideB;
            dst_ptr += dst_stride;
        }
    }

    radeon_bo_unmap(attr->bo);
    if (mapped_named_bo) 
    {
        ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
    }

    attr->stride = dst_stride;
}
Exemplo n.º 21
0
void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
{
	radeonTexObj* t = radeon_tex_obj(texObj);
	int face, level;

	radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
			"%s(%p, tex %p)\n",
			__func__, ctx, texObj);

	if (t->image_override && t->bo)
		unmap_override(ctx, t);
	/* for r100 3D sw fallbacks don't have mt */
	if (!t->mt)
	  return;

	for(face = 0; face < t->mt->faces; ++face) {
		for(level = t->minLod; level <= t->maxLod; ++level)
			texObj->Image[face][level]->Data = 0;
	}
	radeon_bo_unmap(t->mt->bo);
}
Exemplo n.º 22
0
static void radeonQueryGetResult(struct gl_context *ctx, struct gl_query_object *q)
{
	struct radeon_query_object *query = (struct radeon_query_object *)q;
        uint32_t *result;
	int i;

	radeon_print(RADEON_STATE, RADEON_VERBOSE,
			"%s: query id %d, result %d\n",
			__FUNCTION__, query->Base.Id, (int) query->Base.Result);

	radeon_bo_map(query->bo, GL_FALSE);
        result = query->bo->ptr;

	query->Base.Result = 0;
	for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) {
		query->Base.Result += LE32_TO_CPU(result[i]);
		radeon_print(RADEON_STATE, RADEON_TRACE, "result[%d] = %d\n", i, LE32_TO_CPU(result[i]));
	}

	radeon_bo_unmap(query->bo);
}
Exemplo n.º 23
0
/**
 * 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
radeonBufferData(struct gl_context * ctx,
                 GLenum target,
                 GLsizeiptrARB size,
                 const GLvoid * data,
                 GLenum usage,
                 struct gl_buffer_object *obj)
{
    radeonContextPtr radeon = RADEON_CONTEXT(ctx);
    struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);

    radeon_obj->Base.Size = size;
    radeon_obj->Base.Usage = usage;

    if (radeon_obj->bo != NULL) {
        radeon_bo_unref(radeon_obj->bo);
        radeon_obj->bo = NULL;
    }

    if (size != 0) {
        radeon_obj->bo = radeon_bo_open(radeon->radeonScreen->bom,
                                        0,
                                        size,
                                        32,
                                        RADEON_GEM_DOMAIN_GTT,
                                        0);

        if (!radeon_obj->bo)
            return GL_FALSE;

        if (data != NULL) {
            radeon_bo_map(radeon_obj->bo, GL_TRUE);

            memcpy(radeon_obj->bo->ptr, data, size);

            radeon_bo_unmap(radeon_obj->bo);
        }
    }
    return GL_TRUE;
}
Exemplo n.º 24
0
void r200FlushElts(struct gl_context *ctx)
{
   r200ContextPtr rmesa = R200_CONTEXT(ctx);
   int nr, elt_used = rmesa->tcl.elt_used;

   radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %x %d\n", __FUNCTION__, rmesa->tcl.hw_primitive, elt_used);

   assert( rmesa->radeon.dma.flush == r200FlushElts );
   rmesa->radeon.dma.flush = NULL;

   nr = elt_used / 2;

   radeon_bo_unmap(rmesa->radeon.tcl.elt_dma_bo);

   r200FireEB(rmesa, nr, rmesa->tcl.hw_primitive);

   radeon_bo_unref(rmesa->radeon.tcl.elt_dma_bo);
   rmesa->radeon.tcl.elt_dma_bo = NULL;

   if (R200_ELT_BUF_SZ > elt_used)
     radeonReturnDmaRegion(&rmesa->radeon, R200_ELT_BUF_SZ - elt_used);
}
Exemplo n.º 25
0
static void r300AlignDataToDword(GLcontext *ctx, const struct gl_client_array *input, int count, struct vertex_attribute *attr)
{
	r300ContextPtr r300 = R300_CONTEXT(ctx);
	const int dst_stride = (input->StrideB + 3) & ~3;
	const int size = getTypeSize(input->Type) * input->Size * count;
	GLboolean mapped_named_bo = GL_FALSE;

	radeonAllocDmaRegion(&r300->radeon, &attr->bo, &attr->bo_offset, size, 32);

	radeon_bo_map(attr->bo, 1);

	if (!input->BufferObj->Pointer) {
		ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj);
		mapped_named_bo = GL_TRUE;
	}

	radeon_print(RADEON_FALLBACKS, RADEON_IMPORTANT, "%s. Vertex alignment doesn't match hw requirements.\n", __func__);

	{
		GLvoid *src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr);
		GLvoid *dst_ptr = ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
		int i;

		for (i = 0; i < count; ++i) {
			memcpy(dst_ptr, src_ptr, input->StrideB);
			src_ptr += input->StrideB;
			dst_ptr += dst_stride;
		}
	}

	if (mapped_named_bo) {
		ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
	}

	radeon_bo_unmap(attr->bo);
	attr->stride = dst_stride;
}
Exemplo n.º 26
0
static cairo_status_t
radeon_surface_flush (void *abstract_surface,
		      unsigned flags)
{
    radeon_surface_t *surface = abstract_surface;
    cairo_status_t status;

    if (flags)
	return CAIRO_STATUS_SUCCESS;

    if (surface->base.fallback == NULL)
	return CAIRO_STATUS_SUCCESS;

    /* kill any outstanding maps */
    cairo_surface_finish (surface->base.fallback);

    status = cairo_surface_status (surface->base.fallback);
    cairo_surface_destroy (surface->base.fallback);
    surface->base.fallback = NULL;

    radeon_bo_unmap (to_radeon_bo (surface->base.bo));

    return status;
}
Exemplo n.º 27
0
static void cs_gem_dump_bof(struct radeon_cs_int *cs)
{
    struct cs_gem *csg = (struct cs_gem*)cs;
    struct radeon_cs_manager_gem *csm;
    bof_t *bcs, *blob, *array, *bo, *size, *handle, *device_id, *root;
    char tmp[256];
    unsigned i;

    csm = (struct radeon_cs_manager_gem *)cs->csm;
    root = device_id = bcs = blob = array = bo = size = handle = NULL;
    root = bof_object();
    if (root == NULL)
        goto out_err;
    device_id = bof_int32(csm->device_id);
    if (device_id == NULL)
        return;
    if (bof_object_set(root, "device_id", device_id))
        goto out_err;
    bof_decref(device_id);
    device_id = NULL;
    /* dump relocs */
    blob = bof_blob(csg->nrelocs * 16, csg->relocs);
    if (blob == NULL)
        goto out_err;
    if (bof_object_set(root, "reloc", blob))
        goto out_err;
    bof_decref(blob);
    blob = NULL;
    /* dump cs */
    blob = bof_blob(cs->cdw * 4, cs->packets);
    if (blob == NULL)
        goto out_err;
    if (bof_object_set(root, "pm4", blob))
        goto out_err;
    bof_decref(blob);
    blob = NULL;
    /* dump bo */
    array = bof_array();
    if (array == NULL)
        goto out_err;
    for (i = 0; i < csg->base.crelocs; i++) {
        bo = bof_object();
        if (bo == NULL)
            goto out_err;
        size = bof_int32(csg->relocs_bo[i]->size);
        if (size == NULL)
            goto out_err;
        if (bof_object_set(bo, "size", size))
            goto out_err;
        bof_decref(size);
        size = NULL;
        handle = bof_int32(csg->relocs_bo[i]->handle);
        if (handle == NULL)
            goto out_err;
        if (bof_object_set(bo, "handle", handle))
            goto out_err;
        bof_decref(handle);
        handle = NULL;
        radeon_bo_map((struct radeon_bo*)csg->relocs_bo[i], 0);
        blob = bof_blob(csg->relocs_bo[i]->size, csg->relocs_bo[i]->ptr);
        radeon_bo_unmap((struct radeon_bo*)csg->relocs_bo[i]);
        if (blob == NULL)
            goto out_err;
        if (bof_object_set(bo, "data", blob))
            goto out_err;
        bof_decref(blob);
        blob = NULL;
        if (bof_array_append(array, bo))
            goto out_err;
        bof_decref(bo);
        bo = NULL;
    }
    if (bof_object_set(root, "bo", array))
        goto out_err;
    sprintf(tmp, "d-0x%04X-%08d.bof", csm->device_id, csm->nbof++);
    bof_dump_file(root, tmp);
out_err:
    bof_decref(blob);
    bof_decref(array);
    bof_decref(bo);
    bof_decref(size);
    bof_decref(handle);
    bof_decref(device_id);
    bof_decref(root);
}
Exemplo n.º 28
0
static GLboolean
do_blit_readpixels(struct gl_context * ctx,
                   GLint x, GLint y, GLsizei width, GLsizei height,
                   GLenum format, GLenum type,
                   const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
{
    radeonContextPtr radeon = RADEON_CONTEXT(ctx);
    const struct radeon_renderbuffer *rrb = radeon_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
    const gl_format dst_format = gl_format_and_type_to_mesa_format(format, type);
    unsigned dst_rowstride, dst_imagesize, aligned_rowstride, flip_y;
    struct radeon_bo *dst_buffer;
    GLint dst_x = 0, dst_y = 0;
    intptr_t dst_offset;

    /* It's not worth if number of pixels to copy is really small */
    if (width * height < 100) {
        return GL_FALSE;
    }

    if (dst_format == MESA_FORMAT_NONE ||
        !radeon->vtbl.check_blit(dst_format) || !radeon->vtbl.blit) {
        return GL_FALSE;
    }

    if (ctx->_ImageTransferState || ctx->Color._LogicOpEnabled) {
        return GL_FALSE;
    }

    if (pack->SwapBytes || pack->LsbFirst) {
        return GL_FALSE;
    }

    if (pack->RowLength > 0) {
        dst_rowstride = pack->RowLength;
    } else {
        dst_rowstride = width;
    }

    if (!_mesa_clip_copytexsubimage(ctx, &dst_x, &dst_y, &x, &y, &width, &height)) {
        return GL_TRUE;
    }
    assert(x >= 0 && y >= 0);

    aligned_rowstride = get_texture_image_row_stride(radeon, dst_format, dst_rowstride, 0);
    dst_rowstride *= _mesa_get_format_bytes(dst_format);
    if (_mesa_is_bufferobj(pack->BufferObj) && aligned_rowstride != dst_rowstride)
        return GL_FALSE;
    dst_imagesize = get_texture_image_size(dst_format,
                                           aligned_rowstride,
                                           height, 1, 0);

    if (!_mesa_is_bufferobj(pack->BufferObj))
    {
        dst_buffer = radeon_bo_open(radeon->radeonScreen->bom, 0, dst_imagesize, 1024, RADEON_GEM_DOMAIN_GTT, 0);
        dst_offset = 0;
    }
    else
    {
        dst_buffer = get_radeon_buffer_object(pack->BufferObj)->bo;
        dst_offset = (intptr_t)pixels;
    }

    /* Disable source Y flipping for FBOs */
    flip_y = (ctx->ReadBuffer->Name == 0);
    if (pack->Invert) {
        y = rrb->base.Height - height - y;
        flip_y = !flip_y;
    }

    if (radeon->vtbl.blit(ctx,
                          rrb->bo,
                          rrb->draw_offset,
                          rrb->base.Format,
                          rrb->pitch / rrb->cpp,
                          rrb->base.Width,
                          rrb->base.Height,
                          x,
                          y,
                          dst_buffer,
                          dst_offset,
                          dst_format,
                          aligned_rowstride / _mesa_get_format_bytes(dst_format),
                          width,
                          height,
                          0, /* dst_x */
                          0, /* dst_y */
                          width,
                          height,
                          flip_y))
    {
        if (!_mesa_is_bufferobj(pack->BufferObj))
        {
            radeon_bo_map(dst_buffer, 0);
            copy_rows(pixels, dst_rowstride, dst_buffer->ptr,
                      aligned_rowstride, height, dst_rowstride);
            radeon_bo_unmap(dst_buffer);
            radeon_bo_unref(dst_buffer);
        }

        return GL_TRUE;
    }

    if (!_mesa_is_bufferobj(pack->BufferObj))
        radeon_bo_unref(dst_buffer);

    return GL_FALSE;
}
static Bool
RADEONUploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h,
		       char *src, int src_pitch)
{
    ScreenPtr pScreen = pDst->drawable.pScreen;
    RINFO_FROM_SCREEN(pScreen);
    struct radeon_exa_pixmap_priv *driver_priv;
    struct radeon_bo *scratch = NULL;
    struct radeon_bo *copy_dst;
    unsigned char *dst;
    unsigned size;
    uint32_t datatype = 0;
    uint32_t dst_domain;
    uint32_t dst_pitch_offset;
    unsigned bpp = pDst->drawable.bitsPerPixel;
    uint32_t scratch_pitch = RADEON_ALIGN(w * bpp / 8, 64);
    uint32_t copy_pitch;
    uint32_t swap = RADEON_HOST_DATA_SWAP_NONE;
    int ret;
    Bool flush = TRUE;
    Bool r;
    int i;

    if (bpp < 8)
	return FALSE;

    driver_priv = exaGetPixmapDriverPrivate(pDst);
    if (!driver_priv || !driver_priv->bo)
	return FALSE;

#if X_BYTE_ORDER == X_BIG_ENDIAN
    switch (bpp) {
    case 32:
	swap = RADEON_HOST_DATA_SWAP_32BIT;
	break;
    case 16:
	swap = RADEON_HOST_DATA_SWAP_16BIT;
	break;
    }
#endif

    /* If we know the BO won't be busy / in VRAM, don't bother with a scratch */
    copy_dst = driver_priv->bo;
    copy_pitch = pDst->devKind;
    if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) {
	if (!radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) {
	    flush = FALSE;
	    if (!radeon_bo_is_busy(driver_priv->bo, &dst_domain) &&
		!(dst_domain & RADEON_GEM_DOMAIN_VRAM))
		goto copy;
	}
	/* use cpu copy for fast fb access */
	if (info->is_fast_fb)
	    goto copy;
    }

    size = scratch_pitch * h;
    scratch = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_GTT, 0);
    if (scratch == NULL) {
	goto copy;
    }
    radeon_cs_space_reset_bos(info->cs);
    radeon_add_pixmap(info->cs, pDst, 0, RADEON_GEM_DOMAIN_VRAM);
    radeon_cs_space_add_persistent_bo(info->cs, scratch, RADEON_GEM_DOMAIN_GTT, 0);
    ret = radeon_cs_space_check(info->cs);
    if (ret) {
	goto copy;
    }
    copy_dst = scratch;
    copy_pitch = scratch_pitch;
    flush = FALSE;

copy:
    if (flush)
	radeon_cs_flush_indirect(pScrn);

    ret = radeon_bo_map(copy_dst, 0);
    if (ret) {
        r = FALSE;
        goto out;
    }
    r = TRUE;
    size = w * bpp / 8;
    dst = copy_dst->ptr;
    if (copy_dst == driver_priv->bo)
	dst += y * copy_pitch + x * bpp / 8;
    for (i = 0; i < h; i++) {
        RADEONCopySwap(dst + i * copy_pitch, (uint8_t*)src, size, swap);
        src += src_pitch;
    }
    radeon_bo_unmap(copy_dst);

    if (copy_dst == scratch) {
	RADEONGetDatatypeBpp(pDst->drawable.bitsPerPixel, &datatype);
	RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_offset);
	RADEON_SWITCH_TO_2D();
	RADEONBlitChunk(pScrn, scratch, driver_priv->bo, datatype, scratch_pitch << 16,
			dst_pitch_offset, 0, 0, x, y, w, h,
			RADEON_GEM_DOMAIN_GTT, RADEON_GEM_DOMAIN_VRAM);
    }

out:
    if (scratch)
	radeon_bo_unref(scratch);
    return r;
}
static Bool
RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
                           int h, char *dst, int dst_pitch)
{
    RINFO_FROM_SCREEN(pSrc->drawable.pScreen);
    struct radeon_exa_pixmap_priv *driver_priv;
    struct radeon_bo *scratch = NULL;
    struct radeon_bo *copy_src;
    unsigned size;
    uint32_t datatype = 0;
    uint32_t src_domain = 0;
    uint32_t src_pitch_offset;
    unsigned bpp = pSrc->drawable.bitsPerPixel;
    uint32_t scratch_pitch = RADEON_ALIGN(w * bpp / 8, 64);
    uint32_t copy_pitch;
    uint32_t swap = RADEON_HOST_DATA_SWAP_NONE;
    int ret;
    Bool flush = FALSE;
    Bool r;

    if (bpp < 8)
	return FALSE;

    driver_priv = exaGetPixmapDriverPrivate(pSrc);
    if (!driver_priv || !driver_priv->bo)
	return FALSE;

#if X_BYTE_ORDER == X_BIG_ENDIAN
    switch (bpp) {
    case 32:
	swap = RADEON_HOST_DATA_SWAP_32BIT;
	break;
    case 16:
	swap = RADEON_HOST_DATA_SWAP_16BIT;
	break;
    }
#endif

    /* If we know the BO won't end up in VRAM anyway, don't bother with a scratch */
    copy_src = driver_priv->bo;
    copy_pitch = pSrc->devKind;
    if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) {
	if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) {
	    src_domain = radeon_bo_get_src_domain(driver_priv->bo);
	    if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) ==
		(RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM))
		src_domain = 0;
	    else /* A write may be scheduled */
		flush = TRUE;
	}

	if (!src_domain)
	    radeon_bo_is_busy(driver_priv->bo, &src_domain);

	if (src_domain & ~(uint32_t)RADEON_GEM_DOMAIN_VRAM)
	    goto copy;
    }
    size = scratch_pitch * h;
    scratch = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_GTT, 0);
    if (scratch == NULL) {
	goto copy;
    }
    radeon_cs_space_reset_bos(info->cs);
    radeon_add_pixmap(info->cs, pSrc, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
    radeon_cs_space_add_persistent_bo(info->cs, scratch, 0, RADEON_GEM_DOMAIN_GTT);
    ret = radeon_cs_space_check(info->cs);
    if (ret) {
	goto copy;
    }
    RADEONGetDatatypeBpp(pSrc->drawable.bitsPerPixel, &datatype);
    RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset);
    RADEON_SWITCH_TO_2D();
    RADEONBlitChunk(pScrn, driver_priv->bo, scratch, datatype, src_pitch_offset,
                    scratch_pitch << 16, x, y, 0, 0, w, h,
                    RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT,
                    RADEON_GEM_DOMAIN_GTT);
    copy_src = scratch;
    copy_pitch = scratch_pitch;
    flush = TRUE;

copy:
    if (flush)
	FLUSH_RING();

    ret = radeon_bo_map(copy_src, 0);
    if (ret) {
	ErrorF("failed to map pixmap: %d\n", ret);
        r = FALSE;
        goto out;
    }
    r = TRUE;
    w *= bpp / 8;
    if (copy_src == driver_priv->bo)
	size = y * copy_pitch + x * bpp / 8;
    else
	size = 0;
    while (h--) {
        RADEONCopySwap((uint8_t*)dst, copy_src->ptr + size, w, swap);
        size += copy_pitch;
        dst += dst_pitch;
    }
    radeon_bo_unmap(copy_src);
out:
    if (scratch)
	radeon_bo_unref(scratch);
    return r;
}