2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
3 * Joakim Sindholt <opensource@zhasha.com>
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:
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
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. */
26 void r300_translate_fragment_shader(struct r300_context
* r300
,
27 struct r300_fragment_shader
* fs
)
29 struct tgsi_parse_context parser
;
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
];
35 struct r300_fs_asm
* assembler
= CALLOC_STRUCT(r300_fs_asm
);
36 if (assembler
== NULL
) {
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
;
44 /* Make sure we start at the beginning of the shader. */
46 ((struct r5xx_fragment_shader
*)fs
)->instruction_count
= 0;
49 tgsi_parse_init(&parser
, fs
->state
.tokens
);
51 while (!tgsi_parse_end_of_tokens(&parser
)) {
52 tgsi_parse_token(&parser
);
54 /* This is seriously the lamest way to create fragment programs ever.
56 switch (parser
.FullToken
.Token
.Type
) {
57 case TGSI_TOKEN_TYPE_DECLARATION
:
58 /* Allocated registers sitting at the beginning
60 r300_fs_declare(assembler
, &parser
.FullToken
.FullDeclaration
);
62 case TGSI_TOKEN_TYPE_IMMEDIATE
:
63 debug_printf("r300: Emitting immediate to constant buffer, "
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
]
73 assembler
->imm_count
++;
75 case TGSI_TOKEN_TYPE_INSTRUCTION
:
77 r5xx_fs_instruction((struct r5xx_fragment_shader
*)fs
,
78 assembler
, &parser
.FullToken
.FullInstruction
);
80 r3xx_fs_instruction((struct r3xx_fragment_shader
*)fs
,
81 assembler
, &parser
.FullToken
.FullInstruction
);
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
);
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
);
98 r5xx_fs_finalize((struct r5xx_fragment_shader
*)fs
, assembler
);
101 tgsi_dump(fs
->state
.tokens
, 0);
102 /* XXX finish r300 dumper too */
104 r5xx_fs_dump((struct r5xx_fragment_shader
*)fs
);
107 tgsi_parse_free(&parser
);