00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "pipe/p_defines.h"
00029 #include "util/u_memory.h"
00030 #include "pipe/p_inlines.h"
00031 #include "pipe/p_winsys.h"
00032 #include "draw/draw_context.h"
00033 #include "tgsi/tgsi_parse.h"
00034
00035 #include "cell_context.h"
00036 #include "cell_state.h"
00037 #include "cell_gen_fp.h"
00038
00039
00041 static INLINE struct cell_fragment_shader_state *
00042 cell_fragment_shader_state(void *shader)
00043 {
00044 return (struct cell_fragment_shader_state *) shader;
00045 }
00046
00047
00049 static INLINE struct cell_vertex_shader_state *
00050 cell_vertex_shader_state(void *shader)
00051 {
00052 return (struct cell_vertex_shader_state *) shader;
00053 }
00054
00055
00060 static void *
00061 cell_create_fs_state(struct pipe_context *pipe,
00062 const struct pipe_shader_state *templ)
00063 {
00064 struct cell_context *cell = cell_context(pipe);
00065 struct cell_fragment_shader_state *cfs;
00066
00067 cfs = CALLOC_STRUCT(cell_fragment_shader_state);
00068 if (!cfs)
00069 return NULL;
00070
00071 cfs->shader.tokens = tgsi_dup_tokens(templ->tokens);
00072 if (!cfs->shader.tokens) {
00073 FREE(cfs);
00074 return NULL;
00075 }
00076
00077 tgsi_scan_shader(templ->tokens, &cfs->info);
00078
00079 cell_gen_fragment_program(cell, cfs->shader.tokens, &cfs->code);
00080
00081 return cfs;
00082 }
00083
00084
00088 static void
00089 cell_bind_fs_state(struct pipe_context *pipe, void *fs)
00090 {
00091 struct cell_context *cell = cell_context(pipe);
00092
00093 cell->fs = cell_fragment_shader_state(fs);
00094
00095 cell->dirty |= CELL_NEW_FS;
00096 }
00097
00098
00102 static void
00103 cell_delete_fs_state(struct pipe_context *pipe, void *fs)
00104 {
00105 struct cell_fragment_shader_state *cfs = cell_fragment_shader_state(fs);
00106
00107 spe_release_func(&cfs->code);
00108
00109 FREE((void *) cfs->shader.tokens);
00110 FREE(cfs);
00111 }
00112
00113
00118 static void *
00119 cell_create_vs_state(struct pipe_context *pipe,
00120 const struct pipe_shader_state *templ)
00121 {
00122 struct cell_context *cell = cell_context(pipe);
00123 struct cell_vertex_shader_state *cvs;
00124
00125 cvs = CALLOC_STRUCT(cell_vertex_shader_state);
00126 if (!cvs)
00127 return NULL;
00128
00129 cvs->shader.tokens = tgsi_dup_tokens(templ->tokens);
00130 if (!cvs->shader.tokens) {
00131 FREE(cvs);
00132 return NULL;
00133 }
00134
00135 tgsi_scan_shader(templ->tokens, &cvs->info);
00136
00137 cvs->draw_data = draw_create_vertex_shader(cell->draw, &cvs->shader);
00138 if (cvs->draw_data == NULL) {
00139 FREE( (void *) cvs->shader.tokens );
00140 FREE( cvs );
00141 return NULL;
00142 }
00143
00144 return cvs;
00145 }
00146
00147
00151 static void
00152 cell_bind_vs_state(struct pipe_context *pipe, void *vs)
00153 {
00154 struct cell_context *cell = cell_context(pipe);
00155
00156 cell->vs = cell_vertex_shader_state(vs);
00157
00158 draw_bind_vertex_shader(cell->draw,
00159 (cell->vs ? cell->vs->draw_data : NULL));
00160
00161 cell->dirty |= CELL_NEW_VS;
00162 }
00163
00164
00168 static void
00169 cell_delete_vs_state(struct pipe_context *pipe, void *vs)
00170 {
00171 struct cell_context *cell = cell_context(pipe);
00172 struct cell_vertex_shader_state *cvs = cell_vertex_shader_state(vs);
00173
00174 draw_delete_vertex_shader(cell->draw, cvs->draw_data);
00175 FREE( (void *) cvs->shader.tokens );
00176 FREE( cvs );
00177 }
00178
00179
00183 static void
00184 cell_set_constant_buffer(struct pipe_context *pipe,
00185 uint shader, uint index,
00186 const struct pipe_constant_buffer *buf)
00187 {
00188 struct cell_context *cell = cell_context(pipe);
00189 struct pipe_winsys *ws = pipe->winsys;
00190
00191 assert(shader < PIPE_SHADER_TYPES);
00192 assert(index == 0);
00193
00194
00195 winsys_buffer_reference(ws,
00196 &cell->constants[shader].buffer,
00197 buf->buffer);
00198 cell->constants[shader].size = buf->size;
00199
00200 cell->dirty |= CELL_NEW_CONSTANTS;
00201 }
00202
00203
00204 void
00205 cell_init_shader_functions(struct cell_context *cell)
00206 {
00207 cell->pipe.create_fs_state = cell_create_fs_state;
00208 cell->pipe.bind_fs_state = cell_bind_fs_state;
00209 cell->pipe.delete_fs_state = cell_delete_fs_state;
00210
00211 cell->pipe.create_vs_state = cell_create_vs_state;
00212 cell->pipe.bind_vs_state = cell_bind_vs_state;
00213 cell->pipe.delete_vs_state = cell_delete_vs_state;
00214
00215 cell->pipe.set_constant_buffer = cell_set_constant_buffer;
00216 }