1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
28 #include "pipe/p_defines.h"
29 #include "util/u_memory.h"
30 #include "util/u_inlines.h"
31 #include "draw/draw_context.h"
32 #include "tgsi/tgsi_parse.h"
34 #include "cell_context.h"
35 #include "cell_state.h"
36 #include "cell_gen_fp.h"
37 #include "cell_buffer.h"
41 static INLINE struct cell_fragment_shader_state *
42 cell_fragment_shader_state(void *shader)
44 return (struct cell_fragment_shader_state *) shader;
49 static INLINE struct cell_vertex_shader_state *
50 cell_vertex_shader_state(void *shader)
52 return (struct cell_vertex_shader_state *) shader;
57 * Create fragment shader state.
58 * Called via pipe->create_fs_state()
61 cell_create_fs_state(struct pipe_context *pipe,
62 const struct pipe_shader_state *templ)
64 struct cell_context *cell = cell_context(pipe);
65 struct cell_fragment_shader_state *cfs;
67 cfs = CALLOC_STRUCT(cell_fragment_shader_state);
71 cfs->shader.tokens = tgsi_dup_tokens(templ->tokens);
72 if (!cfs->shader.tokens) {
77 tgsi_scan_shader(templ->tokens, &cfs->info);
79 cell_gen_fragment_program(cell, cfs->shader.tokens, &cfs->code);
86 * Called via pipe->bind_fs_state()
89 cell_bind_fs_state(struct pipe_context *pipe, void *fs)
91 struct cell_context *cell = cell_context(pipe);
93 cell->fs = cell_fragment_shader_state(fs);
95 cell->dirty |= CELL_NEW_FS;
100 * Called via pipe->delete_fs_state()
103 cell_delete_fs_state(struct pipe_context *pipe, void *fs)
105 struct cell_fragment_shader_state *cfs = cell_fragment_shader_state(fs);
107 spe_release_func(&cfs->code);
109 FREE((void *) cfs->shader.tokens);
115 * Create vertex shader state.
116 * Called via pipe->create_vs_state()
119 cell_create_vs_state(struct pipe_context *pipe,
120 const struct pipe_shader_state *templ)
122 struct cell_context *cell = cell_context(pipe);
123 struct cell_vertex_shader_state *cvs;
125 cvs = CALLOC_STRUCT(cell_vertex_shader_state);
129 cvs->shader.tokens = tgsi_dup_tokens(templ->tokens);
130 if (!cvs->shader.tokens) {
135 tgsi_scan_shader(templ->tokens, &cvs->info);
137 cvs->draw_data = draw_create_vertex_shader(cell->draw, &cvs->shader);
138 if (cvs->draw_data == NULL) {
139 FREE( (void *) cvs->shader.tokens );
149 * Called via pipe->bind_vs_state()
152 cell_bind_vs_state(struct pipe_context *pipe, void *vs)
154 struct cell_context *cell = cell_context(pipe);
156 cell->vs = cell_vertex_shader_state(vs);
158 draw_bind_vertex_shader(cell->draw,
159 (cell->vs ? cell->vs->draw_data : NULL));
161 cell->dirty |= CELL_NEW_VS;
166 * Called via pipe->delete_vs_state()
169 cell_delete_vs_state(struct pipe_context *pipe, void *vs)
171 struct cell_context *cell = cell_context(pipe);
172 struct cell_vertex_shader_state *cvs = cell_vertex_shader_state(vs);
174 draw_delete_vertex_shader(cell->draw, cvs->draw_data);
175 FREE( (void *) cvs->shader.tokens );
181 * Called via pipe->set_constant_buffer()
184 cell_set_constant_buffer(struct pipe_context *pipe,
185 uint shader, uint index,
186 struct pipe_buffer *constants)
188 struct cell_context *cell = cell_context(pipe);
189 unsigned size = constants ? constants->size : 0;
190 const void *data = constants ? cell_buffer(constants)->data : NULL;
192 assert(shader < PIPE_SHADER_TYPES);
195 if (cell->constants[shader] == constants)
198 draw_flush(cell->draw);
200 /* note: reference counting */
201 pipe_buffer_reference(&cell->constants[shader], constants);
203 if(shader == PIPE_SHADER_VERTEX) {
204 draw_set_mapped_constant_buffer(cell->draw, PIPE_SHADER_VERTEX, 0,
208 cell->mapped_constants[shader] = data;
210 if (shader == PIPE_SHADER_VERTEX)
211 cell->dirty |= CELL_NEW_VS_CONSTANTS;
212 else if (shader == PIPE_SHADER_FRAGMENT)
213 cell->dirty |= CELL_NEW_FS_CONSTANTS;
218 cell_init_shader_functions(struct cell_context *cell)
220 cell->pipe.create_fs_state = cell_create_fs_state;
221 cell->pipe.bind_fs_state = cell_bind_fs_state;
222 cell->pipe.delete_fs_state = cell_delete_fs_state;
224 cell->pipe.create_vs_state = cell_create_vs_state;
225 cell->pipe.bind_vs_state = cell_bind_vs_state;
226 cell->pipe.delete_vs_state = cell_delete_vs_state;
228 cell->pipe.set_constant_buffer = cell_set_constant_buffer;