r600_state_common.c revision a20c2347a0bb9e0e1591b070ee5d0cac81168114
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 63void r600_delete_rs_state(struct pipe_context *ctx, void *state) 64{ 65 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 66 struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; 67 68 if (rctx->rasterizer == rs) { 69 rctx->rasterizer = NULL; 70 } 71 if (rctx->states[rs->rstate.id] == &rs->rstate) { 72 rctx->states[rs->rstate.id] = NULL; 73 } 74 free(rs); 75} 76 77void r600_sampler_view_destroy(struct pipe_context *ctx, 78 struct pipe_sampler_view *state) 79{ 80 struct r600_pipe_sampler_view *resource = (struct r600_pipe_sampler_view *)state; 81 82 pipe_resource_reference(&state->texture, NULL); 83 FREE(resource); 84} 85 86void r600_bind_state(struct pipe_context *ctx, void *state) 87{ 88 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 89 struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; 90 91 if (state == NULL) 92 return; 93 rctx->states[rstate->id] = rstate; 94 r600_context_pipe_state_set(&rctx->ctx, rstate); 95} 96 97void r600_delete_state(struct pipe_context *ctx, void *state) 98{ 99 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 100 struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; 101 102 if (rctx->states[rstate->id] == rstate) { 103 rctx->states[rstate->id] = NULL; 104 } 105 for (int i = 0; i < rstate->nregs; i++) { 106 r600_bo_reference(rctx->radeon, &rstate->regs[i].bo, NULL); 107 } 108 free(rstate); 109} 110 111void r600_bind_vertex_elements(struct pipe_context *ctx, void *state) 112{ 113 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 114 struct r600_vertex_element *v = (struct r600_vertex_element*)state; 115 116 rctx->vertex_elements = v; 117 if (v) { 118// rctx->vs_rebuild = TRUE; 119 } 120} 121 122void r600_delete_vertex_element(struct pipe_context *ctx, void *state) 123{ 124 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 125 126 FREE(state); 127 128 if (rctx->vertex_elements == state) 129 rctx->vertex_elements = NULL; 130} 131 132 133void r600_set_index_buffer(struct pipe_context *ctx, 134 const struct pipe_index_buffer *ib) 135{ 136 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 137 138 if (ib) { 139 pipe_resource_reference(&rctx->index_buffer.buffer, ib->buffer); 140 memcpy(&rctx->index_buffer, ib, sizeof(rctx->index_buffer)); 141 } else { 142 pipe_resource_reference(&rctx->index_buffer.buffer, NULL); 143 memset(&rctx->index_buffer, 0, sizeof(rctx->index_buffer)); 144 } 145 146 /* TODO make this more like a state */ 147} 148 149void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count, 150 const struct pipe_vertex_buffer *buffers) 151{ 152 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 153 struct pipe_vertex_buffer *vbo; 154 unsigned max_index = (unsigned)-1; 155 156 for (int i = 0; i < rctx->nvertex_buffer; i++) { 157 pipe_resource_reference(&rctx->vertex_buffer[i].buffer, NULL); 158 } 159 memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); 160 161 for (int i = 0; i < count; i++) { 162 vbo = (struct pipe_vertex_buffer*)&buffers[i]; 163 164 rctx->vertex_buffer[i].buffer = NULL; 165 if (r600_buffer_is_user_buffer(buffers[i].buffer)) 166 rctx->any_user_vbs = TRUE; 167 pipe_resource_reference(&rctx->vertex_buffer[i].buffer, buffers[i].buffer); 168 169 if (vbo->max_index == ~0) { 170 if (!vbo->stride) 171 vbo->max_index = 1; 172 else 173 vbo->max_index = (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride; 174 } 175 max_index = MIN2(vbo->max_index, max_index); 176 } 177 rctx->nvertex_buffer = count; 178 rctx->vb_max_index = max_index; 179} 180 181 182#define FORMAT_REPLACE(what, withwhat) \ 183 case PIPE_FORMAT_##what: *format = PIPE_FORMAT_##withwhat; break 184 185void *r600_create_vertex_elements(struct pipe_context *ctx, 186 unsigned count, 187 const struct pipe_vertex_element *elements) 188{ 189 struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element); 190 int i; 191 enum pipe_format *format; 192 193 assert(count < 32); 194 if (!v) 195 return NULL; 196 197 v->count = count; 198 memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element)); 199 200 for (i = 0; i < count; i++) { 201 v->hw_format[i] = v->elements[i].src_format; 202 format = &v->hw_format[i]; 203 204 switch (*format) { 205 FORMAT_REPLACE(R64_FLOAT, R32_FLOAT); 206 FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT); 207 FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT); 208 FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT); 209 default:; 210 } 211 v->incompatible_layout = 212 v->incompatible_layout || 213 v->elements[i].src_format != v->hw_format[i] || 214 v->elements[i].src_offset % 4 != 0; 215 216 v->hw_format_size[i] = 217 align(util_format_get_blocksize(v->hw_format[i]), 4); 218 } 219 220 return v; 221} 222 223void *r600_create_shader_state(struct pipe_context *ctx, 224 const struct pipe_shader_state *state) 225{ 226 struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader); 227 int r; 228 229 r = r600_pipe_shader_create(ctx, shader, state->tokens); 230 if (r) { 231 return NULL; 232 } 233 return shader; 234} 235 236void r600_bind_ps_shader(struct pipe_context *ctx, void *state) 237{ 238 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 239 240 /* TODO delete old shader */ 241 rctx->ps_shader = (struct r600_pipe_shader *)state; 242} 243 244void r600_bind_vs_shader(struct pipe_context *ctx, void *state) 245{ 246 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 247 248 /* TODO delete old shader */ 249 rctx->vs_shader = (struct r600_pipe_shader *)state; 250} 251 252void r600_delete_ps_shader(struct pipe_context *ctx, void *state) 253{ 254 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 255 struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; 256 257 if (rctx->ps_shader == shader) { 258 rctx->ps_shader = NULL; 259 } 260 261 r600_pipe_shader_destroy(ctx, shader); 262 free(shader); 263} 264 265void r600_delete_vs_shader(struct pipe_context *ctx, void *state) 266{ 267 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 268 struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; 269 270 if (rctx->vs_shader == shader) { 271 rctx->vs_shader = NULL; 272 } 273 274 r600_pipe_shader_destroy(ctx, shader); 275 free(shader); 276} 277