Home | History | Annotate | Download | only in radeon
      1 /*
      2  * Copyright 2009 Maciej Cencora <m.cencora (at) gmail.com>
      3  *
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining
      7  * a copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sublicense, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial
     16  * portions of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     21  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     22  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     23  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     24  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  */
     27 
     28 #include "radeon_buffer_objects.h"
     29 
     30 #include "main/imports.h"
     31 #include "main/mtypes.h"
     32 #include "main/bufferobj.h"
     33 
     34 #include "radeon_common.h"
     35 
     36 struct radeon_buffer_object *
     37 get_radeon_buffer_object(struct gl_buffer_object *obj)
     38 {
     39     return (struct radeon_buffer_object *) obj;
     40 }
     41 
     42 static struct gl_buffer_object *
     43 radeonNewBufferObject(struct gl_context * ctx,
     44                       GLuint name,
     45                       GLenum target)
     46 {
     47     struct radeon_buffer_object *obj = CALLOC_STRUCT(radeon_buffer_object);
     48 
     49     _mesa_initialize_buffer_object(ctx, &obj->Base, name, target);
     50 
     51     obj->bo = NULL;
     52 
     53     return &obj->Base;
     54 }
     55 
     56 /**
     57  * Called via glDeleteBuffersARB().
     58  */
     59 static void
     60 radeonDeleteBufferObject(struct gl_context * ctx,
     61                          struct gl_buffer_object *obj)
     62 {
     63     struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
     64 
     65     if (obj->Pointer) {
     66         radeon_bo_unmap(radeon_obj->bo);
     67     }
     68 
     69     if (radeon_obj->bo) {
     70         radeon_bo_unref(radeon_obj->bo);
     71     }
     72 
     73     free(radeon_obj);
     74 }
     75 
     76 
     77 /**
     78  * Allocate space for and store data in a buffer object.  Any data that was
     79  * previously stored in the buffer object is lost.  If data is NULL,
     80  * memory will be allocated, but no copy will occur.
     81  * Called via ctx->Driver.BufferData().
     82  * \return GL_TRUE for success, GL_FALSE if out of memory
     83  */
     84 static GLboolean
     85 radeonBufferData(struct gl_context * ctx,
     86                  GLenum target,
     87                  GLsizeiptrARB size,
     88                  const GLvoid * data,
     89                  GLenum usage,
     90                  struct gl_buffer_object *obj)
     91 {
     92     radeonContextPtr radeon = RADEON_CONTEXT(ctx);
     93     struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
     94 
     95     radeon_obj->Base.Size = size;
     96     radeon_obj->Base.Usage = usage;
     97 
     98     if (radeon_obj->bo != NULL) {
     99         radeon_bo_unref(radeon_obj->bo);
    100         radeon_obj->bo = NULL;
    101     }
    102 
    103     if (size != 0) {
    104         radeon_obj->bo = radeon_bo_open(radeon->radeonScreen->bom,
    105                                         0,
    106                                         size,
    107                                         32,
    108                                         RADEON_GEM_DOMAIN_GTT,
    109                                         0);
    110 
    111         if (!radeon_obj->bo)
    112             return GL_FALSE;
    113 
    114         if (data != NULL) {
    115             radeon_bo_map(radeon_obj->bo, GL_TRUE);
    116 
    117             memcpy(radeon_obj->bo->ptr, data, size);
    118 
    119             radeon_bo_unmap(radeon_obj->bo);
    120         }
    121     }
    122     return GL_TRUE;
    123 }
    124 
    125 /**
    126  * Replace data in a subrange of buffer object.  If the data range
    127  * specified by size + offset extends beyond the end of the buffer or
    128  * if data is NULL, no copy is performed.
    129  * Called via glBufferSubDataARB().
    130  */
    131 static void
    132 radeonBufferSubData(struct gl_context * ctx,
    133                     GLintptrARB offset,
    134                     GLsizeiptrARB size,
    135                     const GLvoid * data,
    136                     struct gl_buffer_object *obj)
    137 {
    138     radeonContextPtr radeon = RADEON_CONTEXT(ctx);
    139     struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
    140 
    141     if (radeon_bo_is_referenced_by_cs(radeon_obj->bo, radeon->cmdbuf.cs)) {
    142         radeon_firevertices(radeon);
    143     }
    144 
    145     radeon_bo_map(radeon_obj->bo, GL_TRUE);
    146 
    147     memcpy(radeon_obj->bo->ptr + offset, data, size);
    148 
    149     radeon_bo_unmap(radeon_obj->bo);
    150 }
    151 
    152 /**
    153  * Called via glGetBufferSubDataARB()
    154  */
    155 static void
    156 radeonGetBufferSubData(struct gl_context * ctx,
    157                        GLintptrARB offset,
    158                        GLsizeiptrARB size,
    159                        GLvoid * data,
    160                        struct gl_buffer_object *obj)
    161 {
    162     struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
    163 
    164     radeon_bo_map(radeon_obj->bo, GL_FALSE);
    165 
    166     memcpy(data, radeon_obj->bo->ptr + offset, size);
    167 
    168     radeon_bo_unmap(radeon_obj->bo);
    169 }
    170 
    171 /**
    172  * Called via glMapBuffer() and glMapBufferRange()
    173  */
    174 static void *
    175 radeonMapBufferRange(struct gl_context * ctx,
    176 		     GLintptr offset, GLsizeiptr length,
    177 		     GLbitfield access, struct gl_buffer_object *obj)
    178 {
    179     struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
    180     const GLboolean write_only =
    181        (access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == GL_MAP_WRITE_BIT;
    182 
    183     if (write_only) {
    184         ctx->Driver.Flush(ctx);
    185     }
    186 
    187     if (radeon_obj->bo == NULL) {
    188         obj->Pointer = NULL;
    189         return NULL;
    190     }
    191 
    192     obj->Offset = offset;
    193     obj->Length = length;
    194     obj->AccessFlags = access;
    195 
    196     radeon_bo_map(radeon_obj->bo, write_only);
    197 
    198     obj->Pointer = radeon_obj->bo->ptr + offset;
    199     return obj->Pointer;
    200 }
    201 
    202 
    203 /**
    204  * Called via glUnmapBufferARB()
    205  */
    206 static GLboolean
    207 radeonUnmapBuffer(struct gl_context * ctx,
    208                   struct gl_buffer_object *obj)
    209 {
    210     struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
    211 
    212     if (radeon_obj->bo != NULL) {
    213         radeon_bo_unmap(radeon_obj->bo);
    214     }
    215 
    216     obj->Pointer = NULL;
    217     obj->Offset = 0;
    218     obj->Length = 0;
    219 
    220     return GL_TRUE;
    221 }
    222 
    223 void
    224 radeonInitBufferObjectFuncs(struct dd_function_table *functions)
    225 {
    226     functions->NewBufferObject = radeonNewBufferObject;
    227     functions->DeleteBuffer = radeonDeleteBufferObject;
    228     functions->BufferData = radeonBufferData;
    229     functions->BufferSubData = radeonBufferSubData;
    230     functions->GetBufferSubData = radeonGetBufferSubData;
    231     functions->MapBufferRange = radeonMapBufferRange;
    232     functions->UnmapBuffer = radeonUnmapBuffer;
    233 }
    234