r300_state.c revision 70c8d2a29724d018bacc4a68ddc61db08faea00d
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copy of this software and associated documentation files (the "Software"), 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to deal in the Software without restriction, including without limitation 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on the rights to use, copy, modify, merge, publish, distribute, sub 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * license, and/or sell copies of the Software, and to permit persons to whom 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * the Software is furnished to do so, subject to the following conditions: 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * The above copyright notice and this permission notice (including the next 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * paragraph) shall be included in all copies or substantial portions of the 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Software. 14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "draw/draw_context.h" 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "util/u_math.h" 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "util/u_memory.h" 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "util/u_pack_color.h" 28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tgsi/tgsi_parse.h" 30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "pipe/p_config.h" 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "pipe/internal/p_winsys_screen.h" 33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "r300_context.h" 35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "r300_reg.h" 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "r300_screen.h" 3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "r300_state_inlines.h" 3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "r300_fs.h" 395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "r300_vs.h" 40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/* r300_state: Functions used to intialize state context by translating 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) * Gallium state objects into semi-native r300 state objects. */ 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/* Create a new blend state based on the CSO blend state. 4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) * 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) * This encompasses alpha blending, logic/raster ops, and blend dithering. */ 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)static void* r300_create_blend_state(struct pipe_context* pipe, 4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const struct pipe_blend_state* state) 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch{ 5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state); 5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (state->blend_enable) 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) unsigned eqRGB = state->rgb_func; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned srcRGB = state->rgb_src_factor; 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) unsigned dstRGB = state->rgb_dst_factor; 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) unsigned eqA = state->alpha_func; 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) unsigned srcA = state->alpha_src_factor; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned dstA = state->alpha_dst_factor; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* despite the name, ALPHA_BLEND_ENABLE has nothing to do with alpha, 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * this is just the crappy D3D naming */ 645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blend->blend_control = R300_ALPHA_BLEND_ENABLE | 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu r300_translate_blend_function(eqRGB) | 66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ( r300_translate_blend_factor(srcRGB) << R300_SRC_BLEND_SHIFT) | 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ( r300_translate_blend_factor(dstRGB) << R300_DST_BLEND_SHIFT); 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 69c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch /* optimization: some operations do not require the destination color */ 70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (eqRGB == PIPE_BLEND_MIN || eqA == PIPE_BLEND_MIN || 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) eqRGB == PIPE_BLEND_MAX || eqA == PIPE_BLEND_MAX || 725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu dstRGB != PIPE_BLENDFACTOR_ZERO || 735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu dstA != PIPE_BLENDFACTOR_ZERO || 7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) srcRGB == PIPE_BLENDFACTOR_DST_COLOR || 7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) srcRGB == PIPE_BLENDFACTOR_DST_ALPHA || 7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) srcRGB == PIPE_BLENDFACTOR_INV_DST_COLOR || 7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) srcRGB == PIPE_BLENDFACTOR_INV_DST_ALPHA || 7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) srcA == PIPE_BLENDFACTOR_DST_COLOR || 7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) srcA == PIPE_BLENDFACTOR_DST_ALPHA || 805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu srcA == PIPE_BLENDFACTOR_INV_DST_COLOR || 8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) srcA == PIPE_BLENDFACTOR_INV_DST_ALPHA) 8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) blend->blend_control |= R300_READ_ENABLE; 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu /* XXX implement the optimization with DISCARD_SRC_PIXELS*/ 85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch /* XXX implement the optimization with SRC_ALPHA_?_NO_READ */ 86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch /* separate alpha */ 88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blend->blend_control |= R300_SEPARATE_ALPHA_ENABLE; 9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) blend->alpha_blend_control = 9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) r300_translate_blend_function(eqA) | 925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu (r300_translate_blend_factor(srcA) << R300_SRC_BLEND_SHIFT) | 935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu (r300_translate_blend_factor(dstA) << R300_DST_BLEND_SHIFT); 945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* PIPE_LOGICOP_* don't need to be translated, fortunately. */ 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state->logicop_enable) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE | 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 102 103 /* Color Channel Mask */ 104 if (state->colormask & PIPE_MASK_R) { 105 blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_RED_MASK0; 106 } 107 if (state->colormask & PIPE_MASK_G) { 108 blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0; 109 } 110 if (state->colormask & PIPE_MASK_B) { 111 blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0; 112 } 113 if (state->colormask & PIPE_MASK_A) { 114 blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0; 115 } 116 117 if (state->dither) { 118 blend->dither = R300_RB3D_DITHER_CTL_DITHER_MODE_LUT | 119 R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT; 120 } 121 122 return (void*)blend; 123} 124 125/* Bind blend state. */ 126static void r300_bind_blend_state(struct pipe_context* pipe, 127 void* state) 128{ 129 struct r300_context* r300 = r300_context(pipe); 130 131 r300->blend_state = (struct r300_blend_state*)state; 132 r300->dirty_state |= R300_NEW_BLEND; 133} 134 135/* Free blend state. */ 136static void r300_delete_blend_state(struct pipe_context* pipe, 137 void* state) 138{ 139 FREE(state); 140} 141 142/* Convert float to 10bit integer */ 143static unsigned float_to_fixed10(float f) 144{ 145 return CLAMP((unsigned)(f * 1023.9f), 0, 1023); 146} 147 148/* Set blend color. 149 * Setup both R300 and R500 registers, figure out later which one to write. */ 150static void r300_set_blend_color(struct pipe_context* pipe, 151 const struct pipe_blend_color* color) 152{ 153 struct r300_context* r300 = r300_context(pipe); 154 union util_color uc; 155 156 util_pack_color(color->color, PIPE_FORMAT_A8R8G8B8_UNORM, &uc); 157 r300->blend_color_state->blend_color = uc.ui; 158 159 /* XXX if FP16 blending is enabled, we should use the FP16 format */ 160 r300->blend_color_state->blend_color_red_alpha = 161 float_to_fixed10(color->color[0]) | 162 (float_to_fixed10(color->color[3]) << 16); 163 r300->blend_color_state->blend_color_green_blue = 164 float_to_fixed10(color->color[2]) | 165 (float_to_fixed10(color->color[1]) << 16); 166 167 r300->dirty_state |= R300_NEW_BLEND_COLOR; 168} 169 170static void r300_set_clip_state(struct pipe_context* pipe, 171 const struct pipe_clip_state* state) 172{ 173 struct r300_context* r300 = r300_context(pipe); 174 175 if (r300_screen(pipe->screen)->caps->has_tcl) { 176 r300->clip_state = *state; 177 r300->dirty_state |= R300_NEW_CLIP; 178 } else { 179 draw_flush(r300->draw); 180 draw_set_clip_state(r300->draw, state); 181 } 182} 183 184/* Create a new depth, stencil, and alpha state based on the CSO dsa state. 185 * 186 * This contains the depth buffer, stencil buffer, alpha test, and such. 187 * On the Radeon, depth and stencil buffer setup are intertwined, which is 188 * the reason for some of the strange-looking assignments across registers. */ 189static void* 190 r300_create_dsa_state(struct pipe_context* pipe, 191 const struct pipe_depth_stencil_alpha_state* state) 192{ 193 struct r300_capabilities *caps = 194 r300_screen(r300_context(pipe)->context.screen)->caps; 195 struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state); 196 197 /* Depth test setup. */ 198 if (state->depth.enabled) { 199 dsa->z_buffer_control |= R300_Z_ENABLE; 200 201 if (state->depth.writemask) { 202 dsa->z_buffer_control |= R300_Z_WRITE_ENABLE; 203 } 204 205 dsa->z_stencil_control |= 206 (r300_translate_depth_stencil_function(state->depth.func) << 207 R300_Z_FUNC_SHIFT); 208 } 209 210 /* Stencil buffer setup. */ 211 if (state->stencil[0].enabled) { 212 dsa->z_buffer_control |= R300_STENCIL_ENABLE; 213 dsa->z_stencil_control |= 214 (r300_translate_depth_stencil_function(state->stencil[0].func) << 215 R300_S_FRONT_FUNC_SHIFT) | 216 (r300_translate_stencil_op(state->stencil[0].fail_op) << 217 R300_S_FRONT_SFAIL_OP_SHIFT) | 218 (r300_translate_stencil_op(state->stencil[0].zpass_op) << 219 R300_S_FRONT_ZPASS_OP_SHIFT) | 220 (r300_translate_stencil_op(state->stencil[0].zfail_op) << 221 R300_S_FRONT_ZFAIL_OP_SHIFT); 222 223 dsa->stencil_ref_mask = (state->stencil[0].ref_value) | 224 (state->stencil[0].valuemask << R300_STENCILMASK_SHIFT) | 225 (state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT); 226 227 if (state->stencil[1].enabled) { 228 dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK; 229 dsa->z_stencil_control |= 230 (r300_translate_depth_stencil_function(state->stencil[1].func) << 231 R300_S_BACK_FUNC_SHIFT) | 232 (r300_translate_stencil_op(state->stencil[1].fail_op) << 233 R300_S_BACK_SFAIL_OP_SHIFT) | 234 (r300_translate_stencil_op(state->stencil[1].zpass_op) << 235 R300_S_BACK_ZPASS_OP_SHIFT) | 236 (r300_translate_stencil_op(state->stencil[1].zfail_op) << 237 R300_S_BACK_ZFAIL_OP_SHIFT); 238 239 /* XXX it seems r3xx doesn't support STENCILREFMASK_BF */ 240 if (caps->is_r500) 241 { 242 dsa->z_buffer_control |= R500_STENCIL_REFMASK_FRONT_BACK; 243 dsa->stencil_ref_bf = (state->stencil[1].ref_value) | 244 (state->stencil[1].valuemask << 245 R300_STENCILMASK_SHIFT) | 246 (state->stencil[1].writemask << 247 R300_STENCILWRITEMASK_SHIFT); 248 } 249 } 250 } 251 252 /* Alpha test setup. */ 253 if (state->alpha.enabled) { 254 dsa->alpha_function = 255 r300_translate_alpha_function(state->alpha.func) | 256 R300_FG_ALPHA_FUNC_ENABLE; 257 258 /* XXX figure out why emitting 10bit alpha ref causes CS to dump */ 259 /* always use 8bit alpha ref */ 260 dsa->alpha_function |= float_to_ubyte(state->alpha.ref_value); 261 262 if (caps->is_r500) 263 dsa->alpha_function |= R500_FG_ALPHA_FUNC_8BIT; 264 } 265 266 return (void*)dsa; 267} 268 269/* Bind DSA state. */ 270static void r300_bind_dsa_state(struct pipe_context* pipe, 271 void* state) 272{ 273 struct r300_context* r300 = r300_context(pipe); 274 275 r300->dsa_state = (struct r300_dsa_state*)state; 276 r300->dirty_state |= R300_NEW_DSA; 277} 278 279/* Free DSA state. */ 280static void r300_delete_dsa_state(struct pipe_context* pipe, 281 void* state) 282{ 283 FREE(state); 284} 285 286static void r300_set_scissor_regs(const struct pipe_scissor_state* state, 287 struct r300_scissor_regs *scissor, 288 boolean is_r500) 289{ 290 if (is_r500) { 291 scissor->top_left = 292 (state->minx << R300_SCISSORS_X_SHIFT) | 293 (state->miny << R300_SCISSORS_Y_SHIFT); 294 scissor->bottom_right = 295 ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) | 296 ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT); 297 } else { 298 /* Offset of 1440 in non-R500 chipsets. */ 299 scissor->top_left = 300 ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) | 301 ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT); 302 scissor->bottom_right = 303 (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) | 304 (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT); 305 } 306 307 scissor->empty_area = state->minx >= state->maxx || 308 state->miny >= state->maxy; 309} 310 311static void 312 r300_set_framebuffer_state(struct pipe_context* pipe, 313 const struct pipe_framebuffer_state* state) 314{ 315 struct r300_context* r300 = r300_context(pipe); 316 struct pipe_scissor_state scissor; 317 318 if (r300->draw) { 319 draw_flush(r300->draw); 320 } 321 322 r300->framebuffer_state = *state; 323 324 scissor.minx = scissor.miny = 0; 325 scissor.maxx = state->width; 326 scissor.maxy = state->height; 327 r300_set_scissor_regs(&scissor, &r300->scissor_state->framebuffer, 328 r300_screen(r300->context.screen)->caps->is_r500); 329 330 /* Don't rely on the order of states being set for the first time. */ 331 if (!r300->rs_state || !r300->rs_state->rs.scissor) { 332 r300->dirty_state |= R300_NEW_SCISSOR; 333 } 334 r300->dirty_state |= R300_NEW_FRAMEBUFFERS; 335 r300->dirty_state |= R300_NEW_BLEND; 336} 337 338/* Create fragment shader state. */ 339static void* r300_create_fs_state(struct pipe_context* pipe, 340 const struct pipe_shader_state* shader) 341{ 342 struct r300_fragment_shader* fs = NULL; 343 344 fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader); 345 346 /* Copy state directly into shader. */ 347 fs->state = *shader; 348 fs->state.tokens = tgsi_dup_tokens(shader->tokens); 349 350 tgsi_scan_shader(shader->tokens, &fs->info); 351 r300_shader_read_fs_inputs(&fs->info, &fs->inputs); 352 353 return (void*)fs; 354} 355 356/* Bind fragment shader state. */ 357static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) 358{ 359 struct r300_context* r300 = r300_context(pipe); 360 struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader; 361 362 if (fs == NULL) { 363 r300->fs = NULL; 364 return; 365 } 366 367 r300->fs = fs; 368 r300_pick_fragment_shader(r300); 369 370 r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS; 371} 372 373/* Delete fragment shader state. */ 374static void r300_delete_fs_state(struct pipe_context* pipe, void* shader) 375{ 376 struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader; 377 struct r300_fragment_shader_code *tmp, *ptr = fs->first; 378 379 while (ptr) { 380 tmp = ptr; 381 ptr = ptr->next; 382 rc_constants_destroy(&tmp->code.constants); 383 FREE(tmp); 384 } 385 FREE((void*)fs->state.tokens); 386 FREE(shader); 387} 388 389static void r300_set_polygon_stipple(struct pipe_context* pipe, 390 const struct pipe_poly_stipple* state) 391{ 392 /* XXX no idea how to set this up, but not terribly important */ 393} 394 395/* Create a new rasterizer state based on the CSO rasterizer state. 396 * 397 * This is a very large chunk of state, and covers most of the graphics 398 * backend (GB), geometry assembly (GA), and setup unit (SU) blocks. 399 * 400 * In a not entirely unironic sidenote, this state has nearly nothing to do 401 * with the actual block on the Radeon called the rasterizer (RS). */ 402static void* r300_create_rs_state(struct pipe_context* pipe, 403 const struct pipe_rasterizer_state* state) 404{ 405 struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state); 406 407 /* Copy rasterizer state for Draw. */ 408 rs->rs = *state; 409 410 rs->enable_vte = !state->bypass_vs_clip_and_viewport; 411 412#ifdef PIPE_ARCH_LITTLE_ENDIAN 413 rs->vap_control_status = R300_VC_NO_SWAP; 414#else 415 rs->vap_control_status = R300_VC_32BIT_SWAP; 416#endif 417 418 /* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL. 419 * Else, enable HW TCL and force Draw's TCL off. */ 420 if (state->bypass_vs_clip_and_viewport || 421 !r300_screen(pipe->screen)->caps->has_tcl) { 422 rs->vap_control_status |= R300_VAP_TCL_BYPASS; 423 } 424 425 rs->point_size = pack_float_16_6x(state->point_size) | 426 (pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT); 427 428 rs->point_minmax = 429 ((int)(state->point_size_min * 6.0) << 430 R300_GA_POINT_MINMAX_MIN_SHIFT) | 431 ((int)(state->point_size_max * 6.0) << 432 R300_GA_POINT_MINMAX_MAX_SHIFT); 433 434 rs->line_control = pack_float_16_6x(state->line_width) | 435 R300_GA_LINE_CNTL_END_TYPE_COMP; 436 437 /* XXX I think there is something wrong with the polygon mode, 438 * XXX re-test when r300g is in a better shape */ 439 440 /* Enable polygon mode */ 441 if (state->fill_cw != PIPE_POLYGON_MODE_FILL || 442 state->fill_ccw != PIPE_POLYGON_MODE_FILL) { 443 rs->polygon_mode = R300_GA_POLY_MODE_DUAL; 444 } 445 446 /* Radeons don't think in "CW/CCW", they think in "front/back". */ 447 if (state->front_winding == PIPE_WINDING_CW) { 448 rs->cull_mode = R300_FRONT_FACE_CW; 449 450 /* Polygon offset */ 451 if (state->offset_cw) { 452 rs->polygon_offset_enable |= R300_FRONT_ENABLE; 453 } 454 if (state->offset_ccw) { 455 rs->polygon_offset_enable |= R300_BACK_ENABLE; 456 } 457 458 /* Polygon mode */ 459 if (rs->polygon_mode) { 460 rs->polygon_mode |= 461 r300_translate_polygon_mode_front(state->fill_cw); 462 rs->polygon_mode |= 463 r300_translate_polygon_mode_back(state->fill_ccw); 464 } 465 } else { 466 rs->cull_mode = R300_FRONT_FACE_CCW; 467 468 /* Polygon offset */ 469 if (state->offset_ccw) { 470 rs->polygon_offset_enable |= R300_FRONT_ENABLE; 471 } 472 if (state->offset_cw) { 473 rs->polygon_offset_enable |= R300_BACK_ENABLE; 474 } 475 476 /* Polygon mode */ 477 if (rs->polygon_mode) { 478 rs->polygon_mode |= 479 r300_translate_polygon_mode_front(state->fill_ccw); 480 rs->polygon_mode |= 481 r300_translate_polygon_mode_back(state->fill_cw); 482 } 483 } 484 if (state->front_winding & state->cull_mode) { 485 rs->cull_mode |= R300_CULL_FRONT; 486 } 487 if (~(state->front_winding) & state->cull_mode) { 488 rs->cull_mode |= R300_CULL_BACK; 489 } 490 491 if (rs->polygon_offset_enable) { 492 rs->depth_offset_front = rs->depth_offset_back = 493 fui(state->offset_units); 494 rs->depth_scale_front = rs->depth_scale_back = 495 fui(state->offset_scale); 496 } 497 498 if (state->line_stipple_enable) { 499 rs->line_stipple_config = 500 R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE | 501 (fui((float)state->line_stipple_factor) & 502 R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK); 503 /* XXX this might need to be scaled up */ 504 rs->line_stipple_value = state->line_stipple_pattern; 505 } 506 507 if (state->flatshade) { 508 rs->color_control = R300_SHADE_MODEL_FLAT; 509 } else { 510 rs->color_control = R300_SHADE_MODEL_SMOOTH; 511 } 512 513 return (void*)rs; 514} 515 516/* Bind rasterizer state. */ 517static void r300_bind_rs_state(struct pipe_context* pipe, void* state) 518{ 519 struct r300_context* r300 = r300_context(pipe); 520 struct r300_rs_state* rs = (struct r300_rs_state*)state; 521 522 if (r300->draw) { 523 draw_flush(r300->draw); 524 draw_set_rasterizer_state(r300->draw, &rs->rs); 525 } 526 527 r300->rs_state = rs; 528 /* XXX Clean these up when we move to atom emits */ 529 r300->dirty_state |= R300_NEW_RASTERIZER; 530 r300->dirty_state |= R300_NEW_RS_BLOCK; 531 r300->dirty_state |= R300_NEW_SCISSOR; 532 r300->dirty_state |= R300_NEW_VIEWPORT; 533} 534 535/* Free rasterizer state. */ 536static void r300_delete_rs_state(struct pipe_context* pipe, void* state) 537{ 538 FREE(state); 539} 540 541static void* 542 r300_create_sampler_state(struct pipe_context* pipe, 543 const struct pipe_sampler_state* state) 544{ 545 struct r300_context* r300 = r300_context(pipe); 546 struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state); 547 int lod_bias; 548 union util_color uc; 549 550 sampler->state = *state; 551 552 sampler->filter0 |= 553 (r300_translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) | 554 (r300_translate_wrap(state->wrap_t) << R300_TX_WRAP_T_SHIFT) | 555 (r300_translate_wrap(state->wrap_r) << R300_TX_WRAP_R_SHIFT); 556 557 sampler->filter0 |= r300_translate_tex_filters(state->min_img_filter, 558 state->mag_img_filter, 559 state->min_mip_filter); 560 561 /* Unfortunately, r300-r500 don't support floating-point mipmap lods. */ 562 /* We must pass these to the emit function to clamp them properly. */ 563 sampler->min_lod = MAX2((unsigned)state->min_lod, 0); 564 sampler->max_lod = MAX2((unsigned)ceilf(state->max_lod), 0); 565 566 lod_bias = CLAMP((int)(state->lod_bias * 32), -(1 << 9), (1 << 9) - 1); 567 568 sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT; 569 570 sampler->filter1 |= r300_anisotropy(state->max_anisotropy); 571 572 util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM, &uc); 573 sampler->border_color = uc.ui; 574 575 /* R500-specific fixups and optimizations */ 576 if (r300_screen(r300->context.screen)->caps->is_r500) { 577 sampler->filter1 |= R500_BORDER_FIX; 578 } 579 580 return (void*)sampler; 581} 582 583static void r300_bind_sampler_states(struct pipe_context* pipe, 584 unsigned count, 585 void** states) 586{ 587 struct r300_context* r300 = r300_context(pipe); 588 int i; 589 590 if (count > 8) { 591 return; 592 } 593 594 for (i = 0; i < count; i++) { 595 if (r300->sampler_states[i] != states[i]) { 596 r300->sampler_states[i] = (struct r300_sampler_state*)states[i]; 597 r300->dirty_state |= (R300_NEW_SAMPLER << i); 598 } 599 } 600 601 r300->sampler_count = count; 602 603 /* Pick a fragment shader based on the texture compare state. */ 604 if (r300->fs && (r300->dirty_state & R300_ANY_NEW_SAMPLERS)) { 605 if (r300_pick_fragment_shader(r300)) { 606 r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | 607 R300_NEW_FRAGMENT_SHADER_CONSTANTS; 608 } 609 } 610} 611 612static void r300_lacks_vertex_textures(struct pipe_context* pipe, 613 unsigned count, 614 void** states) 615{ 616} 617 618static void r300_delete_sampler_state(struct pipe_context* pipe, void* state) 619{ 620 FREE(state); 621} 622 623static void r300_set_sampler_textures(struct pipe_context* pipe, 624 unsigned count, 625 struct pipe_texture** texture) 626{ 627 struct r300_context* r300 = r300_context(pipe); 628 boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500; 629 int i; 630 631 /* XXX magic num */ 632 if (count > 8) { 633 return; 634 } 635 636 for (i = 0; i < count; i++) { 637 if (r300->textures[i] != (struct r300_texture*)texture[i]) { 638 pipe_texture_reference((struct pipe_texture**)&r300->textures[i], 639 texture[i]); 640 r300->dirty_state |= (R300_NEW_TEXTURE << i); 641 642 /* R300-specific - set the texrect factor in a fragment shader */ 643 if (!is_r500 && r300->textures[i]->is_npot) { 644 /* XXX It would be nice to re-emit just 1 constant, 645 * XXX not all of them */ 646 r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; 647 } 648 } 649 } 650 651 for (i = count; i < 8; i++) { 652 if (r300->textures[i]) { 653 pipe_texture_reference((struct pipe_texture**)&r300->textures[i], 654 NULL); 655 r300->dirty_state |= (R300_NEW_TEXTURE << i); 656 } 657 } 658 659 r300->texture_count = count; 660} 661 662static void r300_set_scissor_state(struct pipe_context* pipe, 663 const struct pipe_scissor_state* state) 664{ 665 struct r300_context* r300 = r300_context(pipe); 666 667 r300_set_scissor_regs(state, &r300->scissor_state->scissor, 668 r300_screen(r300->context.screen)->caps->is_r500); 669 670 /* Don't rely on the order of states being set for the first time. */ 671 if (!r300->rs_state || r300->rs_state->rs.scissor) { 672 r300->dirty_state |= R300_NEW_SCISSOR; 673 } 674} 675 676static void r300_set_viewport_state(struct pipe_context* pipe, 677 const struct pipe_viewport_state* state) 678{ 679 struct r300_context* r300 = r300_context(pipe); 680 681 /* Do the transform in HW. */ 682 r300->viewport_state->vte_control = R300_VTX_W0_FMT; 683 684 if (state->scale[0] != 1.0f) { 685 r300->viewport_state->xscale = state->scale[0]; 686 r300->viewport_state->vte_control |= R300_VPORT_X_SCALE_ENA; 687 } 688 if (state->scale[1] != 1.0f) { 689 r300->viewport_state->yscale = state->scale[1]; 690 r300->viewport_state->vte_control |= R300_VPORT_Y_SCALE_ENA; 691 } 692 if (state->scale[2] != 1.0f) { 693 r300->viewport_state->zscale = state->scale[2]; 694 r300->viewport_state->vte_control |= R300_VPORT_Z_SCALE_ENA; 695 } 696 if (state->translate[0] != 0.0f) { 697 r300->viewport_state->xoffset = state->translate[0]; 698 r300->viewport_state->vte_control |= R300_VPORT_X_OFFSET_ENA; 699 } 700 if (state->translate[1] != 0.0f) { 701 r300->viewport_state->yoffset = state->translate[1]; 702 r300->viewport_state->vte_control |= R300_VPORT_Y_OFFSET_ENA; 703 } 704 if (state->translate[2] != 0.0f) { 705 r300->viewport_state->zoffset = state->translate[2]; 706 r300->viewport_state->vte_control |= R300_VPORT_Z_OFFSET_ENA; 707 } 708 709 r300->dirty_state |= R300_NEW_VIEWPORT; 710} 711 712static void r300_set_vertex_buffers(struct pipe_context* pipe, 713 unsigned count, 714 const struct pipe_vertex_buffer* buffers) 715{ 716 struct r300_context* r300 = r300_context(pipe); 717 718 memcpy(r300->vertex_buffer, buffers, 719 sizeof(struct pipe_vertex_buffer) * count); 720 r300->vertex_buffer_count = count; 721 722 if (r300->draw) { 723 draw_flush(r300->draw); 724 draw_set_vertex_buffers(r300->draw, count, buffers); 725 } 726 727 r300->dirty_state |= R300_NEW_VERTEX_FORMAT; 728} 729 730static void r300_set_vertex_elements(struct pipe_context* pipe, 731 unsigned count, 732 const struct pipe_vertex_element* elements) 733{ 734 struct r300_context* r300 = r300_context(pipe); 735 736 memcpy(r300->vertex_element, 737 elements, 738 sizeof(struct pipe_vertex_element) * count); 739 r300->vertex_element_count = count; 740 741 if (r300->draw) { 742 draw_flush(r300->draw); 743 draw_set_vertex_elements(r300->draw, count, elements); 744 } 745} 746 747static void* r300_create_vs_state(struct pipe_context* pipe, 748 const struct pipe_shader_state* shader) 749{ 750 struct r300_context* r300 = r300_context(pipe); 751 752 if (r300_screen(pipe->screen)->caps->has_tcl) { 753 struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader); 754 /* Copy state directly into shader. */ 755 vs->state = *shader; 756 vs->state.tokens = tgsi_dup_tokens(shader->tokens); 757 758 tgsi_scan_shader(shader->tokens, &vs->info); 759 760 return (void*)vs; 761 } else { 762 return draw_create_vertex_shader(r300->draw, shader); 763 } 764} 765 766static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) 767{ 768 struct r300_context* r300 = r300_context(pipe); 769 770 if (r300_screen(pipe->screen)->caps->has_tcl) { 771 struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; 772 773 if (vs == NULL) { 774 r300->vs = NULL; 775 return; 776 } else if (!vs->translated) { 777 r300_translate_vertex_shader(r300, vs); 778 } 779 780 r300->vs = vs; 781 r300->dirty_state |= R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS; 782 } else { 783 draw_flush(r300->draw); 784 draw_bind_vertex_shader(r300->draw, 785 (struct draw_vertex_shader*)shader); 786 } 787} 788 789static void r300_delete_vs_state(struct pipe_context* pipe, void* shader) 790{ 791 struct r300_context* r300 = r300_context(pipe); 792 793 if (r300_screen(pipe->screen)->caps->has_tcl) { 794 struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; 795 796 rc_constants_destroy(&vs->code.constants); 797 FREE((void*)vs->state.tokens); 798 FREE(shader); 799 } else { 800 draw_delete_vertex_shader(r300->draw, 801 (struct draw_vertex_shader*)shader); 802 } 803} 804 805static void r300_set_constant_buffer(struct pipe_context *pipe, 806 uint shader, uint index, 807 struct pipe_buffer *buf) 808{ 809 struct r300_context* r300 = r300_context(pipe); 810 void *mapped; 811 812 if (buf == NULL || buf->size == 0 || 813 (mapped = pipe_buffer_map(pipe->screen, buf, PIPE_BUFFER_USAGE_CPU_READ)) == NULL) 814 { 815 r300->shader_constants[shader].count = 0; 816 return; 817 } 818 819 assert((buf->size % 4 * sizeof(float)) == 0); 820 memcpy(r300->shader_constants[shader].constants, mapped, buf->size); 821 r300->shader_constants[shader].count = buf->size / (4 * sizeof(float)); 822 pipe_buffer_unmap(pipe->screen, buf); 823 824 if (shader == PIPE_SHADER_VERTEX) 825 r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS; 826 else if (shader == PIPE_SHADER_FRAGMENT) 827 r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; 828} 829 830void r300_init_state_functions(struct r300_context* r300) 831{ 832 r300->context.create_blend_state = r300_create_blend_state; 833 r300->context.bind_blend_state = r300_bind_blend_state; 834 r300->context.delete_blend_state = r300_delete_blend_state; 835 836 r300->context.set_blend_color = r300_set_blend_color; 837 838 r300->context.set_clip_state = r300_set_clip_state; 839 840 r300->context.set_constant_buffer = r300_set_constant_buffer; 841 842 r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state; 843 r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state; 844 r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state; 845 846 r300->context.set_framebuffer_state = r300_set_framebuffer_state; 847 848 r300->context.create_fs_state = r300_create_fs_state; 849 r300->context.bind_fs_state = r300_bind_fs_state; 850 r300->context.delete_fs_state = r300_delete_fs_state; 851 852 r300->context.set_polygon_stipple = r300_set_polygon_stipple; 853 854 r300->context.create_rasterizer_state = r300_create_rs_state; 855 r300->context.bind_rasterizer_state = r300_bind_rs_state; 856 r300->context.delete_rasterizer_state = r300_delete_rs_state; 857 858 r300->context.create_sampler_state = r300_create_sampler_state; 859 r300->context.bind_fragment_sampler_states = r300_bind_sampler_states; 860 r300->context.bind_vertex_sampler_states = r300_lacks_vertex_textures; 861 r300->context.delete_sampler_state = r300_delete_sampler_state; 862 863 r300->context.set_fragment_sampler_textures = r300_set_sampler_textures; 864 865 r300->context.set_scissor_state = r300_set_scissor_state; 866 867 r300->context.set_viewport_state = r300_set_viewport_state; 868 869 r300->context.set_vertex_buffers = r300_set_vertex_buffers; 870 r300->context.set_vertex_elements = r300_set_vertex_elements; 871 872 r300->context.create_vs_state = r300_create_vs_state; 873 r300->context.bind_vs_state = r300_bind_vs_state; 874 r300->context.delete_vs_state = r300_delete_vs_state; 875} 876