Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / drivers / cell / ppu / cell_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 "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"
33
34 #include "cell_context.h"
35 #include "cell_state.h"
36 #include "cell_gen_fp.h"
37 #include "cell_texture.h"
38
39
40 /** cast wrapper */
41 static INLINE struct cell_fragment_shader_state *
42 cell_fragment_shader_state(void *shader)
43 {
44    return (struct cell_fragment_shader_state *) shader;
45 }
46
47
48 /** cast wrapper */
49 static INLINE struct cell_vertex_shader_state *
50 cell_vertex_shader_state(void *shader)
51 {
52    return (struct cell_vertex_shader_state *) shader;
53 }
54
55
56 /**
57  * Create fragment shader state.
58  * Called via pipe->create_fs_state()
59  */
60 static void *
61 cell_create_fs_state(struct pipe_context *pipe,
62                      const struct pipe_shader_state *templ)
63 {
64    struct cell_context *cell = cell_context(pipe);
65    struct cell_fragment_shader_state *cfs;
66
67    cfs = CALLOC_STRUCT(cell_fragment_shader_state);
68    if (!cfs)
69       return NULL;
70
71    cfs->shader.tokens = tgsi_dup_tokens(templ->tokens);
72    if (!cfs->shader.tokens) {
73       FREE(cfs);
74       return NULL;
75    }
76
77    tgsi_scan_shader(templ->tokens, &cfs->info);
78
79    cell_gen_fragment_program(cell, cfs->shader.tokens, &cfs->code);
80
81    return cfs;
82 }
83
84
85 /**
86  * Called via pipe->bind_fs_state()
87  */
88 static void
89 cell_bind_fs_state(struct pipe_context *pipe, void *fs)
90 {
91    struct cell_context *cell = cell_context(pipe);
92
93    cell->fs = cell_fragment_shader_state(fs);
94
95    cell->dirty |= CELL_NEW_FS;
96 }
97
98
99 /**
100  * Called via pipe->delete_fs_state()
101  */
102 static void
103 cell_delete_fs_state(struct pipe_context *pipe, void *fs)
104 {
105    struct cell_fragment_shader_state *cfs = cell_fragment_shader_state(fs);
106
107    spe_release_func(&cfs->code);
108
109    FREE((void *) cfs->shader.tokens);
110    FREE(cfs);
111 }
112
113
114 /**
115  * Create vertex shader state.
116  * Called via pipe->create_vs_state()
117  */
118 static void *
119 cell_create_vs_state(struct pipe_context *pipe,
120                      const struct pipe_shader_state *templ)
121 {
122    struct cell_context *cell = cell_context(pipe);
123    struct cell_vertex_shader_state *cvs;
124
125    cvs = CALLOC_STRUCT(cell_vertex_shader_state);
126    if (!cvs)
127       return NULL;
128
129    cvs->shader.tokens = tgsi_dup_tokens(templ->tokens);
130    if (!cvs->shader.tokens) {
131       FREE(cvs);
132       return NULL;
133    }
134
135    tgsi_scan_shader(templ->tokens, &cvs->info);
136
137    cvs->draw_data = draw_create_vertex_shader(cell->draw, &cvs->shader);
138    if (cvs->draw_data == NULL) {
139       FREE( (void *) cvs->shader.tokens );
140       FREE( cvs );
141       return NULL;
142    }
143
144    return cvs;
145 }
146
147
148 /**
149  * Called via pipe->bind_vs_state()
150  */
151 static void
152 cell_bind_vs_state(struct pipe_context *pipe, void *vs)
153 {
154    struct cell_context *cell = cell_context(pipe);
155
156    cell->vs = cell_vertex_shader_state(vs);
157
158    draw_bind_vertex_shader(cell->draw,
159                            (cell->vs ? cell->vs->draw_data : NULL));
160
161    cell->dirty |= CELL_NEW_VS;
162 }
163
164
165 /**
166  * Called via pipe->delete_vs_state()
167  */
168 static void
169 cell_delete_vs_state(struct pipe_context *pipe, void *vs)
170 {
171    struct cell_context *cell = cell_context(pipe);
172    struct cell_vertex_shader_state *cvs = cell_vertex_shader_state(vs);
173
174    draw_delete_vertex_shader(cell->draw, cvs->draw_data);
175    FREE( (void *) cvs->shader.tokens );
176    FREE( cvs );
177 }
178
179
180 /**
181  * Called via pipe->set_constant_buffer()
182  */
183 static void
184 cell_set_constant_buffer(struct pipe_context *pipe,
185                          uint shader, uint index,
186                          struct pipe_resource *constants)
187 {
188    struct cell_context *cell = cell_context(pipe);
189    unsigned size = constants ? constants->width0 : 0;
190    const void *data = constants ? cell_resource(constants)->data : NULL;
191
192    assert(shader < PIPE_SHADER_TYPES);
193    assert(index == 0);
194
195    if (cell->constants[shader] == constants)
196       return;
197
198    draw_flush(cell->draw);
199
200    /* note: reference counting */
201    pipe_resource_reference(&cell->constants[shader], constants);
202
203    if(shader == PIPE_SHADER_VERTEX) {
204       draw_set_mapped_constant_buffer(cell->draw, PIPE_SHADER_VERTEX, 0,
205                                       data, size);
206    }
207
208    cell->mapped_constants[shader] = data;
209
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;
214 }
215
216
217 void
218 cell_init_shader_functions(struct cell_context *cell)
219 {
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;
223
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;
227
228    cell->pipe.set_constant_buffer = cell_set_constant_buffer;
229 }