1 /* 2 * Copyright (c) 2011-2013 Luc Verhaegen <libv (at) skynet.be> 3 * Copyright (c) 2017-2019 Lima Project 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 * the rights to use, copy, modify, merge, publish, distribute, sub license, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the 13 * next paragraph) shall be included in all copies or substantial portions 14 * of the 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 */ 25 26 #include "util/format/u_format.h" 27 #include "util/u_memory.h" 28 #include "util/u_inlines.h" 29 #include "util/u_helpers.h" 30 #include "util/u_debug.h" 31 #include "util/u_framebuffer.h" 32 #include "util/u_viewport.h" 33 34 #include "pipe/p_state.h" 35 36 #include "lima_screen.h" 37 #include "lima_context.h" 38 #include "lima_format.h" 39 #include "lima_resource.h" 40 41 static void 42 lima_set_framebuffer_state(struct pipe_context *pctx, 43 const struct pipe_framebuffer_state *framebuffer) 44 { 45 struct lima_context *ctx = lima_context(pctx); 46 47 /* make sure there are always single job in this context */ 48 if (lima_debug & LIMA_DEBUG_SINGLE_JOB) 49 lima_flush(ctx); 50 51 struct lima_context_framebuffer *fb = &ctx->framebuffer; 52 53 util_copy_framebuffer_state(&fb->base, framebuffer); 54 55 ctx->job = NULL; 56 ctx->dirty |= LIMA_CONTEXT_DIRTY_FRAMEBUFFER; 57 } 58 59 static void 60 lima_set_polygon_stipple(struct pipe_context *pctx, 61 const struct pipe_poly_stipple *stipple) 62 { 63 64 } 65 66 static void * 67 lima_create_depth_stencil_alpha_state(struct pipe_context *pctx, 68 const struct pipe_depth_stencil_alpha_state *cso) 69 { 70 struct lima_depth_stencil_alpha_state *so; 71 72 so = CALLOC_STRUCT(lima_depth_stencil_alpha_state); 73 if (!so) 74 return NULL; 75 76 so->base = *cso; 77 78 return so; 79 } 80 81 static void 82 lima_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *hwcso) 83 { 84 struct lima_context *ctx = lima_context(pctx); 85 86 ctx->zsa = hwcso; 87 ctx->dirty |= LIMA_CONTEXT_DIRTY_ZSA; 88 } 89 90 static void 91 lima_delete_depth_stencil_alpha_state(struct pipe_context *pctx, void *hwcso) 92 { 93 FREE(hwcso); 94 } 95 96 static void * 97 lima_create_rasterizer_state(struct pipe_context *pctx, 98 const struct pipe_rasterizer_state *cso) 99 { 100 struct lima_rasterizer_state *so; 101 102 so = CALLOC_STRUCT(lima_rasterizer_state); 103 if (!so) 104 return NULL; 105 106 so->base = *cso; 107 108 return so; 109 } 110 111 static void 112 lima_bind_rasterizer_state(struct pipe_context *pctx, void *hwcso) 113 { 114 struct lima_context *ctx = lima_context(pctx); 115 116 ctx->rasterizer = hwcso; 117 ctx->dirty |= LIMA_CONTEXT_DIRTY_RASTERIZER; 118 } 119 120 static void 121 lima_delete_rasterizer_state(struct pipe_context *pctx, void *hwcso) 122 { 123 FREE(hwcso); 124 } 125 126 static void * 127 lima_create_blend_state(struct pipe_context *pctx, 128 const struct pipe_blend_state *cso) 129 { 130 struct lima_blend_state *so; 131 132 so = CALLOC_STRUCT(lima_blend_state); 133 if (!so) 134 return NULL; 135 136 so->base = *cso; 137 138 return so; 139 } 140 141 static void 142 lima_bind_blend_state(struct pipe_context *pctx, void *hwcso) 143 { 144 struct lima_context *ctx = lima_context(pctx); 145 146 ctx->blend = hwcso; 147 ctx->dirty |= LIMA_CONTEXT_DIRTY_BLEND; 148 } 149 150 static void 151 lima_delete_blend_state(struct pipe_context *pctx, void *hwcso) 152 { 153 FREE(hwcso); 154 } 155 156 static void * 157 lima_create_vertex_elements_state(struct pipe_context *pctx, unsigned num_elements, 158 const struct pipe_vertex_element *elements) 159 { 160 struct lima_vertex_element_state *so; 161 162 so = CALLOC_STRUCT(lima_vertex_element_state); 163 if (!so) 164 return NULL; 165 166 memcpy(so->pipe, elements, sizeof(*elements) * num_elements); 167 so->num_elements = num_elements; 168 169 return so; 170 } 171 172 static void 173 lima_bind_vertex_elements_state(struct pipe_context *pctx, void *hwcso) 174 { 175 struct lima_context *ctx = lima_context(pctx); 176 177 ctx->vertex_elements = hwcso; 178 ctx->dirty |= LIMA_CONTEXT_DIRTY_VERTEX_ELEM; 179 } 180 181 static void 182 lima_delete_vertex_elements_state(struct pipe_context *pctx, void *hwcso) 183 { 184 FREE(hwcso); 185 } 186 187 static void 188 lima_set_vertex_buffers(struct pipe_context *pctx, 189 unsigned start_slot, unsigned count, 190 unsigned unbind_num_trailing_slots, 191 bool take_ownership, 192 const struct pipe_vertex_buffer *vb) 193 { 194 struct lima_context *ctx = lima_context(pctx); 195 struct lima_context_vertex_buffer *so = &ctx->vertex_buffers; 196 197 util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, 198 vb, start_slot, count, 199 unbind_num_trailing_slots, 200 take_ownership); 201 so->count = util_last_bit(so->enabled_mask); 202 203 ctx->dirty |= LIMA_CONTEXT_DIRTY_VERTEX_BUFF; 204 } 205 206 static void 207 lima_set_viewport_states(struct pipe_context *pctx, 208 unsigned start_slot, 209 unsigned num_viewports, 210 const struct pipe_viewport_state *viewport) 211 { 212 struct lima_context *ctx = lima_context(pctx); 213 214 /* reverse calculate the parameter of glViewport */ 215 ctx->viewport.left = viewport->translate[0] - fabsf(viewport->scale[0]); 216 ctx->viewport.right = viewport->translate[0] + fabsf(viewport->scale[0]); 217 ctx->viewport.bottom = viewport->translate[1] - fabsf(viewport->scale[1]); 218 ctx->viewport.top = viewport->translate[1] + fabsf(viewport->scale[1]); 219 220 /* reverse calculate the parameter of glDepthRange */ 221 float near, far; 222 bool halfz = ctx->rasterizer && ctx->rasterizer->base.clip_halfz; 223 util_viewport_zmin_zmax(viewport, halfz, &near, &far); 224 225 ctx->viewport.near = ctx->rasterizer && ctx->rasterizer->base.depth_clip_near ? near : 0.0f; 226 ctx->viewport.far = ctx->rasterizer && ctx->rasterizer->base.depth_clip_far ? far : 1.0f; 227 228 ctx->viewport.transform = *viewport; 229 ctx->dirty |= LIMA_CONTEXT_DIRTY_VIEWPORT; 230 } 231 232 static void 233 lima_set_scissor_states(struct pipe_context *pctx, 234 unsigned start_slot, 235 unsigned num_scissors, 236 const struct pipe_scissor_state *scissor) 237 { 238 struct lima_context *ctx = lima_context(pctx); 239 240 ctx->scissor = *scissor; 241 ctx->dirty |= LIMA_CONTEXT_DIRTY_SCISSOR; 242 } 243 244 static void 245 lima_set_blend_color(struct pipe_context *pctx, 246 const struct pipe_blend_color *blend_color) 247 { 248 struct lima_context *ctx = lima_context(pctx); 249 250 ctx->blend_color = *blend_color; 251 ctx->dirty |= LIMA_CONTEXT_DIRTY_BLEND_COLOR; 252 } 253 254 static void 255 lima_set_stencil_ref(struct pipe_context *pctx, 256 const struct pipe_stencil_ref stencil_ref) 257 { 258 struct lima_context *ctx = lima_context(pctx); 259 260 ctx->stencil_ref = stencil_ref; 261 ctx->dirty |= LIMA_CONTEXT_DIRTY_STENCIL_REF; 262 } 263 264 static void 265 lima_set_clip_state(struct pipe_context *pctx, 266 const struct pipe_clip_state *clip) 267 { 268 struct lima_context *ctx = lima_context(pctx); 269 ctx->clip = *clip; 270 271 ctx->dirty |= LIMA_CONTEXT_DIRTY_CLIP; 272 } 273 274 static void 275 lima_set_constant_buffer(struct pipe_context *pctx, 276 enum pipe_shader_type shader, uint index, 277 bool pass_reference, 278 const struct pipe_constant_buffer *cb) 279 { 280 struct lima_context *ctx = lima_context(pctx); 281 struct lima_context_constant_buffer *so = ctx->const_buffer + shader; 282 283 assert(index == 0); 284 285 if (unlikely(!cb)) { 286 so->buffer = NULL; 287 so->size = 0; 288 } else { 289 assert(!cb->buffer); 290 291 so->buffer = cb->user_buffer + cb->buffer_offset; 292 so->size = cb->buffer_size; 293 } 294 295 so->dirty = true; 296 ctx->dirty |= LIMA_CONTEXT_DIRTY_CONST_BUFF; 297 298 } 299 300 static void * 301 lima_create_sampler_state(struct pipe_context *pctx, 302 const struct pipe_sampler_state *cso) 303 { 304 struct lima_sampler_state *so = CALLOC_STRUCT(lima_sampler_state); 305 if (!so) 306 return NULL; 307 308 memcpy(so, cso, sizeof(*cso)); 309 310 return so; 311 } 312 313 static void 314 lima_sampler_state_delete(struct pipe_context *pctx, void *sstate) 315 { 316 free(sstate); 317 } 318 319 static void 320 lima_sampler_states_bind(struct pipe_context *pctx, 321 enum pipe_shader_type shader, unsigned start, 322 unsigned nr, void **hwcso) 323 { 324 struct lima_context *ctx = lima_context(pctx); 325 struct lima_texture_stateobj *lima_tex = &ctx->tex_stateobj; 326 unsigned i; 327 unsigned new_nr = 0; 328 329 assert(start == 0); 330 331 for (i = 0; i < nr; i++) { 332 if (hwcso[i]) 333 new_nr = i + 1; 334 lima_tex->samplers[i] = hwcso[i]; 335 } 336 337 for (; i < lima_tex->num_samplers; i++) { 338 lima_tex->samplers[i] = NULL; 339 } 340 341 lima_tex->num_samplers = new_nr; 342 ctx->dirty |= LIMA_CONTEXT_DIRTY_TEXTURES; 343 } 344 345 static struct pipe_sampler_view * 346 lima_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, 347 const struct pipe_sampler_view *cso) 348 { 349 struct lima_sampler_view *so = CALLOC_STRUCT(lima_sampler_view); 350 351 if (!so) 352 return NULL; 353 354 so->base = *cso; 355 356 pipe_reference(NULL, &prsc->reference); 357 so->base.texture = prsc; 358 so->base.reference.count = 1; 359 so->base.context = pctx; 360 361 uint8_t sampler_swizzle[4] = { cso->swizzle_r, cso->swizzle_g, 362 cso->swizzle_b, cso->swizzle_a }; 363 const uint8_t *format_swizzle = lima_format_get_texel_swizzle(cso->format); 364 util_format_compose_swizzles(format_swizzle, sampler_swizzle, so->swizzle); 365 366 return &so->base; 367 } 368 369 static void 370 lima_sampler_view_destroy(struct pipe_context *pctx, 371 struct pipe_sampler_view *pview) 372 { 373 struct lima_sampler_view *view = lima_sampler_view(pview); 374 375 pipe_resource_reference(&pview->texture, NULL); 376 377 free(view); 378 } 379 380 static void 381 lima_set_sampler_views(struct pipe_context *pctx, 382 enum pipe_shader_type shader, 383 unsigned start, unsigned nr, 384 unsigned unbind_num_trailing_slots, 385 bool take_ownership, 386 struct pipe_sampler_view **views) 387 { 388 struct lima_context *ctx = lima_context(pctx); 389 struct lima_texture_stateobj *lima_tex = &ctx->tex_stateobj; 390 int i; 391 unsigned new_nr = 0; 392 393 assert(start == 0); 394 395 for (i = 0; i < nr; i++) { 396 if (views[i]) 397 new_nr = i + 1; 398 399 if (take_ownership) { 400 pipe_sampler_view_reference(&lima_tex->textures[i], NULL); 401 lima_tex->textures[i] = views[i]; 402 } else { 403 pipe_sampler_view_reference(&lima_tex->textures[i], views[i]); 404 } 405 } 406 407 for (; i < lima_tex->num_textures; i++) { 408 pipe_sampler_view_reference(&lima_tex->textures[i], NULL); 409 } 410 411 lima_tex->num_textures = new_nr; 412 ctx->dirty |= LIMA_CONTEXT_DIRTY_TEXTURES; 413 } 414 415 static void 416 lima_set_sample_mask(struct pipe_context *pctx, 417 unsigned sample_mask) 418 { 419 } 420 421 void 422 lima_state_init(struct lima_context *ctx) 423 { 424 ctx->base.set_framebuffer_state = lima_set_framebuffer_state; 425 ctx->base.set_polygon_stipple = lima_set_polygon_stipple; 426 ctx->base.set_viewport_states = lima_set_viewport_states; 427 ctx->base.set_scissor_states = lima_set_scissor_states; 428 ctx->base.set_blend_color = lima_set_blend_color; 429 ctx->base.set_stencil_ref = lima_set_stencil_ref; 430 ctx->base.set_clip_state = lima_set_clip_state; 431 432 ctx->base.set_vertex_buffers = lima_set_vertex_buffers; 433 ctx->base.set_constant_buffer = lima_set_constant_buffer; 434 435 ctx->base.create_depth_stencil_alpha_state = lima_create_depth_stencil_alpha_state; 436 ctx->base.bind_depth_stencil_alpha_state = lima_bind_depth_stencil_alpha_state; 437 ctx->base.delete_depth_stencil_alpha_state = lima_delete_depth_stencil_alpha_state; 438 439 ctx->base.create_rasterizer_state = lima_create_rasterizer_state; 440 ctx->base.bind_rasterizer_state = lima_bind_rasterizer_state; 441 ctx->base.delete_rasterizer_state = lima_delete_rasterizer_state; 442 443 ctx->base.create_blend_state = lima_create_blend_state; 444 ctx->base.bind_blend_state = lima_bind_blend_state; 445 ctx->base.delete_blend_state = lima_delete_blend_state; 446 447 ctx->base.create_vertex_elements_state = lima_create_vertex_elements_state; 448 ctx->base.bind_vertex_elements_state = lima_bind_vertex_elements_state; 449 ctx->base.delete_vertex_elements_state = lima_delete_vertex_elements_state; 450 451 ctx->base.create_sampler_state = lima_create_sampler_state; 452 ctx->base.delete_sampler_state = lima_sampler_state_delete; 453 ctx->base.bind_sampler_states = lima_sampler_states_bind; 454 455 ctx->base.create_sampler_view = lima_create_sampler_view; 456 ctx->base.sampler_view_destroy = lima_sampler_view_destroy; 457 ctx->base.set_sampler_views = lima_set_sampler_views; 458 459 ctx->base.set_sample_mask = lima_set_sample_mask; 460 } 461 462 void 463 lima_state_fini(struct lima_context *ctx) 464 { 465 struct lima_context_vertex_buffer *so = &ctx->vertex_buffers; 466 467 util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, NULL, 468 0, 0, ARRAY_SIZE(so->vb), false); 469 470 pipe_surface_reference(&ctx->framebuffer.base.cbufs[0], NULL); 471 pipe_surface_reference(&ctx->framebuffer.base.zsbuf, NULL); 472 } 473