Merge branch 'mesa_7_5_branch'
[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.ImmediateFloat32[i]
71 .Float;
72 }
73 assembler->imm_count++;
74 break;
75 case TGSI_TOKEN_TYPE_INSTRUCTION:
76 if (is_r500) {
77 r5xx_fs_instruction((struct r5xx_fragment_shader*)fs,
78 assembler, &parser.FullToken.FullInstruction);
79 } else {
80 r3xx_fs_instruction((struct r3xx_fragment_shader*)fs,
81 assembler, &parser.FullToken.FullInstruction);
82 }
83 break;
84 }
85 }
86
87 debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n",
88 assembler->tex_count, assembler->color_count,
89 assembler->tex_count + assembler->color_count);
90
91 consts->count = consts->user_count + assembler->imm_count;
92 fs->uses_imms = assembler->imm_count;
93 debug_printf("r300: fs: %d total constants, "
94 "%d from user and %d from immediates\n", consts->count,
95 consts->user_count, assembler->imm_count);
96 r3xx_fs_finalize(fs, assembler);
97 if (is_r500) {
98 r5xx_fs_finalize((struct r5xx_fragment_shader*)fs, assembler);
99 }
100
101 tgsi_dump(fs->state.tokens, 0);
102 /* XXX finish r300 dumper too */
103 if (is_r500) {
104 r5xx_fs_dump((struct r5xx_fragment_shader*)fs);
105 }
106
107 tgsi_parse_free(&parser);
108 FREE(assembler);
109 }