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
00038 #include "pipe/p_winsys.h"
00039 #include "pipe/p_state.h"
00040 #include "pipe/p_inlines.h"
00041 #include "util/u_math.h"
00042 #include "util/u_memory.h"
00043
00044 #include "sw_winsys.h"
00045
00046
00047
00049 struct sw_pipe_winsys
00050 {
00051 struct pipe_winsys Base;
00052
00053 };
00054
00055
00057 struct sw_pipe_buffer
00058 {
00059 struct pipe_buffer Base;
00060 boolean UserBuffer;
00061 void *Data;
00062 void *Mapped;
00063 };
00064
00065
00067 static INLINE struct sw_pipe_buffer *
00068 sw_pipe_buffer(struct pipe_buffer *b)
00069 {
00070 return (struct sw_pipe_buffer *) b;
00071 }
00072
00073
00077 static INLINE unsigned
00078 round_up(unsigned n, unsigned multiple)
00079 {
00080 return (n + multiple - 1) & ~(multiple - 1);
00081 }
00082
00083
00084 static const char *
00085 get_name(struct pipe_winsys *pws)
00086 {
00087 return "software";
00088 }
00089
00090
00092 static struct pipe_buffer *
00093 buffer_create(struct pipe_winsys *pws,
00094 unsigned alignment,
00095 unsigned usage,
00096 unsigned size)
00097 {
00098 struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
00099 if (!buffer)
00100 return NULL;
00101
00102 buffer->Base.refcount = 1;
00103 buffer->Base.alignment = alignment;
00104 buffer->Base.usage = usage;
00105 buffer->Base.size = size;
00106
00107
00108 buffer->Data = align_malloc(size, MAX2(alignment, 16));
00109
00110 return &buffer->Base;
00111 }
00112
00113
00117 static struct pipe_buffer *
00118 user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
00119 {
00120 struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
00121 if (!buffer)
00122 return NULL;
00123
00124 buffer->Base.refcount = 1;
00125 buffer->Base.size = bytes;
00126 buffer->UserBuffer = TRUE;
00127 buffer->Data = ptr;
00128
00129 return &buffer->Base;
00130 }
00131
00132
00133 static void *
00134 buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags)
00135 {
00136 struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
00137 buffer->Mapped = buffer->Data;
00138 return buffer->Mapped;
00139 }
00140
00141
00142 static void
00143 buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
00144 {
00145 struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
00146 buffer->Mapped = NULL;
00147 }
00148
00149
00150 static void
00151 buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buf)
00152 {
00153 struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
00154
00155 if (buffer->Data && !buffer->UserBuffer) {
00156 align_free(buffer->Data);
00157 buffer->Data = NULL;
00158 }
00159
00160 free(buffer);
00161 }
00162
00163
00167 static struct pipe_surface *
00168 surface_alloc(struct pipe_winsys *ws)
00169 {
00170 struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface);
00171 if (!surf)
00172 return NULL;
00173
00174 surf->refcount = 1;
00175 surf->winsys = ws;
00176
00177 return surf;
00178 }
00179
00180
00181 static int
00182 surface_alloc_storage(struct pipe_winsys *winsys,
00183 struct pipe_surface *surf,
00184 unsigned width, unsigned height,
00185 enum pipe_format format,
00186 unsigned flags,
00187 unsigned tex_usage)
00188 {
00189 const unsigned alignment = 64;
00190
00191 surf->width = width;
00192 surf->height = height;
00193 surf->format = format;
00194 pf_get_block(surf->format, &surf->block);
00195 surf->nblocksx = pf_get_nblocksx(&surf->block, width);
00196 surf->nblocksy = pf_get_nblocksy(&surf->block, height);
00197 surf->stride = round_up(surf->nblocksx * surf->block.size, alignment);
00198 surf->usage = flags;
00199
00200 assert(!surf->buffer);
00201 surf->buffer = winsys->buffer_create(winsys, alignment,
00202 PIPE_BUFFER_USAGE_PIXEL,
00203 surf->stride * height);
00204 if(!surf->buffer)
00205 return -1;
00206
00207 return 0;
00208 }
00209
00210
00211 static void
00212 surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
00213 {
00214 struct pipe_surface *surf = *s;
00215 assert(!surf->texture);
00216 surf->refcount--;
00217 if (surf->refcount == 0) {
00218 if (surf->buffer)
00219 winsys_buffer_reference(winsys, &surf->buffer, NULL);
00220 free(surf);
00221 }
00222 *s = NULL;
00223 }
00224
00225
00226 static void
00227 fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
00228 struct pipe_fence_handle *fence)
00229 {
00230
00231 }
00232
00233
00234 static int
00235 fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
00236 unsigned flag)
00237 {
00238
00239 return 0;
00240 }
00241
00242
00243 static int
00244 fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
00245 unsigned flag)
00246 {
00247
00248 return 0;
00249 }
00250
00251
00255 struct pipe_winsys *
00256 create_sw_winsys(void)
00257 {
00258 struct sw_pipe_winsys *ws = CALLOC_STRUCT(sw_pipe_winsys);
00259 if (!ws)
00260 return NULL;
00261
00262
00263
00264
00265 ws->Base.buffer_create = buffer_create;
00266 ws->Base.user_buffer_create = user_buffer_create;
00267 ws->Base.buffer_map = buffer_map;
00268 ws->Base.buffer_unmap = buffer_unmap;
00269 ws->Base.buffer_destroy = buffer_destroy;
00270
00271 ws->Base.surface_alloc = surface_alloc;
00272 ws->Base.surface_alloc_storage = surface_alloc_storage;
00273 ws->Base.surface_release = surface_release;
00274
00275 ws->Base.fence_reference = fence_reference;
00276 ws->Base.fence_signalled = fence_signalled;
00277 ws->Base.fence_finish = fence_finish;
00278
00279 ws->Base.flush_frontbuffer = NULL;
00280
00281 ws->Base.get_name = get_name;
00282
00283 return &ws->Base;
00284 }