f8a18658a98c30c7bbf447e3fd1c8b3796815d34
[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_texture.h"
34 #include "r600_context.h"
35 #include "r600d.h"
36
37 static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
38 {
39 struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
40 struct r600_shader *rshader = &rpshader->shader;
41 struct radeon_state *state;
42 unsigned i, tmp;
43
44 rpshader->state = radeon_state_decref(rpshader->state);
45 state = radeon_state(rscreen->rw, R600_VS_SHADER_TYPE, R600_VS_SHADER);
46 if (state == NULL)
47 return -ENOMEM;
48 for (i = 0; i < rshader->noutput; i += 4) {
49 tmp = rshader->output[i].sid;
50 tmp |= rshader->output[i + 1].sid << 8;
51 tmp |= rshader->output[i + 2].sid << 16;
52 tmp |= rshader->output[i + 3].sid << 24;
53 state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i / 4] = tmp;
54 }
55 state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 1);
56 state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->ngpr);
57 rpshader->state = state;
58 rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
59 rpshader->state->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo);
60 rpshader->state->nbo = 2;
61 rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT;
62 return radeon_state_pm4(state);
63 }
64
65 static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
66 {
67 struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
68 struct r600_shader *rshader = &rpshader->shader;
69 struct radeon_state *state;
70 unsigned i, tmp;
71
72 rpshader->state = radeon_state_decref(rpshader->state);
73 state = radeon_state(rscreen->rw, R600_PS_SHADER_TYPE, R600_PS_SHADER);
74 if (state == NULL)
75 return -ENOMEM;
76 for (i = 0; i < rshader->ninput; i++) {
77 tmp = S_028644_SEMANTIC(rshader->input[i].sid);
78 tmp |= S_028644_SEL_CENTROID(1);
79 tmp |= S_028644_FLAT_SHADE(rshader->flat_shade);
80 state->states[R600_PS_SHADER__SPI_PS_INPUT_CNTL_0 + i] = tmp;
81 }
82 state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_0] = S_0286CC_NUM_INTERP(rshader->ninput) |
83 S_0286CC_PERSP_GRADIENT_ENA(1);
84 state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_1] = 0x00000000;
85 state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->ngpr);
86 state->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = 0x00000002;
87 rpshader->state = state;
88 rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
89 rpshader->state->nbo = 1;
90 rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT;
91 return radeon_state_pm4(state);
92 }
93
94 static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
95 {
96 struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
97 struct r600_context *rctx = (struct r600_context*)ctx;
98 struct r600_shader *rshader = &rpshader->shader;
99 int r;
100
101 /* copy new shader */
102 radeon_bo_decref(rscreen->rw, rpshader->bo);
103 rpshader->bo = NULL;
104 rpshader->bo = radeon_bo(rscreen->rw, 0, rshader->ndw * 4,
105 4096, NULL);
106 if (rpshader->bo == NULL) {
107 return -ENOMEM;
108 }
109 radeon_bo_map(rscreen->rw, rpshader->bo);
110 memcpy(rpshader->bo->data, rshader->bcode, rshader->ndw * 4);
111 radeon_bo_unmap(rscreen->rw, rpshader->bo);
112 /* build state */
113 rshader->flat_shade = rctx->flat_shade;
114 switch (rpshader->type) {
115 case C_PROGRAM_TYPE_VS:
116 r = r600_pipe_shader_vs(ctx, rpshader);
117 break;
118 case C_PROGRAM_TYPE_FS:
119 r = r600_pipe_shader_ps(ctx, rpshader);
120 break;
121 default:
122 r = -EINVAL;
123 break;
124 }
125 return r;
126 }
127
128 struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, unsigned type, const struct tgsi_token *tokens)
129 {
130 struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader);
131 struct r600_shader *rshader = &rpshader->shader;
132 int r;
133
134 if (rpshader == NULL)
135 return NULL;
136 rpshader->type = type;
137 c_list_init(&rshader->nodes);
138 fprintf(stderr, "<<\n");
139 tgsi_dump(tokens, 0);
140 fprintf(stderr, "--------------------------------------------------------------\n");
141 r = c_shader_from_tgsi(&rshader->cshader, type, tokens);
142 if (r) {
143 r600_pipe_shader_destroy(ctx, rpshader);
144 fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
145 return NULL;
146 }
147 r = r600_shader_insert_fetch(&rshader->cshader);
148 if (r) {
149 r600_pipe_shader_destroy(ctx, rpshader);
150 fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
151 return NULL;
152 }
153 r = c_shader_build_dominator_tree(&rshader->cshader);
154 if (r) {
155 r600_pipe_shader_destroy(ctx, rpshader);
156 fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
157 return NULL;
158 }
159 c_shader_dump(&rshader->cshader);
160 r = r700_shader_translate(rshader);
161 if (r) {
162 r600_pipe_shader_destroy(ctx, rpshader);
163 fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
164 return NULL;
165 }
166 #if 1
167 #if 0
168 fprintf(stderr, "--------------------------------------------------------------\n");
169 for (int i = 0; i < rshader->ndw; i++) {
170 fprintf(stderr, "0x%08X\n", rshader->bcode[i]);
171 }
172 #endif
173 fprintf(stderr, ">>\n\n");
174 #endif
175 return rpshader;
176 }
177
178 void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
179 {
180 struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
181
182 if (rpshader == NULL)
183 return;
184 radeon_bo_decref(rscreen->rw, rpshader->bo);
185 rpshader->bo = NULL;
186 r600_shader_cleanup(&rpshader->shader);
187 FREE(rpshader);
188 }
189
190 int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
191 {
192 struct r600_context *rctx = (struct r600_context*)ctx;
193 struct r600_shader *rshader;
194 enum pipe_format resource_format[160];
195 unsigned i, nresources = 0;
196 int r;
197
198 if (rpshader == NULL)
199 return -EINVAL;
200 rshader = &rpshader->shader;
201 switch (rpshader->type) {
202 case C_PROGRAM_TYPE_VS:
203 for (i = 0; i < rctx->nvertex_element; i++) {
204 resource_format[nresources++] = rctx->vertex_element[i].src_format;
205 }
206 break;
207 default:
208 break;
209 }
210 /* there should be enough input */
211 if (nresources < rshader->nresource)
212 return -EINVAL;
213 /* FIXME compare resources */
214 r = r600_shader_update(rshader, resource_format);
215 if (r)
216 return r;
217 return r600_pipe_shader(ctx, rpshader);
218 }