Beispiel #1
0
enum pipe_error u_upload_data( struct u_upload_mgr *upload,
                               unsigned size,
                               const void *data,
                               unsigned *out_offset,
                               struct pipe_buffer **outbuf )
{
    unsigned alloc_size = align( size, upload->alignment );
    enum pipe_error ret = PIPE_OK;

    if (upload->offset + alloc_size > upload->size) {
        ret = u_upload_alloc_buffer( upload, alloc_size );
        if (ret)
            return ret;
    }

    /* Copy the data, using map_range if available:
     */
    ret = my_buffer_write( upload->screen,
                           upload->buffer,
                           upload->offset,
                           size,
                           alloc_size,
                           data );
    if (ret)
        return ret;

    /* Emit the return values:
     */
    pipe_buffer_reference( outbuf, upload->buffer );
    *out_offset = upload->offset;
    upload->offset += alloc_size;
    return PIPE_OK;
}
Beispiel #2
0
enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
                                unsigned min_out_offset,
                                unsigned size,
                                unsigned *out_offset,
                                struct pipe_resource **outbuf,
                                void **ptr )
{
   unsigned alloc_size = align( size, upload->alignment );
   unsigned alloc_offset = align(min_out_offset, upload->alignment);
   unsigned offset;

   /* Init these return values here in case we fail below to make
    * sure the caller doesn't get garbage values.
    */
   *out_offset = ~0;
   pipe_resource_reference(outbuf, NULL);
   *ptr = NULL;

   /* Make sure we have enough space in the upload buffer
    * for the sub-allocation. */
   if (MAX2(upload->offset, alloc_offset) + alloc_size > upload->size) {
      enum pipe_error ret = u_upload_alloc_buffer(upload,
                                                  alloc_offset + alloc_size);
      if (ret != PIPE_OK)
         return ret;
   }

   offset = MAX2(upload->offset, alloc_offset);

   if (!upload->map) {
      upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer,
					  offset, upload->size - offset,
					  PIPE_TRANSFER_WRITE |
					  PIPE_TRANSFER_FLUSH_EXPLICIT |
					  PIPE_TRANSFER_UNSYNCHRONIZED,
					  &upload->transfer);
      if (!upload->map) {
         upload->transfer = NULL;
         return PIPE_ERROR_OUT_OF_MEMORY;
      }

      upload->map -= offset;
   }

   assert(offset < upload->buffer->width0);
   assert(offset + size <= upload->buffer->width0);
   assert(size);

   /* Emit the return values: */
   *ptr = upload->map + offset;
   pipe_resource_reference( outbuf, upload->buffer );
   *out_offset = offset;

   upload->offset = offset + alloc_size;
   return PIPE_OK;
}
Beispiel #3
0
enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
                                unsigned min_out_offset,
                                unsigned size,
                                unsigned *out_offset,
                                struct pipe_resource **outbuf,
                                boolean *flushed,
                                void **ptr )
{
   unsigned alloc_size = align( size, upload->alignment );
   unsigned alloc_offset = align(min_out_offset, upload->alignment);
   unsigned offset;

   /* Make sure we have enough space in the upload buffer
    * for the sub-allocation. */
   if (MAX2(upload->offset, alloc_offset) + alloc_size > upload->size) {
      enum pipe_error ret = u_upload_alloc_buffer(upload,
                                                  alloc_offset + alloc_size);
      if (ret)
         return ret;

      *flushed = TRUE;
   } else {
      *flushed = FALSE;
   }

   offset = MAX2(upload->offset, alloc_offset);

   if (!upload->map) {
      upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer,
					  offset, upload->size - offset,
					  PIPE_TRANSFER_WRITE |
					  PIPE_TRANSFER_FLUSH_EXPLICIT |
					  PIPE_TRANSFER_UNSYNCHRONIZED,
					  &upload->transfer);
   }

   assert(offset < upload->buffer->width0);
   assert(offset + size <= upload->buffer->width0);
   assert(size);

   /* Emit the return values: */
   *ptr = upload->map + offset;
   pipe_resource_reference( outbuf, upload->buffer );
   *out_offset = offset;

   upload->offset = offset + alloc_size;
   return PIPE_OK;
}
Beispiel #4
0
void
u_upload_alloc(struct u_upload_mgr *upload,
               unsigned min_out_offset,
               unsigned size,
               unsigned alignment,
               unsigned *out_offset,
               struct pipe_resource **outbuf,
               void **ptr)
{
   unsigned buffer_size = upload->buffer ? upload->buffer->width0 : 0;
   unsigned offset;

   min_out_offset = align(min_out_offset, alignment);

   offset = align(upload->offset, alignment);
   offset = MAX2(offset, min_out_offset);

   /* Make sure we have enough space in the upload buffer
    * for the sub-allocation.
    */
   if (unlikely(!upload->buffer || offset + size > buffer_size)) {
      u_upload_alloc_buffer(upload, min_out_offset + size);

      if (unlikely(!upload->buffer)) {
         *out_offset = ~0;
         pipe_resource_reference(outbuf, NULL);
         *ptr = NULL;
         return;
      }

      offset = min_out_offset;
      buffer_size = upload->buffer->width0;
   }

   if (unlikely(!upload->map)) {
      upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer,
                                          offset,
                                          buffer_size - offset,
                                          upload->map_flags,
                                          &upload->transfer);
      if (unlikely(!upload->map)) {
         upload->transfer = NULL;
         *out_offset = ~0;
         pipe_resource_reference(outbuf, NULL);
         *ptr = NULL;
         return;
      }

      upload->map -= offset;
   }

   assert(offset < buffer_size);
   assert(offset + size <= buffer_size);
   assert(size);

   /* Emit the return values: */
   *ptr = upload->map + offset;
   pipe_resource_reference(outbuf, upload->buffer);
   *out_offset = offset;

   upload->offset = offset + size;
}