00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00039 #include "pipe/p_winsys.h"
00040 #include "pipe/p_format.h"
00041 #include "pipe/p_context.h"
00042 #include "pipe/p_inlines.h"
00043 #include "util/u_math.h"
00044 #include "util/u_memory.h"
00045 #include "softpipe/sp_winsys.h"
00046 #include "st_winsys.h"
00047
00048
00049 struct st_softpipe_buffer
00050 {
00051 struct pipe_buffer base;
00052 boolean userBuffer;
00053 void *data;
00054 void *mapped;
00055 };
00056
00057
00059 static INLINE struct st_softpipe_buffer *
00060 st_softpipe_buffer( struct pipe_buffer *buf )
00061 {
00062 return (struct st_softpipe_buffer *)buf;
00063 }
00064
00065
00066 static void *
00067 st_softpipe_buffer_map(struct pipe_winsys *winsys,
00068 struct pipe_buffer *buf,
00069 unsigned flags)
00070 {
00071 struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
00072 st_softpipe_buf->mapped = st_softpipe_buf->data;
00073 return st_softpipe_buf->mapped;
00074 }
00075
00076
00077 static void
00078 st_softpipe_buffer_unmap(struct pipe_winsys *winsys,
00079 struct pipe_buffer *buf)
00080 {
00081 struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
00082 st_softpipe_buf->mapped = NULL;
00083 }
00084
00085
00086 static void
00087 st_softpipe_buffer_destroy(struct pipe_winsys *winsys,
00088 struct pipe_buffer *buf)
00089 {
00090 struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf);
00091
00092 if (oldBuf->data) {
00093 if (!oldBuf->userBuffer)
00094 align_free(oldBuf->data);
00095
00096 oldBuf->data = NULL;
00097 }
00098
00099 FREE(oldBuf);
00100 }
00101
00102
00103 static void
00104 st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys,
00105 struct pipe_surface *surf,
00106 void *context_private)
00107 {
00108 }
00109
00110
00111
00112 static const char *
00113 st_softpipe_get_name(struct pipe_winsys *winsys)
00114 {
00115 return "softpipe";
00116 }
00117
00118
00119 static struct pipe_buffer *
00120 st_softpipe_buffer_create(struct pipe_winsys *winsys,
00121 unsigned alignment,
00122 unsigned usage,
00123 unsigned size)
00124 {
00125 struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer);
00126
00127 buffer->base.refcount = 1;
00128 buffer->base.alignment = alignment;
00129 buffer->base.usage = usage;
00130 buffer->base.size = size;
00131
00132 buffer->data = align_malloc(size, alignment);
00133
00134 return &buffer->base;
00135 }
00136
00137
00141 static struct pipe_buffer *
00142 st_softpipe_user_buffer_create(struct pipe_winsys *winsys,
00143 void *ptr,
00144 unsigned bytes)
00145 {
00146 struct st_softpipe_buffer *buffer;
00147
00148 buffer = CALLOC_STRUCT(st_softpipe_buffer);
00149 if(!buffer)
00150 return NULL;
00151
00152 buffer->base.refcount = 1;
00153 buffer->base.size = bytes;
00154 buffer->userBuffer = TRUE;
00155 buffer->data = ptr;
00156
00157 return &buffer->base;
00158 }
00159
00160
00164 static INLINE unsigned
00165 round_up(unsigned n, unsigned multiple)
00166 {
00167 return (n + multiple - 1) & ~(multiple - 1);
00168 }
00169
00170
00171 static int
00172 st_softpipe_surface_alloc_storage(struct pipe_winsys *winsys,
00173 struct pipe_surface *surf,
00174 unsigned width, unsigned height,
00175 enum pipe_format format,
00176 unsigned flags,
00177 unsigned tex_usage)
00178 {
00179 const unsigned alignment = 64;
00180
00181 surf->width = width;
00182 surf->height = height;
00183 surf->format = format;
00184 pf_get_block(format, &surf->block);
00185 surf->nblocksx = pf_get_nblocksx(&surf->block, width);
00186 surf->nblocksy = pf_get_nblocksy(&surf->block, height);
00187 surf->stride = round_up(surf->nblocksx * surf->block.size, alignment);
00188 surf->usage = flags;
00189
00190 assert(!surf->buffer);
00191 surf->buffer = winsys->buffer_create(winsys, alignment,
00192 PIPE_BUFFER_USAGE_PIXEL,
00193 surf->stride * surf->nblocksy);
00194 if(!surf->buffer)
00195 return -1;
00196
00197 return 0;
00198 }
00199
00200
00201 static struct pipe_surface *
00202 st_softpipe_surface_alloc(struct pipe_winsys *winsys)
00203 {
00204 struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface);
00205
00206 assert(winsys);
00207
00208 surface->refcount = 1;
00209 surface->winsys = winsys;
00210
00211 return surface;
00212 }
00213
00214
00215 static void
00216 st_softpipe_surface_release(struct pipe_winsys *winsys,
00217 struct pipe_surface **s)
00218 {
00219 struct pipe_surface *surf = *s;
00220 assert(!surf->texture);
00221 surf->refcount--;
00222 if (surf->refcount == 0) {
00223 if (surf->buffer)
00224 winsys_buffer_reference(winsys, &surf->buffer, NULL);
00225 free(surf);
00226 }
00227 *s = NULL;
00228 }
00229
00230
00231 static void
00232 st_softpipe_fence_reference(struct pipe_winsys *winsys,
00233 struct pipe_fence_handle **ptr,
00234 struct pipe_fence_handle *fence)
00235 {
00236 }
00237
00238
00239 static int
00240 st_softpipe_fence_signalled(struct pipe_winsys *winsys,
00241 struct pipe_fence_handle *fence,
00242 unsigned flag)
00243 {
00244 return 0;
00245 }
00246
00247
00248 static int
00249 st_softpipe_fence_finish(struct pipe_winsys *winsys,
00250 struct pipe_fence_handle *fence,
00251 unsigned flag)
00252 {
00253 return 0;
00254 }
00255
00256
00257 static void
00258 st_softpipe_destroy(struct pipe_winsys *winsys)
00259 {
00260 FREE(winsys);
00261 }
00262
00263
00264 static struct pipe_screen *
00265 st_softpipe_screen_create(void)
00266 {
00267 static struct pipe_winsys *winsys;
00268 struct pipe_screen *screen;
00269
00270 winsys = CALLOC_STRUCT(pipe_winsys);
00271 if(!winsys)
00272 return NULL;
00273
00274 winsys->destroy = st_softpipe_destroy;
00275
00276 winsys->buffer_create = st_softpipe_buffer_create;
00277 winsys->user_buffer_create = st_softpipe_user_buffer_create;
00278 winsys->buffer_map = st_softpipe_buffer_map;
00279 winsys->buffer_unmap = st_softpipe_buffer_unmap;
00280 winsys->buffer_destroy = st_softpipe_buffer_destroy;
00281
00282 winsys->surface_alloc = st_softpipe_surface_alloc;
00283 winsys->surface_alloc_storage = st_softpipe_surface_alloc_storage;
00284 winsys->surface_release = st_softpipe_surface_release;
00285
00286 winsys->fence_reference = st_softpipe_fence_reference;
00287 winsys->fence_signalled = st_softpipe_fence_signalled;
00288 winsys->fence_finish = st_softpipe_fence_finish;
00289
00290 winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer;
00291 winsys->get_name = st_softpipe_get_name;
00292
00293 screen = softpipe_create_screen(winsys);
00294 if(!screen)
00295 st_softpipe_destroy(winsys);
00296
00297 return screen;
00298 }
00299
00300
00301 static struct pipe_context *
00302 st_softpipe_context_create(struct pipe_screen *screen)
00303 {
00304 return softpipe_create(screen, screen->winsys, NULL);
00305 }
00306
00307
00308 const struct st_winsys st_softpipe_winsys = {
00309 &st_softpipe_screen_create,
00310 &st_softpipe_context_create,
00311 };