r600g: Remove unnecessary headers.
[mesa.git] / src / gallium / drivers / r600 / r600_shader.c
1 /*
2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Jerome Glisse
25 */
26 #include <stdio.h>
27 #include <errno.h>
28 #include <util/u_inlines.h>
29 #include <util/u_format.h>
30 #include <util/u_memory.h>
31 #include <tgsi/tgsi_dump.h>
32 #include "r600_screen.h"
33 #include "r600_context.h"
34 #include "r600d.h"
35
36 static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
37 {
38 struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
39 struct r600_shader *rshader = &rpshader->shader;
40 struct radeon_state *state;
41 unsigned i, tmp;
42
43 rpshader->state = radeon_state_decref(rpshader->state);
44 state = radeon_state(rscreen->rw, R600_VS_SHADER_TYPE, R600_VS_SHADER);
45 if (state == NULL)
46 return -ENOMEM;
47 for (i = 0; i < rshader->noutput; i += 4) {
48 tmp = rshader->output[i].sid;
49 tmp |= rshader->output[i + 1].sid << 8;
50 tmp |= rshader->output[i + 2].sid << 16;
51 tmp |= rshader->output[i + 3].sid << 24;
52 state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i / 4] = tmp;
53 }
54 state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 1);
55 state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->ngpr);
56 rpshader->state = state;
57 rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
58 rpshader->state->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo);
59 rpshader->state->nbo = 2;
60 rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT;
61 return radeon_state_pm4(state);
62 }
63
64 static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
65 {
66 struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
67 struct r600_shader *rshader = &rpshader->shader;
68 struct radeon_state *state;
69 unsigned i, tmp;
70
71 rpshader->state = radeon_state_decref(rpshader->state);
72 state = radeon_state(rscreen->rw, R600_PS_SHADER_TYPE, R600_PS_SHADER);
73 if (state == NULL)
74 return -ENOMEM;
75 for (i = 0; i < rshader->ninput; i++) {
76 tmp = S_028644_SEMANTIC(rshader->input[i].sid);
77 tmp |= S_028644_SEL_CENTROID(1);
78 tmp |= S_028644_FLAT_SHADE(rshader->flat_shade);
79 state->states[R600_PS_SHADER__SPI_PS_INPUT_CNTL_0 + i] = tmp;
80 }
81 state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_0] = S_0286CC_NUM_INTERP(rshader->ninput) |
82 S_0286CC_PERSP_GRADIENT_ENA(1);
83 state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_1] = 0x00000000;
84 state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->ngpr);
85 state->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = 0x00000002;
86 rpshader->state = state;
87 rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
88 rpshader->state->nbo = 1;
89 rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT;
90 return radeon_state_pm4(state);
91 }
92
93 static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
94 {
95 struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
96 struct r600_context *rctx = (struct r600_context*)ctx;
97 struct r600_shader *rshader = &rpshader->shader;
98 int r;
99
100 /* copy new shader */
101 radeon_bo_decref(rscreen->rw, rpshader->bo);
102 rpshader->bo = NULL;
103 rpshader->bo = radeon_bo(rscreen->rw, 0, rshader->ndw * 4,
104 4096, NULL);
105 if (rpshader->bo == NULL) {
106 return -ENOMEM;
107 }
108 radeon_bo_map(rscreen->rw, rpshader->bo);
109 memcpy(rpshader->bo->data, rshader->bcode, rshader->ndw * 4);
110 radeon_bo_unmap(rscreen->rw, rpshader->bo);
111 /* build state */
112 rshader->flat_shade = rctx->flat_shade;
113 switch (rpshader->type) {
114 case C_PROGRAM_TYPE_VS:
115 r = r600_pipe_shader_vs(ctx, rpshader);
116 break;
117 case C_PROGRAM_TYPE_FS:
118 r = r600_pipe_shader_ps(ctx, rpshader);
119 break;
120 default:
121 r = -EINVAL;
122 break;
123 }
124 return r;
125 }
126
127 struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, unsigned type, const struct tgsi_token *tokens)
128 {
129 struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader);
130 struct r600_shader *rshader = &rpshader->shader;
131 int r;
132
133 if (rpshader == NULL)
134 return NULL;
135 rpshader->type = type;
136 c_list_init(&rshader->nodes);
137 fprintf(stderr, "<<\n");
138 tgsi_dump(tokens, 0);
139 fprintf(stderr, "--------------------------------------------------------------\n");
140 r = c_shader_from_tgsi(&rshader->cshader, type, tokens);
141 if (r) {
142 r600_pipe_shader_destroy(ctx, rpshader);
143 fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
144 return NULL;
145 }
146 r = r600_shader_insert_fetch(&rshader->cshader);
147 if (r) {
148 r600_pipe_shader_destroy(ctx, rpshader);
149 fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
150 return NULL;
151 }
152 r = c_shader_build_dominator_tree(&rshader->cshader);
153 if (r) {
154 r600_pipe_shader_destroy(ctx, rpshader);
155 fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
156 return NULL;
157 }
158 c_shader_dump(&rshader->cshader);
159 r = r700_shader_translate(rshader);
160 if (r) {
161 r600_pipe_shader_destroy(ctx, rpshader);
162 fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
163 return NULL;
164 }
165 #if 1
166 #if 0
167 fprintf(stderr, "--------------------------------------------------------------\n");
168 for (int i = 0; i < rshader->ndw; i++) {
169 fprintf(stderr, "0x%08X\n", rshader->bcode[i]);
170 }
171 #endif
172 fprintf(stderr, ">>\n\n");
173 #endif
174 return rpshader;
175 }
176
177 void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
178 {
179 struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
180
181 if (rpshader == NULL)
182 return;
183 radeon_bo_decref(rscreen->rw, rpshader->bo);
184 rpshader->bo = NULL;
185 r600_shader_cleanup(&rpshader->shader);
186 FREE(rpshader);
187 }
188
189 int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
190 {
191 struct r600_context *rctx = (struct r600_context*)ctx;
192 struct r600_shader *rshader;
193 enum pipe_format resource_format[160];
194 unsigned i, nresources = 0;
195 int r;
196
197 if (rpshader == NULL)
198 return -EINVAL;
199 rshader = &rpshader->shader;
200 switch (rpshader->type) {
201 case C_PROGRAM_TYPE_VS:
202 for (i = 0; i < rctx->vertex_elements->count; i++) {
203 resource_format[nresources++] = rctx->vertex_elements->elements[i].src_format;
204 }
205 break;
206 default:
207 break;
208 }
209 /* there should be enough input */
210 if (nresources < rshader->nresource)
211 return -EINVAL;
212 /* FIXME compare resources */
213 r = r600_shader_update(rshader, resource_format);
214 if (r)
215 return r;
216 return r600_pipe_shader(ctx, rpshader);
217 }