ca8ef9990244a76c5fb1977b4d2a51c18dfaa29a
[mesa.git] / src / gallium / drivers / r300 / r300_fs.c
1 /*
2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
3 * Joakim Sindholt <opensource@zhasha.com>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23
24 #include "r300_fs.h"
25
26 void r300_translate_fragment_shader(struct r300_context* r300,
27 struct r300_fragment_shader* fs)
28 {
29 struct tgsi_parse_context parser;
30 int i;
31 boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
32 struct r300_constant_buffer* consts =
33 &r300->shader_constants[PIPE_SHADER_FRAGMENT];
34
35 struct r300_fs_asm* assembler = CALLOC_STRUCT(r300_fs_asm);
36 if (assembler == NULL) {
37 return;
38 }
39 /* Setup starting offset for immediates. */
40 assembler->imm_offset = consts->user_count;
41 /* Enable depth writes, if needed. */
42 assembler->writes_depth = fs->info.writes_z;
43
44 /* Make sure we start at the beginning of the shader. */
45 if (is_r500) {
46 ((struct r5xx_fragment_shader*)fs)->instruction_count = 0;
47 }
48
49 tgsi_parse_init(&parser, fs->state.tokens);
50
51 while (!tgsi_parse_end_of_tokens(&parser)) {
52 tgsi_parse_token(&parser);
53
54 /* This is seriously the lamest way to create fragment programs ever.
55 * I blame TGSI. */
56 switch (parser.FullToken.Token.Type) {
57 case TGSI_TOKEN_TYPE_DECLARATION:
58 /* Allocated registers sitting at the beginning
59 * of the program. */
60 r300_fs_declare(assembler, &parser.FullToken.FullDeclaration);
61 break;
62 case TGSI_TOKEN_TYPE_IMMEDIATE:
63 debug_printf("r300: Emitting immediate to constant buffer, "
64 "position %d\n",
65 assembler->imm_offset + assembler->imm_count);
66 /* I am not amused by the length of these. */
67 for (i = 0; i < 4; i++) {
68 consts->constants[assembler->imm_offset +
69 assembler->imm_count][i] =
70 parser.FullToken.FullImmediate.u[i].Float;
71 }
72 assembler->imm_count++;
73 break;
74 case TGSI_TOKEN_TYPE_INSTRUCTION:
75 if (is_r500) {
76 r5xx_fs_instruction((struct r5xx_fragment_shader*)fs,
77 assembler, &parser.FullToken.FullInstruction);
78 } else {
79 r3xx_fs_instruction((struct r3xx_fragment_shader*)fs,
80 assembler, &parser.FullToken.FullInstruction);
81 }
82 break;
83 }
84 }
85
86 debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n",
87 assembler->tex_count, assembler->color_count,
88 assembler->tex_count + assembler->color_count);
89
90 consts->count = consts->user_count + assembler->imm_count;
91 fs->uses_imms = assembler->imm_count;
92 debug_printf("r300: fs: %d total constants, "
93 "%d from user and %d from immediates\n", consts->count,
94 consts->user_count, assembler->imm_count);
95 r3xx_fs_finalize(fs, assembler);
96 if (is_r500) {
97 r5xx_fs_finalize((struct r5xx_fragment_shader*)fs, assembler);
98 }
99
100 tgsi_dump(fs->state.tokens, 0);
101 /* XXX finish r300 dumper too */
102 if (is_r500) {
103 r5xx_fs_dump((struct r5xx_fragment_shader*)fs);
104 }
105
106 tgsi_parse_free(&parser);
107 FREE(assembler);
108
109 /* And, finally... */
110 fs->translated = TRUE;
111 }