163529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson/*
263529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com>
3cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák * Copyright 2009 Marek Olšák <maraeo@gmail.com>
463529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson *
563529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * Permission is hereby granted, free of charge, to any person obtaining a
663529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * copy of this software and associated documentation files (the "Software"),
763529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * to deal in the Software without restriction, including without limitation
863529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * on the rights to use, copy, modify, merge, publish, distribute, sub
963529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * license, and/or sell copies of the Software, and to permit persons to whom
1063529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * the Software is furnished to do so, subject to the following conditions:
1163529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson *
1263529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * The above copyright notice and this permission notice (including the next
1363529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * paragraph) shall be included in all copies or substantial portions of the
1463529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * Software.
1563529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson *
1663529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1763529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1863529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1963529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
2063529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2163529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2263529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson * USE OR OTHER DEALINGS IN THE SOFTWARE. */
2363529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson
24622858884fc5923c9e7a0c1bb0e80b53f0acb5a7Joakim Sindholt#include "r300_vs.h"
2563529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson
26188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle#include "r300_context.h"
27cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák#include "r300_screen.h"
28188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle#include "r300_tgsi_to_rc.h"
29cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák#include "r300_reg.h"
3063529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson
31188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle#include "tgsi/tgsi_dump.h"
32188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle#include "tgsi/tgsi_parse.h"
336eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák#include "tgsi/tgsi_ureg.h"
347cd535b47805cc086783cc4aa857292b5986672eCorbin Simpson
351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "compiler/radeon_compiler.h"
36a738d2b4c2979d7d54064f2ad08da401b28a473bCorbin Simpson
37cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák/* Convert info about VS output semantics into r300_shader_semantics. */
38cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšákstatic void r300_shader_read_vs_outputs(
395ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšák    struct r300_context *r300,
40cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák    struct tgsi_shader_info* info,
41cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák    struct r300_shader_semantics* vs_outputs)
42cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák{
43cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák    int i;
44cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák    unsigned index;
45cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák
46cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák    r300_shader_semantics_reset(vs_outputs);
47cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák
48cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák    for (i = 0; i < info->num_outputs; i++) {
49cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák        index = info->output_semantic_index[i];
50cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák
51cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák        switch (info->output_semantic_name[i]) {
52cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák            case TGSI_SEMANTIC_POSITION:
53cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                assert(index == 0);
54cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                vs_outputs->pos = i;
55cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                break;
56cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák
57cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák            case TGSI_SEMANTIC_PSIZE:
58cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                assert(index == 0);
59cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                vs_outputs->psize = i;
60cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                break;
61cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák
62cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák            case TGSI_SEMANTIC_COLOR:
6370f8aaa0c30c640d0cce7faea9402b4e53bbfff0Vinson Lee                assert(index < ATTR_COLOR_COUNT);
64cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                vs_outputs->color[index] = i;
65cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                break;
66cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák
67cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák            case TGSI_SEMANTIC_BCOLOR:
6870f8aaa0c30c640d0cce7faea9402b4e53bbfff0Vinson Lee                assert(index < ATTR_COLOR_COUNT);
69cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                vs_outputs->bcolor[index] = i;
70cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                break;
71cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák
72cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák            case TGSI_SEMANTIC_GENERIC:
7370f8aaa0c30c640d0cce7faea9402b4e53bbfff0Vinson Lee                assert(index < ATTR_GENERIC_COUNT);
74cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                vs_outputs->generic[index] = i;
75cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                break;
76cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák
77cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák            case TGSI_SEMANTIC_FOG:
78cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                assert(index == 0);
79cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                vs_outputs->fog = i;
80cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák                break;
81cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák
82429f0e3b37e33a33289f8488369474b20bfd5247Roland Scheidegger            case TGSI_SEMANTIC_EDGEFLAG:
83429f0e3b37e33a33289f8488369474b20bfd5247Roland Scheidegger                assert(index == 0);
84146879284c6b844f35afe3a3ef3330726afbe8acMarek Olšák                fprintf(stderr, "r300 VP: cannot handle edgeflag output.\n");
85429f0e3b37e33a33289f8488369474b20bfd5247Roland Scheidegger                break;
86146879284c6b844f35afe3a3ef3330726afbe8acMarek Olšák
875ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšák            case TGSI_SEMANTIC_CLIPVERTEX:
885ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšák                assert(index == 0);
895ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšák                /* Draw does clip vertex for us. */
905ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšák                if (r300->screen->caps.has_tcl) {
915ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšák                    fprintf(stderr, "r300 VP: cannot handle clip vertex output.\n");
925ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšák                }
935ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšák                break;
945ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšák
95cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák            default:
96146879284c6b844f35afe3a3ef3330726afbe8acMarek Olšák                fprintf(stderr, "r300 VP: unknown vertex output semantic: %i.\n",
97146879284c6b844f35afe3a3ef3330726afbe8acMarek Olšák                        info->output_semantic_name[i]);
98cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák        }
99cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák    }
1004f541db80c5ffff8932679a389a6043105f0b1beMarek Olšák
1014f541db80c5ffff8932679a389a6043105f0b1beMarek Olšák    /* WPOS is a straight copy of POSITION and it's always emitted. */
1024f541db80c5ffff8932679a389a6043105f0b1beMarek Olšák    vs_outputs->wpos = i;
103cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák}
104cb90235135ef7c657053657f3bdfbda7ca70d708Marek Olšák
105188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnlestatic void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
106233c6fb694ebd946ae76cb48701adf4d2086b1c1Corbin Simpson{
107188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    struct r300_vertex_shader * vs = c->UserData;
108af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    struct r300_shader_semantics* outputs = &vs->outputs;
109233c6fb694ebd946ae76cb48701adf4d2086b1c1Corbin Simpson    struct tgsi_shader_info* info = &vs->info;
110af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    int i, reg = 0;
1116f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák    boolean any_bcolor_used = outputs->bcolor[0] != ATTR_UNUSED ||
1126f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák                              outputs->bcolor[1] != ATTR_UNUSED;
113233c6fb694ebd946ae76cb48701adf4d2086b1c1Corbin Simpson
114188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    /* Fill in the input mapping */
115188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    for (i = 0; i < info->num_inputs; i++)
116188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle        c->code->inputs[i] = i;
117188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle
118af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    /* Position. */
119af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    if (outputs->pos != ATTR_UNUSED) {
120af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák        c->code->outputs[outputs->pos] = reg++;
121af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    } else {
122af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák        assert(0);
123233c6fb694ebd946ae76cb48701adf4d2086b1c1Corbin Simpson    }
12445435abcb967931c79aba1714ae797a1c5dc075eCorbin Simpson
125af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    /* Point size. */
126af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    if (outputs->psize != ATTR_UNUSED) {
127af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák        c->code->outputs[outputs->psize] = reg++;
128af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    }
129188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle
1306f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák    /* If we're writing back facing colors we need to send
1316f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák     * four colors to make front/back face colors selection work.
1326f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák     * If the vertex program doesn't write all 4 colors, lets
1336f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák     * pretend it does by skipping output index reg so the colors
1346f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák     * get written into appropriate output vectors.
1356f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák     */
1366f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák
137af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    /* Colors. */
138af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
139af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák        if (outputs->color[i] != ATTR_UNUSED) {
140af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák            c->code->outputs[outputs->color[i]] = reg++;
141b62d339301f32d29c0a0fdaba2a0e192bff42c23Marek Olšák        } else if (any_bcolor_used ||
142b62d339301f32d29c0a0fdaba2a0e192bff42c23Marek Olšák                   outputs->color[1] != ATTR_UNUSED) {
1436f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák            reg++;
144af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák        }
145af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    }
146188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle
1476f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák    /* Back-face colors. */
1486f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
1496f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák        if (outputs->bcolor[i] != ATTR_UNUSED) {
1506f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák            c->code->outputs[outputs->bcolor[i]] = reg++;
1516f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák        } else if (any_bcolor_used) {
1526f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák            reg++;
1536f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák        }
1546f498a7eff26dc055c0a1f75ce3102aa4a1a0141Marek Olšák    }
155188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle
156af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    /* Texture coordinates. */
157af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
158af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák        if (outputs->generic[i] != ATTR_UNUSED) {
159af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák            c->code->outputs[outputs->generic[i]] = reg++;
16063529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson        }
16163529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson    }
16263529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson
163af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    /* Fog coordinates. */
164af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    if (outputs->fog != ATTR_UNUSED) {
165af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák        c->code->outputs[outputs->fog] = reg++;
166af3dea36603687067197c22747537eaeb6c4ad2bMarek Olšák    }
167bf60eb3fec844a7c3793aba0c70da56b74a17344Marek Olšák
168bf60eb3fec844a7c3793aba0c70da56b74a17344Marek Olšák    /* WPOS. */
16968e720e12d51cf6d5237467a74af8c56b021acb7Marek Olšák    c->code->outputs[outputs->wpos] = reg++;
170bf60eb3fec844a7c3793aba0c70da56b74a17344Marek Olšák}
171bf60eb3fec844a7c3793aba0c70da56b74a17344Marek Olšák
1725ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšákvoid r300_init_vs_outputs(struct r300_context *r300,
1735ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšák                          struct r300_vertex_shader *vs)
1747d602b3651d4be18a207d3089fd3aa14eaffe441Marek Olšák{
1757d602b3651d4be18a207d3089fd3aa14eaffe441Marek Olšák    tgsi_scan_shader(vs->state.tokens, &vs->info);
1765ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšák    r300_shader_read_vs_outputs(r300, &vs->info, &vs->outputs);
1777d602b3651d4be18a207d3089fd3aa14eaffe441Marek Olšák}
1787d602b3651d4be18a207d3089fd3aa14eaffe441Marek Olšák
1796eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšákstatic void r300_dummy_vertex_shader(
1806eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák    struct r300_context* r300,
1816eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák    struct r300_vertex_shader* shader)
182bf60eb3fec844a7c3793aba0c70da56b74a17344Marek Olšák{
1836eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák    struct ureg_program *ureg;
1846eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák    struct ureg_dst dst;
1856eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák    struct ureg_src imm;
186bf60eb3fec844a7c3793aba0c70da56b74a17344Marek Olšák
1876eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák    /* Make a simple vertex shader which outputs (0, 0, 0, 1),
1886eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák     * effectively rendering nothing. */
1896eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák    ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
1906eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák    dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
1916eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák    imm = ureg_imm4f(ureg, 0, 0, 0, 1);
1926eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák
1936eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák    ureg_MOV(ureg, dst, imm);
1946eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák    ureg_END(ureg);
1956eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák
1967d602b3651d4be18a207d3089fd3aa14eaffe441Marek Olšák    shader->state.tokens = tgsi_dup_tokens(ureg_finalize(ureg));
1977d602b3651d4be18a207d3089fd3aa14eaffe441Marek Olšák    ureg_destroy(ureg);
1986eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák
1996eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák    shader->dummy = TRUE;
2005ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšák    r300_init_vs_outputs(r300, shader);
201f86ac27bf9203fdd9b7110dc843263307f475a99Marek Olšák    r300_translate_vertex_shader(r300, shader);
202f86ac27bf9203fdd9b7110dc843263307f475a99Marek Olšák}
203f86ac27bf9203fdd9b7110dc843263307f475a99Marek Olšák
204f86ac27bf9203fdd9b7110dc843263307f475a99Marek Olšákvoid r300_translate_vertex_shader(struct r300_context *r300,
205f86ac27bf9203fdd9b7110dc843263307f475a99Marek Olšák                                  struct r300_vertex_shader *vs)
206188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle{
207188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    struct r300_vertex_program_compiler compiler;
208188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    struct tgsi_to_rc ttr;
209abae06ac85349a30996257f29f9c52c3f687d35dMarek Olšák    unsigned i;
21084d76607ec0e43edd7dd28d1d5b6a538fd087434Corbin Simpson
211188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    /* Setup the compiler */
212ece8490bb5fbee10bbe8d186bdc5e13f85e22df4Marek Olšák    memset(&compiler, 0, sizeof(compiler));
213188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    rc_init(&compiler.Base);
214188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle
215f822cc22f223a0a4f9cf1cdd5871780e5df11d67Tom Stellard    DBG_ON(r300, DBG_VP) ? compiler.Base.Debug |= RC_DBG_LOG : 0;
216f822cc22f223a0a4f9cf1cdd5871780e5df11d67Tom Stellard    DBG_ON(r300, DBG_P_STAT) ? compiler.Base.Debug |= RC_DBG_STATS : 0;
217188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    compiler.code = &vs->code;
218188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    compiler.UserData = vs;
2195c067a63040cc66f0320f30482529a4ff1bd3811Marek Olšák    compiler.Base.is_r500 = r300->screen->caps.is_r500;
220cfc461fca6ad5656f58c48803d13052537063316Marek Olšák    compiler.Base.disable_optimizations = DBG_ON(r300, DBG_NO_OPT);
221f46fd041369a1c2c188cbd65918c900900724d37Marek Olšák    compiler.Base.has_half_swizzles = FALSE;
22263432ecfce5415fbf07f1781ec77b5ea3efff599Tom Stellard    compiler.Base.has_presub = FALSE;
223e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard    compiler.Base.has_omod = FALSE;
2245c067a63040cc66f0320f30482529a4ff1bd3811Marek Olšák    compiler.Base.max_temp_regs = 32;
2253ba562e62af0db0318ecebb356d5a3c514f4d1c8Marek Olšák    compiler.Base.max_constants = 256;
226313e95f0c792580f6051fedb67e65838405c88f8Marek Olšák    compiler.Base.max_alu_insts = r300->screen->caps.is_r500 ? 1024 : 256;
227188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle
228f822cc22f223a0a4f9cf1cdd5871780e5df11d67Tom Stellard    if (compiler.Base.Debug & RC_DBG_LOG) {
22929b7d26401a77ee4f772233b003d942bba59bb63Marek Olšák        DBG(r300, DBG_VP, "r300: Initial vertex program\n");
230f86ac27bf9203fdd9b7110dc843263307f475a99Marek Olšák        tgsi_dump(vs->state.tokens, 0);
231188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    }
232188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle
233188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    /* Translate TGSI to our internal representation */
234188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    ttr.compiler = &compiler.Base;
235188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    ttr.info = &vs->info;
236229db2b8ade33571e4cece1d838234895db220c2Corbin Simpson    ttr.use_half_swizzles = FALSE;
237188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle
238f86ac27bf9203fdd9b7110dc843263307f475a99Marek Olšák    r300_tgsi_to_rc(&ttr, vs->state.tokens);
239188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle
240ffcdd49c69811b9f768c0b32acef6527d5626a6eMarek Olšák    if (ttr.error) {
241ffcdd49c69811b9f768c0b32acef6527d5626a6eMarek Olšák        fprintf(stderr, "r300 VP: Cannot translate a shader. "
242ffcdd49c69811b9f768c0b32acef6527d5626a6eMarek Olšák                "Using a dummy shader instead.\n");
243ffcdd49c69811b9f768c0b32acef6527d5626a6eMarek Olšák        r300_dummy_vertex_shader(r300, vs);
244ffcdd49c69811b9f768c0b32acef6527d5626a6eMarek Olšák        return;
245ffcdd49c69811b9f768c0b32acef6527d5626a6eMarek Olšák    }
246ffcdd49c69811b9f768c0b32acef6527d5626a6eMarek Olšák
247a60a5b850bde94c9c0c21f07800ed57436525998Marek Olšák    if (compiler.Base.Program.Constants.Count > 200) {
248a60a5b850bde94c9c0c21f07800ed57436525998Marek Olšák        compiler.Base.remove_unused_constants = TRUE;
249a60a5b850bde94c9c0c21f07800ed57436525998Marek Olšák    }
250a60a5b850bde94c9c0c21f07800ed57436525998Marek Olšák
25168e720e12d51cf6d5237467a74af8c56b021acb7Marek Olšák    compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs + 1));
252188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
253188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle
254bf60eb3fec844a7c3793aba0c70da56b74a17344Marek Olšák    /* Insert the WPOS output. */
25568e720e12d51cf6d5237467a74af8c56b021acb7Marek Olšák    rc_copy_output(&compiler.Base, 0, vs->outputs.wpos);
256bf60eb3fec844a7c3793aba0c70da56b74a17344Marek Olšák
257188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    /* Invoke the compiler */
258188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    r3xx_compile_vertex_program(&compiler);
259188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    if (compiler.Base.Error) {
260abae06ac85349a30996257f29f9c52c3f687d35dMarek Olšák        fprintf(stderr, "r300 VP: Compiler error:\n%sUsing a dummy shader"
261abae06ac85349a30996257f29f9c52c3f687d35dMarek Olšák                " instead.\n", compiler.Base.ErrorMsg);
2626eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák
2636eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák        if (vs->dummy) {
2646eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák            fprintf(stderr, "r300 VP: Cannot compile the dummy shader! "
2656eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák                    "Giving up...\n");
2666eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák            abort();
2676eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák        }
268d72f1c3b80f84e8bceb414439b679b3fe71ec5b9Marek Olšák
269d72f1c3b80f84e8bceb414439b679b3fe71ec5b9Marek Olšák        rc_destroy(&compiler.Base);
2706eae8e4482b6d5e3d46e10473b05f16381736a5aMarek Olšák        r300_dummy_vertex_shader(r300, vs);
271d72f1c3b80f84e8bceb414439b679b3fe71ec5b9Marek Olšák        return;
272188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    }
27307961bb05e5ba05205b9f53834863664f1023870Corbin Simpson
274abc2f29dd2baa9c8aa672f07a1500e579364ab29Marek Olšák    /* Initialize numbers of constants for each type. */
275abae06ac85349a30996257f29f9c52c3f687d35dMarek Olšák    vs->externals_count = 0;
276abae06ac85349a30996257f29f9c52c3f687d35dMarek Olšák    for (i = 0;
277abae06ac85349a30996257f29f9c52c3f687d35dMarek Olšák         i < vs->code.constants.Count &&
278abae06ac85349a30996257f29f9c52c3f687d35dMarek Olšák         vs->code.constants.Constants[i].Type == RC_CONSTANT_EXTERNAL; i++) {
279abae06ac85349a30996257f29f9c52c3f687d35dMarek Olšák        vs->externals_count = i+1;
280abae06ac85349a30996257f29f9c52c3f687d35dMarek Olšák    }
281abae06ac85349a30996257f29f9c52c3f687d35dMarek Olšák    for (; i < vs->code.constants.Count; i++) {
282abae06ac85349a30996257f29f9c52c3f687d35dMarek Olšák        assert(vs->code.constants.Constants[i].Type == RC_CONSTANT_IMMEDIATE);
283abae06ac85349a30996257f29f9c52c3f687d35dMarek Olšák    }
284abc2f29dd2baa9c8aa672f07a1500e579364ab29Marek Olšák    vs->immediates_count = vs->code.constants.Count - vs->externals_count;
285abc2f29dd2baa9c8aa672f07a1500e579364ab29Marek Olšák
28607961bb05e5ba05205b9f53834863664f1023870Corbin Simpson    /* And, finally... */
287188f8c679254f193cdcfcd4ef338f3c8c5e1146dNicolai Hähnle    rc_destroy(&compiler.Base);
28863529c731a090c5e41c1224ca79b544243a1e570Corbin Simpson}
289