svga: Don't advertise pixel shader addr register support.
[mesa.git] / src / gallium / drivers / softpipe / sp_state_shader.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * 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, sub license, 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 portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include "sp_context.h"
29 #include "sp_state.h"
30 #include "sp_fs.h"
31 #include "sp_texture.h"
32
33 #include "pipe/p_defines.h"
34 #include "util/u_memory.h"
35 #include "util/u_inlines.h"
36 #include "draw/draw_context.h"
37 #include "draw/draw_vs.h"
38 #include "draw/draw_gs.h"
39 #include "tgsi/tgsi_dump.h"
40 #include "tgsi/tgsi_exec.h"
41 #include "tgsi/tgsi_scan.h"
42 #include "tgsi/tgsi_parse.h"
43
44
45 static void *
46 softpipe_create_fs_state(struct pipe_context *pipe,
47 const struct pipe_shader_state *templ)
48 {
49 struct softpipe_context *softpipe = softpipe_context(pipe);
50 struct sp_fragment_shader *state;
51 unsigned i;
52
53 /* debug */
54 if (softpipe->dump_fs)
55 tgsi_dump(templ->tokens, 0);
56
57 /* codegen */
58 state = softpipe_create_fs_sse( softpipe, templ );
59 if (!state) {
60 state = softpipe_create_fs_exec( softpipe, templ );
61 }
62
63 if (!state)
64 return NULL;
65
66 /* draw's fs state */
67 state->draw_shader = draw_create_fragment_shader(softpipe->draw, templ);
68 if (!state->draw_shader) {
69 state->delete( state );
70 return NULL;
71 }
72
73 /* get/save the summary info for this shader */
74 tgsi_scan_shader(templ->tokens, &state->info);
75
76 for (i = 0; i < state->info.num_properties; ++i) {
77 if (state->info.properties[i].name == TGSI_PROPERTY_FS_COORD_ORIGIN)
78 state->origin_lower_left = state->info.properties[i].data[0];
79 else if (state->info.properties[i].name == TGSI_PROPERTY_FS_COORD_PIXEL_CENTER)
80 state->pixel_center_integer = state->info.properties[i].data[0];
81 else if (state->info.properties[i].name == TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS)
82 state->color0_writes_all_cbufs = state->info.properties[i].data[0];
83 }
84
85 return state;
86 }
87
88
89 static void
90 softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
91 {
92 struct softpipe_context *softpipe = softpipe_context(pipe);
93
94 draw_flush(softpipe->draw);
95
96 if (softpipe->fs == fs)
97 return;
98
99 draw_flush(softpipe->draw);
100
101 softpipe->fs = fs;
102
103 draw_bind_fragment_shader(softpipe->draw,
104 (softpipe->fs ? softpipe->fs->draw_shader : NULL));
105
106 softpipe->dirty |= SP_NEW_FS;
107 }
108
109
110 static void
111 softpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
112 {
113 struct softpipe_context *softpipe = softpipe_context(pipe);
114 struct sp_fragment_shader *state = fs;
115
116 assert(fs != softpipe_context(pipe)->fs);
117
118 if (softpipe->fs_machine->Tokens == state->shader.tokens) {
119 /* unbind the shader from the tgsi executor if we're
120 * deleting it.
121 */
122 tgsi_exec_machine_bind_shader(softpipe->fs_machine, NULL, 0, NULL);
123 }
124
125 draw_delete_fragment_shader(softpipe->draw, state->draw_shader);
126
127 state->delete( state );
128 }
129
130
131 static void *
132 softpipe_create_vs_state(struct pipe_context *pipe,
133 const struct pipe_shader_state *templ)
134 {
135 struct softpipe_context *softpipe = softpipe_context(pipe);
136 struct sp_vertex_shader *state;
137
138 state = CALLOC_STRUCT(sp_vertex_shader);
139 if (state == NULL )
140 goto fail;
141
142 /* copy shader tokens, the ones passed in will go away.
143 */
144 state->shader.tokens = tgsi_dup_tokens(templ->tokens);
145 if (state->shader.tokens == NULL)
146 goto fail;
147
148 state->draw_data = draw_create_vertex_shader(softpipe->draw, templ);
149 if (state->draw_data == NULL)
150 goto fail;
151
152 state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
153
154 return state;
155
156 fail:
157 if (state) {
158 FREE( (void *)state->shader.tokens );
159 FREE( state->draw_data );
160 FREE( state );
161 }
162 return NULL;
163 }
164
165
166 static void
167 softpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
168 {
169 struct softpipe_context *softpipe = softpipe_context(pipe);
170
171 softpipe->vs = (struct sp_vertex_shader *) vs;
172
173 draw_bind_vertex_shader(softpipe->draw,
174 (softpipe->vs ? softpipe->vs->draw_data : NULL));
175
176 softpipe->dirty |= SP_NEW_VS;
177 }
178
179
180 static void
181 softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
182 {
183 struct softpipe_context *softpipe = softpipe_context(pipe);
184
185 struct sp_vertex_shader *state = (struct sp_vertex_shader *) vs;
186
187 draw_delete_vertex_shader(softpipe->draw, state->draw_data);
188 FREE( (void *)state->shader.tokens );
189 FREE( state );
190 }
191
192
193 static void *
194 softpipe_create_gs_state(struct pipe_context *pipe,
195 const struct pipe_shader_state *templ)
196 {
197 struct softpipe_context *softpipe = softpipe_context(pipe);
198 struct sp_geometry_shader *state;
199
200 state = CALLOC_STRUCT(sp_geometry_shader);
201 if (state == NULL )
202 goto fail;
203
204 /* debug */
205 if (softpipe->dump_gs)
206 tgsi_dump(templ->tokens, 0);
207
208 /* copy shader tokens, the ones passed in will go away.
209 */
210 state->shader.tokens = tgsi_dup_tokens(templ->tokens);
211 if (state->shader.tokens == NULL)
212 goto fail;
213
214 state->draw_data = draw_create_geometry_shader(softpipe->draw, templ);
215 if (state->draw_data == NULL)
216 goto fail;
217
218 state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
219
220 return state;
221
222 fail:
223 if (state) {
224 FREE( (void *)state->shader.tokens );
225 FREE( state->draw_data );
226 FREE( state );
227 }
228 return NULL;
229 }
230
231
232 static void
233 softpipe_bind_gs_state(struct pipe_context *pipe, void *gs)
234 {
235 struct softpipe_context *softpipe = softpipe_context(pipe);
236
237 softpipe->gs = (struct sp_geometry_shader *)gs;
238
239 draw_bind_geometry_shader(softpipe->draw,
240 (softpipe->gs ? softpipe->gs->draw_data : NULL));
241
242 softpipe->dirty |= SP_NEW_GS;
243 }
244
245
246 static void
247 softpipe_delete_gs_state(struct pipe_context *pipe, void *gs)
248 {
249 struct softpipe_context *softpipe = softpipe_context(pipe);
250
251 struct sp_geometry_shader *state =
252 (struct sp_geometry_shader *)gs;
253
254 draw_delete_geometry_shader(softpipe->draw,
255 (state) ? state->draw_data : 0);
256 FREE(state);
257 }
258
259
260 static void
261 softpipe_set_constant_buffer(struct pipe_context *pipe,
262 uint shader, uint index,
263 struct pipe_resource *constants)
264 {
265 struct softpipe_context *softpipe = softpipe_context(pipe);
266 unsigned size = constants ? constants->width0 : 0;
267 const void *data = constants ? softpipe_resource(constants)->data : NULL;
268
269 assert(shader < PIPE_SHADER_TYPES);
270
271 draw_flush(softpipe->draw);
272
273 /* note: reference counting */
274 pipe_resource_reference(&softpipe->constants[shader][index], constants);
275
276 if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {
277 draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size);
278 }
279
280 softpipe->mapped_constants[shader][index] = data;
281 softpipe->const_buffer_size[shader][index] = size;
282
283 softpipe->dirty |= SP_NEW_CONSTANTS;
284 }
285
286
287 void
288 softpipe_init_shader_funcs(struct pipe_context *pipe)
289 {
290 pipe->create_fs_state = softpipe_create_fs_state;
291 pipe->bind_fs_state = softpipe_bind_fs_state;
292 pipe->delete_fs_state = softpipe_delete_fs_state;
293
294 pipe->create_vs_state = softpipe_create_vs_state;
295 pipe->bind_vs_state = softpipe_bind_vs_state;
296 pipe->delete_vs_state = softpipe_delete_vs_state;
297
298 pipe->create_gs_state = softpipe_create_gs_state;
299 pipe->bind_gs_state = softpipe_bind_gs_state;
300 pipe->delete_gs_state = softpipe_delete_gs_state;
301
302 pipe->set_constant_buffer = softpipe_set_constant_buffer;
303 }