Merge remote branch 'vdpau/pipe-video' into pipe-video
[mesa.git] / src / gallium / drivers / noop / noop_pipe.c
1 /*
2 * Copyright 2010 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23 #include <stdio.h>
24 #include <errno.h>
25 #include <pipe/p_defines.h>
26 #include <pipe/p_state.h>
27 #include <pipe/p_context.h>
28 #include <pipe/p_screen.h>
29 #include <util/u_memory.h>
30 #include <util/u_inlines.h>
31 #include <util/u_format.h>
32 #include "noop_public.h"
33 #include "state_tracker/sw_winsys.h"
34
35 void noop_init_state_functions(struct pipe_context *ctx);
36
37 /*
38 * query
39 */
40 struct noop_query {
41 unsigned query;
42 };
43 static struct pipe_query *noop_create_query(struct pipe_context *ctx, unsigned query_type)
44 {
45 struct noop_query *query = CALLOC_STRUCT(noop_query);
46
47 return (struct pipe_query *)query;
48 }
49
50 static void noop_destroy_query(struct pipe_context *ctx, struct pipe_query *query)
51 {
52 FREE(query);
53 }
54
55 static void noop_begin_query(struct pipe_context *ctx, struct pipe_query *query)
56 {
57 }
58
59 static void noop_end_query(struct pipe_context *ctx, struct pipe_query *query)
60 {
61 }
62
63 static boolean noop_get_query_result(struct pipe_context *ctx,
64 struct pipe_query *query,
65 boolean wait, void *vresult)
66 {
67 uint64_t *result = (uint64_t*)vresult;
68
69 *result = 0;
70 return TRUE;
71 }
72
73
74 /*
75 * resource
76 */
77 struct noop_resource {
78 struct pipe_resource base;
79 unsigned size;
80 char *data;
81 struct sw_displaytarget *dt;
82 };
83
84 static unsigned noop_is_resource_referenced(struct pipe_context *pipe,
85 struct pipe_resource *resource,
86 unsigned level, int layer)
87 {
88 return PIPE_UNREFERENCED;
89 }
90
91 static struct pipe_resource *noop_resource_create(struct pipe_screen *screen,
92 const struct pipe_resource *templ)
93 {
94 struct noop_resource *nresource;
95 unsigned stride;
96
97 nresource = CALLOC_STRUCT(noop_resource);
98 if (nresource == NULL)
99 return NULL;
100
101 stride = util_format_get_stride(templ->format, templ->width0);
102 nresource->base = *templ;
103 nresource->base.screen = screen;
104 nresource->size = stride * templ->height0 * templ->depth0;
105 nresource->data = malloc(nresource->size);
106 pipe_reference_init(&nresource->base.reference, 1);
107 if (nresource->data == NULL) {
108 FREE(nresource);
109 return NULL;
110 }
111 #if 0
112 if (nresource->base.bind & (PIPE_BIND_DISPLAY_TARGET |
113 PIPE_BIND_SCANOUT |
114 PIPE_BIND_SHARED)) {
115 struct sw_winsys *winsys = (struct sw_winsys *)screen->winsys;
116 unsigned stride;
117
118 nresource->dt = winsys->displaytarget_create(winsys, nresource->base.bind,
119 nresource->base.format,
120 nresource->base.width0,
121 nresource->base.height0,
122 16, &stride);
123 }
124 #endif
125 return &nresource->base;
126 }
127
128 static struct pipe_resource *noop_resource_from_handle(struct pipe_screen * screen,
129 const struct pipe_resource *templ,
130 struct winsys_handle *whandle)
131 {
132 struct sw_winsys *winsys = (struct sw_winsys *)screen->winsys;
133 struct noop_resource *nresource;
134 struct sw_displaytarget *dt;
135 unsigned stride;
136
137 dt = winsys->displaytarget_from_handle(winsys, templ, whandle, &stride);
138 if (dt == NULL) {
139 return NULL;
140 }
141 nresource = (struct noop_resource *)noop_resource_create(screen, templ);
142 nresource->dt = dt;
143 return &nresource->base;
144 }
145
146 static boolean noop_resource_get_handle(struct pipe_screen *screen,
147 struct pipe_resource *resource,
148 struct winsys_handle *handle)
149 {
150 struct sw_winsys *winsys = (struct sw_winsys *)screen->winsys;
151 struct noop_resource *nresource = (struct noop_resource *)resource;
152
153 if (nresource->dt == NULL)
154 return FALSE;
155
156 return winsys->displaytarget_get_handle(winsys, nresource->dt, handle);
157 }
158
159 static void noop_resource_destroy(struct pipe_screen *screen,
160 struct pipe_resource *resource)
161 {
162 struct noop_resource *nresource = (struct noop_resource *)resource;
163
164 if (nresource->dt) {
165 /* display target */
166 struct sw_winsys *winsys = (struct sw_winsys *)screen->winsys;
167 winsys->displaytarget_destroy(winsys, nresource->dt);
168 }
169 free(nresource->data);
170 FREE(resource);
171 }
172
173 static struct pipe_resource *noop_user_buffer_create(struct pipe_screen *screen,
174 void *ptr, unsigned bytes,
175 unsigned bind)
176 {
177 struct pipe_resource templ;
178
179 templ.target = PIPE_BUFFER;
180 templ.format = PIPE_FORMAT_R8_UNORM;
181 templ.usage = PIPE_USAGE_IMMUTABLE;
182 templ.bind = bind;
183 templ.width0 = bytes;
184 templ.height0 = 1;
185 templ.depth0 = 1;
186 templ.flags = 0;
187 return noop_resource_create(screen, &templ);
188 }
189
190
191 /*
192 * transfer
193 */
194 static struct pipe_transfer *noop_get_transfer(struct pipe_context *context,
195 struct pipe_resource *resource,
196 unsigned level,
197 enum pipe_transfer_usage usage,
198 const struct pipe_box *box)
199 {
200 struct pipe_transfer *transfer;
201
202 transfer = CALLOC_STRUCT(pipe_transfer);
203 if (transfer == NULL)
204 return NULL;
205 pipe_resource_reference(&transfer->resource, resource);
206 transfer->level = level;
207 transfer->usage = usage;
208 transfer->box = *box;
209 transfer->stride = 1;
210 transfer->layer_stride = 1;
211 return transfer;
212 }
213
214 static void *noop_transfer_map(struct pipe_context *pipe,
215 struct pipe_transfer *transfer)
216 {
217 struct noop_resource *nresource = (struct noop_resource *)transfer->resource;
218
219 return nresource->data;
220 }
221
222 static void noop_transfer_flush_region(struct pipe_context *pipe,
223 struct pipe_transfer *transfer,
224 const struct pipe_box *box)
225 {
226 }
227
228 static void noop_transfer_unmap(struct pipe_context *pipe,
229 struct pipe_transfer *transfer)
230 {
231 }
232
233 static void noop_transfer_destroy(struct pipe_context *pipe,
234 struct pipe_transfer *transfer)
235 {
236 pipe_resource_reference(&transfer->resource, NULL);
237 FREE(transfer);
238 }
239
240 static void noop_transfer_inline_write(struct pipe_context *pipe,
241 struct pipe_resource *resource,
242 unsigned level,
243 unsigned usage,
244 const struct pipe_box *box,
245 const void *data,
246 unsigned stride,
247 unsigned layer_stride)
248 {
249 }
250
251
252 /*
253 * clear/copy
254 */
255 static void noop_clear(struct pipe_context *ctx, unsigned buffers,
256 const float *rgba, double depth, unsigned stencil)
257 {
258 }
259
260 static void noop_clear_render_target(struct pipe_context *ctx,
261 struct pipe_surface *dst,
262 const float *rgba,
263 unsigned dstx, unsigned dsty,
264 unsigned width, unsigned height)
265 {
266 }
267
268 static void noop_clear_depth_stencil(struct pipe_context *ctx,
269 struct pipe_surface *dst,
270 unsigned clear_flags,
271 double depth,
272 unsigned stencil,
273 unsigned dstx, unsigned dsty,
274 unsigned width, unsigned height)
275 {
276 }
277
278 static void noop_resource_copy_region(struct pipe_context *ctx,
279 struct pipe_resource *dst,
280 unsigned dst_level,
281 unsigned dstx, unsigned dsty, unsigned dstz,
282 struct pipe_resource *src,
283 unsigned src_level,
284 const struct pipe_box *src_box)
285 {
286 }
287
288
289 /*
290 * context
291 */
292 static void noop_flush(struct pipe_context *ctx, unsigned flags,
293 struct pipe_fence_handle **fence)
294 {
295 }
296
297 static void noop_destroy_context(struct pipe_context *ctx)
298 {
299 FREE(ctx);
300 }
301
302 static struct pipe_context *noop_create_context(struct pipe_screen *screen, void *priv)
303 {
304 struct pipe_context *ctx = CALLOC_STRUCT(pipe_context);
305
306 if (ctx == NULL)
307 return NULL;
308 ctx->winsys = screen->winsys;
309 ctx->screen = screen;
310 ctx->priv = priv;
311 ctx->destroy = noop_destroy_context;
312 ctx->flush = noop_flush;
313 ctx->clear = noop_clear;
314 ctx->clear_render_target = noop_clear_render_target;
315 ctx->clear_depth_stencil = noop_clear_depth_stencil;
316 ctx->resource_copy_region = noop_resource_copy_region;
317 ctx->create_query = noop_create_query;
318 ctx->destroy_query = noop_destroy_query;
319 ctx->begin_query = noop_begin_query;
320 ctx->end_query = noop_end_query;
321 ctx->get_query_result = noop_get_query_result;
322 ctx->get_transfer = noop_get_transfer;
323 ctx->transfer_map = noop_transfer_map;
324 ctx->transfer_flush_region = noop_transfer_flush_region;
325 ctx->transfer_unmap = noop_transfer_unmap;
326 ctx->transfer_destroy = noop_transfer_destroy;
327 ctx->transfer_inline_write = noop_transfer_inline_write;
328 ctx->is_resource_referenced = noop_is_resource_referenced;
329 noop_init_state_functions(ctx);
330
331 return ctx;
332 }
333
334
335 /*
336 * pipe_screen
337 */
338 static void noop_flush_frontbuffer(struct pipe_screen *_screen,
339 struct pipe_resource *resource,
340 unsigned level, unsigned layer,
341 void *context_private)
342 {
343 }
344
345 static const char *noop_get_vendor(struct pipe_screen* pscreen)
346 {
347 return "X.Org";
348 }
349
350 static const char *noop_get_name(struct pipe_screen* pscreen)
351 {
352 return "NOOP";
353 }
354
355 static int noop_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
356 {
357 switch (param) {
358 /* Supported features (boolean caps). */
359 case PIPE_CAP_NPOT_TEXTURES:
360 case PIPE_CAP_TWO_SIDED_STENCIL:
361 case PIPE_CAP_GLSL:
362 case PIPE_CAP_OCCLUSION_QUERY:
363 case PIPE_CAP_POINT_SPRITE:
364 case PIPE_CAP_ANISOTROPIC_FILTER:
365 case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
366 case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
367 case PIPE_CAP_TEXTURE_SHADOW_MAP:
368 case PIPE_CAP_TEXTURE_SWIZZLE:
369 case PIPE_CAP_BLEND_EQUATION_SEPARATE:
370
371 return 1;
372 case PIPE_CAP_DUAL_SOURCE_BLEND:
373
374 case PIPE_CAP_SM3:
375 case PIPE_CAP_INDEP_BLEND_ENABLE:
376 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
377 case PIPE_CAP_DEPTH_CLAMP:
378 case PIPE_CAP_SHADER_STENCIL_EXPORT:
379 case PIPE_CAP_TIMER_QUERY:
380 case PIPE_CAP_STREAM_OUTPUT:
381 case PIPE_CAP_PRIMITIVE_RESTART:
382 case PIPE_CAP_INDEP_BLEND_FUNC:
383 return 0;
384
385 /* Texturing. */
386 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
387 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
388 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
389 return 14;
390 case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
391 return 16;
392 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
393 case PIPE_CAP_MAX_COMBINED_SAMPLERS:
394 return 16;
395
396 /* Render targets. */
397 case PIPE_CAP_MAX_RENDER_TARGETS:
398 return 8;
399
400 /* Fragment coordinate conventions. */
401 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
402 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
403 return 1;
404 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
405 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
406 return 0;
407
408 default:
409 return 0;
410 }
411 }
412
413 static float noop_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param)
414 {
415 switch (param) {
416 case PIPE_CAP_MAX_LINE_WIDTH:
417 case PIPE_CAP_MAX_LINE_WIDTH_AA:
418 case PIPE_CAP_MAX_POINT_WIDTH:
419 case PIPE_CAP_MAX_POINT_WIDTH_AA:
420 return 8192.0f;
421 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
422 return 16.0f;
423 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
424 return 16.0f;
425 default:
426 return 0.0f;
427 }
428 }
429
430 static int noop_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enum pipe_shader_cap param)
431 {
432 switch(shader)
433 {
434 case PIPE_SHADER_FRAGMENT:
435 case PIPE_SHADER_VERTEX:
436 case PIPE_SHADER_GEOMETRY:
437 break;
438 default:
439 return 0;
440 }
441
442 switch (param) {
443 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
444 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
445 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
446 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
447 return 16384;
448 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
449 return 8;
450 case PIPE_SHADER_CAP_MAX_INPUTS:
451 return 16;
452 case PIPE_SHADER_CAP_MAX_TEMPS:
453 return 256;
454 case PIPE_SHADER_CAP_MAX_ADDRS:
455 return 1;
456 case PIPE_SHADER_CAP_MAX_CONSTS:
457 return 256;
458 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
459 return 1;
460 case PIPE_SHADER_CAP_MAX_PREDS:
461 return 0;
462 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
463 return 1;
464 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
465 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
466 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
467 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
468 return 1;
469 default:
470 return 0;
471 }
472 }
473
474 static boolean noop_is_format_supported(struct pipe_screen* screen,
475 enum pipe_format format,
476 enum pipe_texture_target target,
477 unsigned sample_count,
478 unsigned usage,
479 unsigned geom_flags)
480 {
481 return true;
482 }
483
484 static void noop_destroy_screen(struct pipe_screen *screen)
485 {
486 FREE(screen);
487 }
488
489 struct pipe_screen *noop_screen_create(struct sw_winsys *winsys)
490 {
491 struct pipe_screen *screen;
492
493 screen = CALLOC_STRUCT(pipe_screen);
494 if (screen == NULL) {
495 return NULL;
496 }
497
498 screen->winsys = (struct pipe_winsys*)winsys;
499 screen->destroy = noop_destroy_screen;
500 screen->get_name = noop_get_name;
501 screen->get_vendor = noop_get_vendor;
502 screen->get_param = noop_get_param;
503 screen->get_shader_param = noop_get_shader_param;
504 screen->get_paramf = noop_get_paramf;
505 screen->is_format_supported = noop_is_format_supported;
506 screen->context_create = noop_create_context;
507 screen->resource_create = noop_resource_create;
508 screen->resource_from_handle = noop_resource_from_handle;
509 screen->resource_get_handle = noop_resource_get_handle;
510 screen->resource_destroy = noop_resource_destroy;
511 screen->user_buffer_create = noop_user_buffer_create;
512 screen->flush_frontbuffer = noop_flush_frontbuffer;
513
514 return screen;
515 }