r600_state_common.c revision fa86fc564aea4e40c89f6fc889e6a5bf817634b3
1/* 2 * Copyright 2010 Red Hat Inc. 3 * 2010 Jerome Glisse 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 * Authors: Dave Airlie <airlied@redhat.com> 25 * Jerome Glisse <jglisse@redhat.com> 26 */ 27#include <util/u_memory.h> 28#include <util/u_format.h> 29#include <pipebuffer/pb_buffer.h> 30#include "r600_pipe.h" 31 32/* common state between evergreen and r600 */ 33void r600_bind_blend_state(struct pipe_context *ctx, void *state) 34{ 35 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 36 struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state; 37 struct r600_pipe_state *rstate; 38 39 if (state == NULL) 40 return; 41 rstate = &blend->rstate; 42 rctx->states[rstate->id] = rstate; 43 rctx->cb_target_mask = blend->cb_target_mask; 44 r600_context_pipe_state_set(&rctx->ctx, rstate); 45} 46 47void r600_bind_rs_state(struct pipe_context *ctx, void *state) 48{ 49 struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; 50 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 51 52 if (state == NULL) 53 return; 54 55 rctx->flatshade = rs->flatshade; 56 rctx->sprite_coord_enable = rs->sprite_coord_enable; 57 rctx->rasterizer = rs; 58 59 rctx->states[rs->rstate.id] = &rs->rstate; 60 r600_context_pipe_state_set(&rctx->ctx, &rs->rstate); 61 62 if (rctx->family >= CHIP_CEDAR) { 63 evergreen_polygon_offset_update(rctx); 64 } else { 65 r600_polygon_offset_update(rctx); 66 } 67} 68 69void r600_delete_rs_state(struct pipe_context *ctx, void *state) 70{ 71 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 72 struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; 73 74 if (rctx->rasterizer == rs) { 75 rctx->rasterizer = NULL; 76 } 77 if (rctx->states[rs->rstate.id] == &rs->rstate) { 78 rctx->states[rs->rstate.id] = NULL; 79 } 80 free(rs); 81} 82 83void r600_sampler_view_destroy(struct pipe_context *ctx, 84 struct pipe_sampler_view *state) 85{ 86 struct r600_pipe_sampler_view *resource = (struct r600_pipe_sampler_view *)state; 87 88 pipe_resource_reference(&state->texture, NULL); 89 FREE(resource); 90} 91 92void r600_bind_state(struct pipe_context *ctx, void *state) 93{ 94 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 95 struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; 96 97 if (state == NULL) 98 return; 99 rctx->states[rstate->id] = rstate; 100 r600_context_pipe_state_set(&rctx->ctx, rstate); 101} 102 103void r600_delete_state(struct pipe_context *ctx, void *state) 104{ 105 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 106 struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; 107 108 if (rctx->states[rstate->id] == rstate) { 109 rctx->states[rstate->id] = NULL; 110 } 111 for (int i = 0; i < rstate->nregs; i++) { 112 r600_bo_reference(rctx->radeon, &rstate->regs[i].bo, NULL); 113 } 114 free(rstate); 115} 116 117void r600_bind_vertex_elements(struct pipe_context *ctx, void *state) 118{ 119 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 120 struct r600_vertex_element *v = (struct r600_vertex_element*)state; 121 122 rctx->vertex_elements = v; 123 if (v) { 124 rctx->states[v->rstate.id] = &v->rstate; 125 r600_context_pipe_state_set(&rctx->ctx, &v->rstate); 126 if (rctx->family >= CHIP_CEDAR) { 127 evergreen_vertex_buffer_update(rctx); 128 } else { 129 r600_vertex_buffer_update(rctx); 130 } 131 } 132 133 if (v) { 134// rctx->vs_rebuild = TRUE; 135 } 136} 137 138void r600_delete_vertex_element(struct pipe_context *ctx, void *state) 139{ 140 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 141 struct r600_vertex_element *v = (struct r600_vertex_element*)state; 142 143 if (rctx->states[v->rstate.id] == &v->rstate) { 144 rctx->states[v->rstate.id] = NULL; 145 } 146 if (rctx->vertex_elements == state) 147 rctx->vertex_elements = NULL; 148 149 r600_bo_reference(rctx->radeon, &v->fetch_shader, NULL); 150 FREE(state); 151} 152 153 154void r600_set_index_buffer(struct pipe_context *ctx, 155 const struct pipe_index_buffer *ib) 156{ 157 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 158 159 if (ib) { 160 pipe_resource_reference(&rctx->index_buffer.buffer, ib->buffer); 161 memcpy(&rctx->index_buffer, ib, sizeof(rctx->index_buffer)); 162 } else { 163 pipe_resource_reference(&rctx->index_buffer.buffer, NULL); 164 memset(&rctx->index_buffer, 0, sizeof(rctx->index_buffer)); 165 } 166 167 /* TODO make this more like a state */ 168} 169 170void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count, 171 const struct pipe_vertex_buffer *buffers) 172{ 173 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 174 struct pipe_vertex_buffer *vbo; 175 unsigned max_index = (unsigned)-1; 176 177 for (int i = 0; i < rctx->nvertex_buffer; i++) { 178 pipe_resource_reference(&rctx->vertex_buffer[i].buffer, NULL); 179 } 180 memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); 181 182 for (int i = 0; i < count; i++) { 183 vbo = (struct pipe_vertex_buffer*)&buffers[i]; 184 185 rctx->vertex_buffer[i].buffer = NULL; 186 if (r600_buffer_is_user_buffer(buffers[i].buffer)) 187 rctx->any_user_vbs = TRUE; 188 pipe_resource_reference(&rctx->vertex_buffer[i].buffer, buffers[i].buffer); 189 190 if (vbo->max_index == ~0) { 191 if (!vbo->stride) 192 vbo->max_index = 1; 193 else 194 vbo->max_index = (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride; 195 } 196 max_index = MIN2(vbo->max_index, max_index); 197 } 198 rctx->nvertex_buffer = count; 199 rctx->vb_max_index = max_index; 200 if (rctx->family >= CHIP_CEDAR) { 201 evergreen_vertex_buffer_update(rctx); 202 } else { 203 r600_vertex_buffer_update(rctx); 204 } 205} 206 207 208#define FORMAT_REPLACE(what, withwhat) \ 209 case PIPE_FORMAT_##what: *format = PIPE_FORMAT_##withwhat; break 210 211void *r600_create_vertex_elements(struct pipe_context *ctx, 212 unsigned count, 213 const struct pipe_vertex_element *elements) 214{ 215 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 216 struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element); 217 enum pipe_format *format; 218 int i; 219 220 assert(count < 32); 221 if (!v) 222 return NULL; 223 224 v->count = count; 225 memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element)); 226 227 for (i = 0; i < count; i++) { 228 v->hw_format[i] = v->elements[i].src_format; 229 format = &v->hw_format[i]; 230 231 switch (*format) { 232 FORMAT_REPLACE(R64_FLOAT, R32_FLOAT); 233 FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT); 234 FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT); 235 FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT); 236 default:; 237 } 238 v->incompatible_layout = 239 v->incompatible_layout || 240 v->elements[i].src_format != v->hw_format[i]; 241 242 v->hw_format_size[i] = align(util_format_get_blocksize(v->hw_format[i]), 4); 243 } 244 245 if (r600_vertex_elements_build_fetch_shader(rctx, v)) { 246 FREE(v); 247 return NULL; 248 } 249 250 return v; 251} 252 253void *r600_create_shader_state(struct pipe_context *ctx, 254 const struct pipe_shader_state *state) 255{ 256 struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader); 257 int r; 258 259 r = r600_pipe_shader_create(ctx, shader, state->tokens); 260 if (r) { 261 return NULL; 262 } 263 return shader; 264} 265 266void r600_bind_ps_shader(struct pipe_context *ctx, void *state) 267{ 268 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 269 270 /* TODO delete old shader */ 271 rctx->ps_shader = (struct r600_pipe_shader *)state; 272} 273 274void r600_bind_vs_shader(struct pipe_context *ctx, void *state) 275{ 276 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 277 278 /* TODO delete old shader */ 279 rctx->vs_shader = (struct r600_pipe_shader *)state; 280} 281 282void r600_delete_ps_shader(struct pipe_context *ctx, void *state) 283{ 284 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 285 struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; 286 287 if (rctx->ps_shader == shader) { 288 rctx->ps_shader = NULL; 289 } 290 291 r600_pipe_shader_destroy(ctx, shader); 292 free(shader); 293} 294 295void r600_delete_vs_shader(struct pipe_context *ctx, void *state) 296{ 297 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 298 struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; 299 300 if (rctx->vs_shader == shader) { 301 rctx->vs_shader = NULL; 302 } 303 304 r600_pipe_shader_destroy(ctx, shader); 305 free(shader); 306} 307