1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com>
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 Marek Olšák <maraeo@gmail.com>
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * on the rights to use, copy, modify, merge, publish, distribute, sub
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * license, and/or sell copies of the Software, and to permit persons to whom
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the Software is furnished to do so, subject to the following conditions:
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software.
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "r300_vs.h"
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "r300_context.h"
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "r300_screen.h"
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "r300_tgsi_to_rc.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "r300_reg.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_dump.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_parse.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_ureg.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "compiler/radeon_compiler.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Convert info about VS output semantics into r300_shader_semantics. */
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r300_shader_read_vs_outputs(
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct r300_context *r300,
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct tgsi_shader_info* info,
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct r300_shader_semantics* vs_outputs)
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int i;
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned index;
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    r300_shader_semantics_reset(vs_outputs);
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (i = 0; i < info->num_outputs; i++) {
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        index = info->output_semantic_index[i];
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        switch (info->output_semantic_name[i]) {
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case TGSI_SEMANTIC_POSITION:
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                assert(index == 0);
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                vs_outputs->pos = i;
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                break;
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case TGSI_SEMANTIC_PSIZE:
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                assert(index == 0);
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                vs_outputs->psize = i;
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                break;
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case TGSI_SEMANTIC_COLOR:
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                assert(index < ATTR_COLOR_COUNT);
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                vs_outputs->color[index] = i;
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                break;
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case TGSI_SEMANTIC_BCOLOR:
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                assert(index < ATTR_COLOR_COUNT);
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                vs_outputs->bcolor[index] = i;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                break;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case TGSI_SEMANTIC_GENERIC:
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                assert(index < ATTR_GENERIC_COUNT);
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                vs_outputs->generic[index] = i;
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                break;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case TGSI_SEMANTIC_FOG:
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                assert(index == 0);
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                vs_outputs->fog = i;
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                break;
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case TGSI_SEMANTIC_EDGEFLAG:
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                assert(index == 0);
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                fprintf(stderr, "r300 VP: cannot handle edgeflag output.\n");
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                break;
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case TGSI_SEMANTIC_CLIPVERTEX:
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                assert(index == 0);
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                /* Draw does clip vertex for us. */
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                if (r300->screen->caps.has_tcl) {
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    fprintf(stderr, "r300 VP: cannot handle clip vertex output.\n");
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                }
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                break;
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            default:
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                fprintf(stderr, "r300 VP: unknown vertex output semantic: %i.\n",
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        info->output_semantic_name[i]);
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* WPOS is a straight copy of POSITION and it's always emitted. */
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    vs_outputs->wpos = i;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct r300_vertex_shader * vs = c->UserData;
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct r300_shader_semantics* outputs = &vs->outputs;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct tgsi_shader_info* info = &vs->info;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int i, reg = 0;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    boolean any_bcolor_used = outputs->bcolor[0] != ATTR_UNUSED ||
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              outputs->bcolor[1] != ATTR_UNUSED;
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Fill in the input mapping */
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (i = 0; i < info->num_inputs; i++)
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        c->code->inputs[i] = i;
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Position. */
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (outputs->pos != ATTR_UNUSED) {
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        c->code->outputs[outputs->pos] = reg++;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        assert(0);
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Point size. */
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (outputs->psize != ATTR_UNUSED) {
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        c->code->outputs[outputs->psize] = reg++;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* If we're writing back facing colors we need to send
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * four colors to make front/back face colors selection work.
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * If the vertex program doesn't write all 4 colors, lets
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * pretend it does by skipping output index reg so the colors
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * get written into appropriate output vectors.
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     */
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Colors. */
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (outputs->color[i] != ATTR_UNUSED) {
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            c->code->outputs[outputs->color[i]] = reg++;
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        } else if (any_bcolor_used ||
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   outputs->color[1] != ATTR_UNUSED) {
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            reg++;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Back-face colors. */
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (outputs->bcolor[i] != ATTR_UNUSED) {
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            c->code->outputs[outputs->bcolor[i]] = reg++;
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        } else if (any_bcolor_used) {
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            reg++;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Texture coordinates. */
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (outputs->generic[i] != ATTR_UNUSED) {
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            c->code->outputs[outputs->generic[i]] = reg++;
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Fog coordinates. */
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (outputs->fog != ATTR_UNUSED) {
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        c->code->outputs[outputs->fog] = reg++;
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* WPOS. */
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    c->code->outputs[outputs->wpos] = reg++;
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r300_init_vs_outputs(struct r300_context *r300,
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          struct r300_vertex_shader *vs)
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    tgsi_scan_shader(vs->state.tokens, &vs->info);
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    r300_shader_read_vs_outputs(r300, &vs->info, &vs->outputs);
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r300_dummy_vertex_shader(
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct r300_context* r300,
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct r300_vertex_shader* shader)
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_program *ureg;
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst dst;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_src imm;
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Make a simple vertex shader which outputs (0, 0, 0, 1),
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * effectively rendering nothing. */
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    imm = ureg_imm4f(ureg, 0, 0, 0, 1);
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MOV(ureg, dst, imm);
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_END(ureg);
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    shader->state.tokens = tgsi_dup_tokens(ureg_finalize(ureg));
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_destroy(ureg);
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    shader->dummy = TRUE;
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    r300_init_vs_outputs(r300, shader);
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    r300_translate_vertex_shader(r300, shader);
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r300_translate_vertex_shader(struct r300_context *r300,
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  struct r300_vertex_shader *vs)
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct r300_vertex_program_compiler compiler;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct tgsi_to_rc ttr;
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned i;
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Setup the compiler */
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    memset(&compiler, 0, sizeof(compiler));
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rc_init(&compiler.Base);
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DBG_ON(r300, DBG_VP) ? compiler.Base.Debug |= RC_DBG_LOG : 0;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DBG_ON(r300, DBG_P_STAT) ? compiler.Base.Debug |= RC_DBG_STATS : 0;
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    compiler.code = &vs->code;
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    compiler.UserData = vs;
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    compiler.Base.is_r500 = r300->screen->caps.is_r500;
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    compiler.Base.disable_optimizations = DBG_ON(r300, DBG_NO_OPT);
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    compiler.Base.has_half_swizzles = FALSE;
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    compiler.Base.has_presub = FALSE;
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    compiler.Base.has_omod = FALSE;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    compiler.Base.max_temp_regs = 32;
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    compiler.Base.max_constants = 256;
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    compiler.Base.max_alu_insts = r300->screen->caps.is_r500 ? 1024 : 256;
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (compiler.Base.Debug & RC_DBG_LOG) {
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        DBG(r300, DBG_VP, "r300: Initial vertex program\n");
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        tgsi_dump(vs->state.tokens, 0);
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Translate TGSI to our internal representation */
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ttr.compiler = &compiler.Base;
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ttr.info = &vs->info;
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ttr.use_half_swizzles = FALSE;
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    r300_tgsi_to_rc(&ttr, vs->state.tokens);
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ttr.error) {
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        fprintf(stderr, "r300 VP: Cannot translate a shader. "
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                "Using a dummy shader instead.\n");
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        r300_dummy_vertex_shader(r300, vs);
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return;
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (compiler.Base.Program.Constants.Count > 200) {
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        compiler.Base.remove_unused_constants = TRUE;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs + 1));
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Insert the WPOS output. */
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rc_copy_output(&compiler.Base, 0, vs->outputs.wpos);
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Invoke the compiler */
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    r3xx_compile_vertex_program(&compiler);
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (compiler.Base.Error) {
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        fprintf(stderr, "r300 VP: Compiler error:\n%sUsing a dummy shader"
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                " instead.\n", compiler.Base.ErrorMsg);
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (vs->dummy) {
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fprintf(stderr, "r300 VP: Cannot compile the dummy shader! "
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    "Giving up...\n");
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            abort();
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        rc_destroy(&compiler.Base);
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        r300_dummy_vertex_shader(r300, vs);
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Initialize numbers of constants for each type. */
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    vs->externals_count = 0;
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (i = 0;
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         i < vs->code.constants.Count &&
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         vs->code.constants.Constants[i].Type == RC_CONSTANT_EXTERNAL; i++) {
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        vs->externals_count = i+1;
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (; i < vs->code.constants.Count; i++) {
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        assert(vs->code.constants.Constants[i].Type == RC_CONSTANT_IMMEDIATE);
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    vs->immediates_count = vs->code.constants.Count - vs->externals_count;
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* And, finally... */
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rc_destroy(&compiler.Base);
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
289