e2cdcf636f9bd18dc0e004ed69da13dcbc404e48
[mesa.git] / src / gallium / drivers / nvfx / nvfx_context.c
1 #include "draw/draw_context.h"
2 #include "pipe/p_defines.h"
3 #include "util/u_framebuffer.h"
4 #include "vl/vl_decoder.h"
5 #include "vl/vl_video_buffer.h"
6
7 #include "nvfx_context.h"
8 #include "nvfx_screen.h"
9 #include "nvfx_resource.h"
10
11 static void
12 nvfx_flush(struct pipe_context *pipe,
13 struct pipe_fence_handle **fence)
14 {
15 struct nvfx_context *nvfx = nvfx_context(pipe);
16 struct nvfx_screen *screen = nvfx->screen;
17 struct nouveau_channel *chan = screen->base.channel;
18 /*struct nouveau_grobj *eng3d = screen->eng3d;*/
19
20 /* XXX: we need to actually be intelligent here */
21 /* XXX This flag wasn't set by the state tracker anyway. */
22 /*if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
23 BEGIN_RING(chan, eng3d, 0x1fd8, 1);
24 OUT_RING(chan, 2);
25 BEGIN_RING(chan, eng3d, 0x1fd8, 1);
26 OUT_RING(chan, 1);
27 }*/
28
29 if (fence) {
30 /* horrific hack to make glFinish() work in the absence of
31 * having proper fences in nvfx. a pending rewrite will
32 * fix this properly, but may be a while off.
33 */
34 MARK_RING(chan, 1, 1);
35 OUT_RELOC(chan, screen->fence, 0, NOUVEAU_BO_WR |
36 NOUVEAU_BO_DUMMY, 0, 0);
37 FIRE_RING(chan);
38 nouveau_bo_map(screen->fence, NOUVEAU_BO_RDWR);
39 nouveau_bo_unmap(screen->fence);
40 *fence = NULL;
41 } else {
42 FIRE_RING(chan);
43 }
44 }
45
46 static void
47 nvfx_destroy(struct pipe_context *pipe)
48 {
49 struct nvfx_context *nvfx = nvfx_context(pipe);
50
51 if(nvfx->dummy_fs)
52 pipe->delete_fs_state(pipe, nvfx->dummy_fs);
53
54 for(unsigned i = 0; i < nvfx->vtxbuf_nr; ++i)
55 pipe_resource_reference(&nvfx->vtxbuf[i].buffer, 0);
56 pipe_resource_reference(&nvfx->idxbuf.buffer, 0);
57 util_unreference_framebuffer_state(&nvfx->framebuffer);
58 for(unsigned i = 0; i < PIPE_MAX_SAMPLERS; ++i)
59 pipe_sampler_view_reference(&nvfx->fragment_sampler_views[i], 0);
60
61 if (nvfx->draw)
62 draw_destroy(nvfx->draw);
63
64 if(nvfx->screen->cur_ctx == nvfx)
65 nvfx->screen->cur_ctx = NULL;
66
67 FREE(nvfx);
68 }
69
70 struct pipe_context *
71 nvfx_create(struct pipe_screen *pscreen, void *priv)
72 {
73 struct nvfx_screen *screen = nvfx_screen(pscreen);
74 struct pipe_winsys *ws = pscreen->winsys;
75 struct nvfx_context *nvfx;
76 struct nouveau_winsys *nvws = screen->nvws;
77
78 nvfx = CALLOC(1, sizeof(struct nvfx_context));
79 if (!nvfx)
80 return NULL;
81 nvfx->screen = screen;
82
83 nvfx->nvws = nvws;
84
85 nvfx->pipe.winsys = ws;
86 nvfx->pipe.screen = pscreen;
87 nvfx->pipe.priv = priv;
88 nvfx->pipe.destroy = nvfx_destroy;
89 nvfx->pipe.draw_vbo = nvfx_draw_vbo;
90 nvfx->pipe.clear = nvfx_clear;
91 nvfx->pipe.flush = nvfx_flush;
92
93 nvfx->pipe.create_video_decoder = vl_create_decoder;
94 nvfx->pipe.create_video_buffer = vl_video_buffer_create;
95
96 nvfx->is_nv4x = screen->is_nv4x;
97 nvfx->use_nv4x = screen->use_nv4x;
98 /* TODO: it seems that nv30 might have fixed function clipping usable with vertex programs
99 * However, my code for that doesn't work, so use vp clipping for all cards, which works.
100 */
101 nvfx->use_vp_clipping = TRUE;
102
103 nvfx_init_query_functions(nvfx);
104 nvfx_init_surface_functions(nvfx);
105 nvfx_init_state_functions(nvfx);
106 nvfx_init_sampling_functions(nvfx);
107 nvfx_init_vbo_functions(nvfx);
108 nvfx_init_fragprog_functions(nvfx);
109 nvfx_init_vertprog_functions(nvfx);
110 nvfx_init_resource_functions(&nvfx->pipe);
111 nvfx_init_transfer_functions(&nvfx->pipe);
112
113 /* Create, configure, and install fallback swtnl path */
114 nvfx->draw = draw_create(&nvfx->pipe);
115 draw_wide_point_threshold(nvfx->draw, 9999999.0);
116 draw_wide_line_threshold(nvfx->draw, 9999999.0);
117 draw_enable_line_stipple(nvfx->draw, FALSE);
118 draw_enable_point_sprites(nvfx->draw, FALSE);
119 draw_set_rasterize_stage(nvfx->draw, nvfx_draw_render_stage(nvfx));
120
121 /* set these to that we init them on first validation */
122 nvfx->state.scissor_enabled = ~0;
123 nvfx->hw_pointsprite_control = -1;
124 nvfx->hw_vp_output = -1;
125 nvfx->use_vertex_buffers = -1;
126 nvfx->relocs_needed = NVFX_RELOCATE_ALL;
127
128 LIST_INITHEAD(&nvfx->render_cache);
129
130 return &nvfx->pipe;
131 }