gallium: refactor/replace p_util.h with util/u_memory.h and util/u_math.h
[mesa.git] / src / gallium / drivers / cell / ppu / cell_state_emit.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 "util/u_memory.h"
29 #include "cell_context.h"
30 #include "cell_state.h"
31 #include "cell_state_emit.h"
32 #include "cell_state_per_fragment.h"
33 #include "cell_batch.h"
34 #include "cell_texture.h"
35 #include "draw/draw_context.h"
36 #include "draw/draw_private.h"
37
38
39 static void
40 emit_state_cmd(struct cell_context *cell, uint cmd,
41 const void *state, uint state_size)
42 {
43 uint64_t *dst = (uint64_t *)
44 cell_batch_alloc(cell, ROUNDUP8(sizeof(uint64_t) + state_size));
45 *dst = cmd;
46 memcpy(dst + 1, state, state_size);
47 }
48
49
50
51 void
52 cell_emit_state(struct cell_context *cell)
53 {
54 if (cell->dirty & (CELL_NEW_FRAMEBUFFER | CELL_NEW_BLEND)) {
55 struct cell_command_logicop logicop;
56
57 if (cell->logic_op.store != NULL) {
58 spe_release_func(& cell->logic_op);
59 }
60
61 cell_generate_logic_op(& cell->logic_op,
62 & cell->blend->base,
63 cell->framebuffer.cbufs[0]);
64
65 logicop.base = (intptr_t) cell->logic_op.store;
66 logicop.size = 64 * 4;
67 emit_state_cmd(cell, CELL_CMD_STATE_LOGICOP, &logicop,
68 sizeof(logicop));
69 }
70
71 if (cell->dirty & CELL_NEW_FRAMEBUFFER) {
72 struct pipe_surface *cbuf = cell->framebuffer.cbufs[0];
73 struct pipe_surface *zbuf = cell->framebuffer.zsbuf;
74 struct cell_command_framebuffer *fb
75 = cell_batch_alloc(cell, sizeof(*fb));
76 fb->opcode = CELL_CMD_STATE_FRAMEBUFFER;
77 fb->color_start = cell->cbuf_map[0];
78 fb->color_format = cbuf->format;
79 fb->depth_start = cell->zsbuf_map;
80 fb->depth_format = zbuf ? zbuf->format : PIPE_FORMAT_NONE;
81 fb->width = cell->framebuffer.width;
82 fb->height = cell->framebuffer.height;
83 }
84
85 if (cell->dirty & CELL_NEW_BLEND) {
86 struct cell_command_blend blend;
87
88 if (cell->blend != NULL) {
89 blend.base = (intptr_t) cell->blend->code.store;
90 blend.size = (char *) cell->blend->code.csr
91 - (char *) cell->blend->code.store;
92 blend.read_fb = TRUE;
93 } else {
94 blend.base = 0;
95 blend.size = 0;
96 blend.read_fb = FALSE;
97 }
98
99 emit_state_cmd(cell, CELL_CMD_STATE_BLEND, &blend, sizeof(blend));
100 }
101
102 if (cell->dirty & CELL_NEW_DEPTH_STENCIL) {
103 struct cell_command_depth_stencil_alpha_test dsat;
104
105
106 if (cell->depth_stencil != NULL) {
107 dsat.base = (intptr_t) cell->depth_stencil->code.store;
108 dsat.size = (char *) cell->depth_stencil->code.csr
109 - (char *) cell->depth_stencil->code.store;
110 dsat.read_depth = TRUE;
111 dsat.read_stencil = FALSE;
112 } else {
113 dsat.base = 0;
114 dsat.size = 0;
115 dsat.read_depth = FALSE;
116 dsat.read_stencil = FALSE;
117 }
118
119 emit_state_cmd(cell, CELL_CMD_STATE_DEPTH_STENCIL, &dsat,
120 sizeof(dsat));
121 }
122
123 if (cell->dirty & CELL_NEW_SAMPLER) {
124 uint i;
125 for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
126 if (cell->sampler[i]) {
127 struct cell_command_sampler *sampler
128 = cell_batch_alloc(cell, sizeof(*sampler));
129 sampler->opcode = CELL_CMD_STATE_SAMPLER;
130 sampler->unit = i;
131 sampler->state = *cell->sampler[i];
132 }
133 }
134 }
135
136 if (cell->dirty & CELL_NEW_TEXTURE) {
137 uint i;
138 for (i = 0;i < CELL_MAX_SAMPLERS; i++) {
139 struct cell_command_texture *texture
140 = cell_batch_alloc(cell, sizeof(*texture));
141 texture->opcode = CELL_CMD_STATE_TEXTURE;
142 texture->unit = i;
143 if (cell->texture[i]) {
144 texture->start = cell->texture[i]->tiled_data;
145 texture->width = cell->texture[i]->base.width[0];
146 texture->height = cell->texture[i]->base.height[0];
147 }
148 else {
149 texture->start = NULL;
150 texture->width = 1;
151 texture->height = 1;
152 }
153 }
154 }
155
156 if (cell->dirty & CELL_NEW_VERTEX_INFO) {
157 emit_state_cmd(cell, CELL_CMD_STATE_VERTEX_INFO,
158 &cell->vertex_info, sizeof(struct vertex_info));
159 }
160
161 if (cell->dirty & CELL_NEW_VS) {
162 const struct draw_context *const draw = cell->draw;
163 struct cell_shader_info info;
164
165 info.num_outputs = draw->num_vs_outputs;
166 info.declarations = (uintptr_t) draw->machine.Declarations;
167 info.num_declarations = draw->machine.NumDeclarations;
168 info.instructions = (uintptr_t) draw->machine.Instructions;
169 info.num_instructions = draw->machine.NumInstructions;
170 info.immediates = (uintptr_t) draw->machine.Imms;
171 info.num_immediates = draw->machine.ImmLimit / 4;
172
173 emit_state_cmd(cell, CELL_CMD_STATE_BIND_VS,
174 & info, sizeof(info));
175 }
176 }