2 * Copyright © 2014-2017 Broadcom
3 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
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, sublicense,
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:
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 NONINFRINGEMENT. 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 DEALINGS
25 #include "pipe/p_state.h"
26 #include "util/format/u_format.h"
27 #include "util/u_framebuffer.h"
28 #include "util/u_inlines.h"
29 #include "util/u_math.h"
30 #include "util/u_memory.h"
31 #include "util/u_half.h"
32 #include "util/u_helpers.h"
33 #include "util/u_upload_mgr.h"
35 #include "v3d_context.h"
36 #include "v3d_tiling.h"
37 #include "broadcom/common/v3d_macros.h"
38 #include "broadcom/compiler/v3d_compiler.h"
39 #include "broadcom/cle/v3dx_pack.h"
42 v3d_generic_cso_state_delete(struct pipe_context
*pctx
, void *hwcso
)
48 v3d_set_blend_color(struct pipe_context
*pctx
,
49 const struct pipe_blend_color
*blend_color
)
51 struct v3d_context
*v3d
= v3d_context(pctx
);
52 v3d
->blend_color
.f
= *blend_color
;
53 for (int i
= 0; i
< 4; i
++) {
54 v3d
->blend_color
.hf
[i
] =
55 util_float_to_half(blend_color
->color
[i
]);
57 v3d
->dirty
|= VC5_DIRTY_BLEND_COLOR
;
61 v3d_set_stencil_ref(struct pipe_context
*pctx
,
62 const struct pipe_stencil_ref
*stencil_ref
)
64 struct v3d_context
*v3d
= v3d_context(pctx
);
65 v3d
->stencil_ref
= *stencil_ref
;
66 v3d
->dirty
|= VC5_DIRTY_STENCIL_REF
;
70 v3d_set_clip_state(struct pipe_context
*pctx
,
71 const struct pipe_clip_state
*clip
)
73 struct v3d_context
*v3d
= v3d_context(pctx
);
75 v3d
->dirty
|= VC5_DIRTY_CLIP
;
79 v3d_set_sample_mask(struct pipe_context
*pctx
, unsigned sample_mask
)
81 struct v3d_context
*v3d
= v3d_context(pctx
);
82 v3d
->sample_mask
= sample_mask
& ((1 << V3D_MAX_SAMPLES
) - 1);
83 v3d
->dirty
|= VC5_DIRTY_SAMPLE_STATE
;
87 v3d_create_rasterizer_state(struct pipe_context
*pctx
,
88 const struct pipe_rasterizer_state
*cso
)
90 struct v3d_rasterizer_state
*so
;
92 so
= CALLOC_STRUCT(v3d_rasterizer_state
);
98 /* Workaround: HW-2726 PTB does not handle zero-size points (BCM2835,
101 so
->point_size
= MAX2(cso
->point_size
, .125f
);
103 STATIC_ASSERT(sizeof(so
->depth_offset
) >=
104 cl_packet_length(DEPTH_OFFSET
));
105 v3dx_pack(&so
->depth_offset
, DEPTH_OFFSET
, depth
) {
106 depth
.depth_offset_factor
= cso
->offset_scale
;
107 depth
.depth_offset_units
= cso
->offset_units
;
110 /* The HW treats polygon offset units based on a Z24 buffer, so we
111 * need to scale up offset_units if we're only Z16.
113 v3dx_pack(&so
->depth_offset_z16
, DEPTH_OFFSET
, depth
) {
114 depth
.depth_offset_factor
= cso
->offset_scale
;
115 depth
.depth_offset_units
= cso
->offset_units
* 256.0;
121 /* Blend state is baked into shaders. */
123 v3d_create_blend_state(struct pipe_context
*pctx
,
124 const struct pipe_blend_state
*cso
)
126 struct v3d_blend_state
*so
;
128 so
= CALLOC_STRUCT(v3d_blend_state
);
134 if (cso
->independent_blend_enable
) {
135 for (int i
= 0; i
< V3D_MAX_DRAW_BUFFERS
; i
++) {
136 so
->blend_enables
|= cso
->rt
[i
].blend_enable
<< i
;
138 /* V3D 4.x is when we got independent blend enables. */
139 assert(V3D_VERSION
>= 40 ||
140 cso
->rt
[i
].blend_enable
== cso
->rt
[0].blend_enable
);
143 if (cso
->rt
[0].blend_enable
)
144 so
->blend_enables
= (1 << V3D_MAX_DRAW_BUFFERS
) - 1;
151 translate_stencil_op(enum pipe_stencil_op op
)
154 case PIPE_STENCIL_OP_KEEP
: return V3D_STENCIL_OP_KEEP
;
155 case PIPE_STENCIL_OP_ZERO
: return V3D_STENCIL_OP_ZERO
;
156 case PIPE_STENCIL_OP_REPLACE
: return V3D_STENCIL_OP_REPLACE
;
157 case PIPE_STENCIL_OP_INCR
: return V3D_STENCIL_OP_INCR
;
158 case PIPE_STENCIL_OP_DECR
: return V3D_STENCIL_OP_DECR
;
159 case PIPE_STENCIL_OP_INCR_WRAP
: return V3D_STENCIL_OP_INCWRAP
;
160 case PIPE_STENCIL_OP_DECR_WRAP
: return V3D_STENCIL_OP_DECWRAP
;
161 case PIPE_STENCIL_OP_INVERT
: return V3D_STENCIL_OP_INVERT
;
163 unreachable("bad stencil op");
167 v3d_create_depth_stencil_alpha_state(struct pipe_context
*pctx
,
168 const struct pipe_depth_stencil_alpha_state
*cso
)
170 struct v3d_depth_stencil_alpha_state
*so
;
172 so
= CALLOC_STRUCT(v3d_depth_stencil_alpha_state
);
178 if (cso
->depth
.enabled
) {
179 switch (cso
->depth
.func
) {
181 case PIPE_FUNC_LEQUAL
:
182 so
->ez_state
= VC5_EZ_LT_LE
;
184 case PIPE_FUNC_GREATER
:
185 case PIPE_FUNC_GEQUAL
:
186 so
->ez_state
= VC5_EZ_GT_GE
;
188 case PIPE_FUNC_NEVER
:
189 case PIPE_FUNC_EQUAL
:
190 so
->ez_state
= VC5_EZ_UNDECIDED
;
193 so
->ez_state
= VC5_EZ_DISABLED
;
197 /* If stencil is enabled and it's not a no-op, then it would
200 if (cso
->stencil
[0].enabled
&&
201 (cso
->stencil
[0].zfail_op
!= PIPE_STENCIL_OP_KEEP
||
202 cso
->stencil
[0].func
!= PIPE_FUNC_ALWAYS
||
203 (cso
->stencil
[1].enabled
&&
204 (cso
->stencil
[1].zfail_op
!= PIPE_STENCIL_OP_KEEP
&&
205 cso
->stencil
[1].func
!= PIPE_FUNC_ALWAYS
)))) {
206 so
->ez_state
= VC5_EZ_DISABLED
;
210 const struct pipe_stencil_state
*front
= &cso
->stencil
[0];
211 const struct pipe_stencil_state
*back
= &cso
->stencil
[1];
213 if (front
->enabled
) {
214 STATIC_ASSERT(sizeof(so
->stencil_front
) >=
215 cl_packet_length(STENCIL_CFG
));
216 v3dx_pack(&so
->stencil_front
, STENCIL_CFG
, config
) {
217 config
.front_config
= true;
218 /* If !back->enabled, then the front values should be
219 * used for both front and back-facing primitives.
221 config
.back_config
= !back
->enabled
;
223 config
.stencil_write_mask
= front
->writemask
;
224 config
.stencil_test_mask
= front
->valuemask
;
226 config
.stencil_test_function
= front
->func
;
227 config
.stencil_pass_op
=
228 translate_stencil_op(front
->zpass_op
);
229 config
.depth_test_fail_op
=
230 translate_stencil_op(front
->zfail_op
);
231 config
.stencil_test_fail_op
=
232 translate_stencil_op(front
->fail_op
);
236 STATIC_ASSERT(sizeof(so
->stencil_back
) >=
237 cl_packet_length(STENCIL_CFG
));
238 v3dx_pack(&so
->stencil_back
, STENCIL_CFG
, config
) {
239 config
.front_config
= false;
240 config
.back_config
= true;
242 config
.stencil_write_mask
= back
->writemask
;
243 config
.stencil_test_mask
= back
->valuemask
;
245 config
.stencil_test_function
= back
->func
;
246 config
.stencil_pass_op
=
247 translate_stencil_op(back
->zpass_op
);
248 config
.depth_test_fail_op
=
249 translate_stencil_op(back
->zfail_op
);
250 config
.stencil_test_fail_op
=
251 translate_stencil_op(back
->fail_op
);
259 v3d_set_polygon_stipple(struct pipe_context
*pctx
,
260 const struct pipe_poly_stipple
*stipple
)
262 struct v3d_context
*v3d
= v3d_context(pctx
);
263 v3d
->stipple
= *stipple
;
264 v3d
->dirty
|= VC5_DIRTY_STIPPLE
;
268 v3d_set_scissor_states(struct pipe_context
*pctx
,
270 unsigned num_scissors
,
271 const struct pipe_scissor_state
*scissor
)
273 struct v3d_context
*v3d
= v3d_context(pctx
);
275 v3d
->scissor
= *scissor
;
276 v3d
->dirty
|= VC5_DIRTY_SCISSOR
;
280 v3d_set_viewport_states(struct pipe_context
*pctx
,
282 unsigned num_viewports
,
283 const struct pipe_viewport_state
*viewport
)
285 struct v3d_context
*v3d
= v3d_context(pctx
);
286 v3d
->viewport
= *viewport
;
287 v3d
->dirty
|= VC5_DIRTY_VIEWPORT
;
291 v3d_set_vertex_buffers(struct pipe_context
*pctx
,
292 unsigned start_slot
, unsigned count
,
293 const struct pipe_vertex_buffer
*vb
)
295 struct v3d_context
*v3d
= v3d_context(pctx
);
296 struct v3d_vertexbuf_stateobj
*so
= &v3d
->vertexbuf
;
298 util_set_vertex_buffers_mask(so
->vb
, &so
->enabled_mask
, vb
,
300 so
->count
= util_last_bit(so
->enabled_mask
);
302 v3d
->dirty
|= VC5_DIRTY_VTXBUF
;
306 v3d_blend_state_bind(struct pipe_context
*pctx
, void *hwcso
)
308 struct v3d_context
*v3d
= v3d_context(pctx
);
310 v3d
->dirty
|= VC5_DIRTY_BLEND
;
314 v3d_rasterizer_state_bind(struct pipe_context
*pctx
, void *hwcso
)
316 struct v3d_context
*v3d
= v3d_context(pctx
);
317 v3d
->rasterizer
= hwcso
;
318 v3d
->dirty
|= VC5_DIRTY_RASTERIZER
;
322 v3d_zsa_state_bind(struct pipe_context
*pctx
, void *hwcso
)
324 struct v3d_context
*v3d
= v3d_context(pctx
);
326 v3d
->dirty
|= VC5_DIRTY_ZSA
;
330 v3d_vertex_state_create(struct pipe_context
*pctx
, unsigned num_elements
,
331 const struct pipe_vertex_element
*elements
)
333 struct v3d_context
*v3d
= v3d_context(pctx
);
334 struct v3d_vertex_stateobj
*so
= CALLOC_STRUCT(v3d_vertex_stateobj
);
339 memcpy(so
->pipe
, elements
, sizeof(*elements
) * num_elements
);
340 so
->num_elements
= num_elements
;
342 for (int i
= 0; i
< so
->num_elements
; i
++) {
343 const struct pipe_vertex_element
*elem
= &elements
[i
];
344 const struct util_format_description
*desc
=
345 util_format_description(elem
->src_format
);
346 uint32_t r_size
= desc
->channel
[0].size
;
348 const uint32_t size
=
349 cl_packet_length(GL_SHADER_STATE_ATTRIBUTE_RECORD
);
351 v3dx_pack(&so
->attrs
[i
* size
],
352 GL_SHADER_STATE_ATTRIBUTE_RECORD
, attr
) {
353 /* vec_size == 0 means 4 */
354 attr
.vec_size
= desc
->nr_channels
& 3;
355 attr
.signed_int_type
= (desc
->channel
[0].type
==
356 UTIL_FORMAT_TYPE_SIGNED
);
358 attr
.normalized_int_type
= desc
->channel
[0].normalized
;
359 attr
.read_as_int_uint
= desc
->channel
[0].pure_integer
;
360 attr
.instance_divisor
= MIN2(elem
->instance_divisor
,
363 switch (desc
->channel
[0].type
) {
364 case UTIL_FORMAT_TYPE_FLOAT
:
366 attr
.type
= ATTRIBUTE_FLOAT
;
368 assert(r_size
== 16);
369 attr
.type
= ATTRIBUTE_HALF_FLOAT
;
373 case UTIL_FORMAT_TYPE_SIGNED
:
374 case UTIL_FORMAT_TYPE_UNSIGNED
:
377 attr
.type
= ATTRIBUTE_INT
;
380 attr
.type
= ATTRIBUTE_SHORT
;
383 attr
.type
= ATTRIBUTE_INT2_10_10_10
;
386 attr
.type
= ATTRIBUTE_BYTE
;
390 "format %s unsupported\n",
392 attr
.type
= ATTRIBUTE_BYTE
;
399 "format %s unsupported\n",
406 /* Set up the default attribute values in case any of the vertex
410 u_upload_alloc(v3d
->state_uploader
, 0,
411 V3D_MAX_VS_INPUTS
* sizeof(float), 16,
412 &so
->defaults_offset
, &so
->defaults
, (void **)&attrs
);
414 for (int i
= 0; i
< V3D_MAX_VS_INPUTS
/ 4; i
++) {
415 attrs
[i
* 4 + 0] = 0;
416 attrs
[i
* 4 + 1] = 0;
417 attrs
[i
* 4 + 2] = 0;
418 if (i
< so
->num_elements
&&
419 util_format_is_pure_integer(so
->pipe
[i
].src_format
)) {
420 attrs
[i
* 4 + 3] = 1;
422 attrs
[i
* 4 + 3] = fui(1.0);
426 u_upload_unmap(v3d
->state_uploader
);
431 v3d_vertex_state_delete(struct pipe_context
*pctx
, void *hwcso
)
433 struct v3d_vertex_stateobj
*so
= hwcso
;
435 pipe_resource_reference(&so
->defaults
, NULL
);
440 v3d_vertex_state_bind(struct pipe_context
*pctx
, void *hwcso
)
442 struct v3d_context
*v3d
= v3d_context(pctx
);
444 v3d
->dirty
|= VC5_DIRTY_VTXSTATE
;
448 v3d_set_constant_buffer(struct pipe_context
*pctx
, uint shader
, uint index
,
449 const struct pipe_constant_buffer
*cb
)
451 struct v3d_context
*v3d
= v3d_context(pctx
);
452 struct v3d_constbuf_stateobj
*so
= &v3d
->constbuf
[shader
];
454 util_copy_constant_buffer(&so
->cb
[index
], cb
);
456 /* Note that the gallium frontend can unbind constant buffers by
460 so
->enabled_mask
&= ~(1 << index
);
461 so
->dirty_mask
&= ~(1 << index
);
465 so
->enabled_mask
|= 1 << index
;
466 so
->dirty_mask
|= 1 << index
;
467 v3d
->dirty
|= VC5_DIRTY_CONSTBUF
;
471 v3d_set_framebuffer_state(struct pipe_context
*pctx
,
472 const struct pipe_framebuffer_state
*framebuffer
)
474 struct v3d_context
*v3d
= v3d_context(pctx
);
475 struct pipe_framebuffer_state
*cso
= &v3d
->framebuffer
;
479 util_copy_framebuffer_state(cso
, framebuffer
);
481 v3d
->swap_color_rb
= 0;
482 v3d
->blend_dst_alpha_one
= 0;
483 for (int i
= 0; i
< v3d
->framebuffer
.nr_cbufs
; i
++) {
484 struct pipe_surface
*cbuf
= v3d
->framebuffer
.cbufs
[i
];
487 struct v3d_surface
*v3d_cbuf
= v3d_surface(cbuf
);
489 const struct util_format_description
*desc
=
490 util_format_description(cbuf
->format
);
492 /* For BGRA8 formats (DRI window system default format), we
493 * need to swap R and B, since the HW's format is RGBA8. On
494 * V3D 4.1+, the RCL can swap R and B on load/store.
496 if (v3d
->screen
->devinfo
.ver
< 41 && v3d_cbuf
->swap_rb
)
497 v3d
->swap_color_rb
|= 1 << i
;
499 if (desc
->swizzle
[3] == PIPE_SWIZZLE_1
)
500 v3d
->blend_dst_alpha_one
|= 1 << i
;
503 v3d
->dirty
|= VC5_DIRTY_FRAMEBUFFER
;
506 static enum V3DX(Wrap_Mode
)
507 translate_wrap(uint32_t pipe_wrap
, bool using_nearest
)
510 case PIPE_TEX_WRAP_REPEAT
:
511 return V3D_WRAP_MODE_REPEAT
;
512 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
:
513 return V3D_WRAP_MODE_CLAMP
;
514 case PIPE_TEX_WRAP_MIRROR_REPEAT
:
515 return V3D_WRAP_MODE_MIRROR
;
516 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
:
517 return V3D_WRAP_MODE_BORDER
;
518 case PIPE_TEX_WRAP_CLAMP
:
519 return (using_nearest
?
520 V3D_WRAP_MODE_CLAMP
:
521 V3D_WRAP_MODE_BORDER
);
523 unreachable("Unknown wrap mode");
527 #if V3D_VERSION >= 40
529 v3d_upload_sampler_state_variant(void *map
,
530 const struct pipe_sampler_state
*cso
,
531 enum v3d_sampler_state_variant variant
,
534 v3dx_pack(map
, SAMPLER_STATE
, sampler
) {
535 sampler
.wrap_i_border
= false;
537 sampler
.wrap_s
= translate_wrap(cso
->wrap_s
, either_nearest
);
538 sampler
.wrap_t
= translate_wrap(cso
->wrap_t
, either_nearest
);
539 sampler
.wrap_r
= translate_wrap(cso
->wrap_r
, either_nearest
);
541 sampler
.fixed_bias
= cso
->lod_bias
;
542 sampler
.depth_compare_function
= cso
->compare_func
;
544 sampler
.min_filter_nearest
=
545 cso
->min_img_filter
== PIPE_TEX_FILTER_NEAREST
;
546 sampler
.mag_filter_nearest
=
547 cso
->mag_img_filter
== PIPE_TEX_FILTER_NEAREST
;
548 sampler
.mip_filter_nearest
=
549 cso
->min_mip_filter
!= PIPE_TEX_MIPFILTER_LINEAR
;
551 sampler
.min_level_of_detail
= MIN2(MAX2(0, cso
->min_lod
),
553 sampler
.max_level_of_detail
= MIN2(cso
->max_lod
, 15);
555 /* If we're not doing inter-miplevel filtering, we need to
556 * clamp the LOD so that we only sample from baselevel.
557 * However, we need to still allow the calculated LOD to be
558 * fractionally over the baselevel, so that the HW can decide
559 * between the min and mag filters.
561 if (cso
->min_mip_filter
== PIPE_TEX_MIPFILTER_NONE
) {
562 sampler
.min_level_of_detail
=
563 MIN2(sampler
.min_level_of_detail
, 1.0 / 256.0);
564 sampler
.max_level_of_detail
=
565 MIN2(sampler
.max_level_of_detail
, 1.0 / 256.0);
568 if (cso
->max_anisotropy
) {
569 sampler
.anisotropy_enable
= true;
571 if (cso
->max_anisotropy
> 8)
572 sampler
.maximum_anisotropy
= 3;
573 else if (cso
->max_anisotropy
> 4)
574 sampler
.maximum_anisotropy
= 2;
575 else if (cso
->max_anisotropy
> 2)
576 sampler
.maximum_anisotropy
= 1;
579 if (variant
== V3D_SAMPLER_STATE_BORDER_0
) {
580 sampler
.border_color_mode
= V3D_BORDER_COLOR_0000
;
582 sampler
.border_color_mode
= V3D_BORDER_COLOR_FOLLOWS
;
584 union pipe_color_union border
;
586 /* First, reswizzle the border color for any
587 * mismatching we're doing between the texture's
588 * channel order in hardware (R) versus what it is at
589 * the GL level (ALPHA)
592 case V3D_SAMPLER_STATE_F16_BGRA
:
593 case V3D_SAMPLER_STATE_F16_BGRA_UNORM
:
594 case V3D_SAMPLER_STATE_F16_BGRA_SNORM
:
595 border
.i
[0] = cso
->border_color
.i
[2];
596 border
.i
[1] = cso
->border_color
.i
[1];
597 border
.i
[2] = cso
->border_color
.i
[0];
598 border
.i
[3] = cso
->border_color
.i
[3];
601 case V3D_SAMPLER_STATE_F16_A
:
602 case V3D_SAMPLER_STATE_F16_A_UNORM
:
603 case V3D_SAMPLER_STATE_F16_A_SNORM
:
604 case V3D_SAMPLER_STATE_32_A
:
605 case V3D_SAMPLER_STATE_32_A_UNORM
:
606 case V3D_SAMPLER_STATE_32_A_SNORM
:
607 border
.i
[0] = cso
->border_color
.i
[3];
613 case V3D_SAMPLER_STATE_F16_LA
:
614 case V3D_SAMPLER_STATE_F16_LA_UNORM
:
615 case V3D_SAMPLER_STATE_F16_LA_SNORM
:
616 border
.i
[0] = cso
->border_color
.i
[0];
617 border
.i
[1] = cso
->border_color
.i
[3];
623 border
= cso
->border_color
;
626 /* Perform any clamping. */
628 case V3D_SAMPLER_STATE_F16_UNORM
:
629 case V3D_SAMPLER_STATE_F16_BGRA_UNORM
:
630 case V3D_SAMPLER_STATE_F16_A_UNORM
:
631 case V3D_SAMPLER_STATE_F16_LA_UNORM
:
632 case V3D_SAMPLER_STATE_32_UNORM
:
633 case V3D_SAMPLER_STATE_32_A_UNORM
:
634 for (int i
= 0; i
< 4; i
++)
635 border
.f
[i
] = CLAMP(border
.f
[i
], 0, 1);
638 case V3D_SAMPLER_STATE_F16_SNORM
:
639 case V3D_SAMPLER_STATE_F16_BGRA_SNORM
:
640 case V3D_SAMPLER_STATE_F16_A_SNORM
:
641 case V3D_SAMPLER_STATE_F16_LA_SNORM
:
642 case V3D_SAMPLER_STATE_32_SNORM
:
643 case V3D_SAMPLER_STATE_32_A_SNORM
:
644 for (int i
= 0; i
< 4; i
++)
645 border
.f
[i
] = CLAMP(border
.f
[i
], -1, 1);
648 case V3D_SAMPLER_STATE_1010102U
:
649 border
.ui
[0] = CLAMP(border
.ui
[0],
651 border
.ui
[1] = CLAMP(border
.ui
[1],
653 border
.ui
[2] = CLAMP(border
.ui
[2],
655 border
.ui
[3] = CLAMP(border
.ui
[3],
659 case V3D_SAMPLER_STATE_16U
:
660 for (int i
= 0; i
< 4; i
++)
661 border
.ui
[i
] = CLAMP(border
.ui
[i
],
665 case V3D_SAMPLER_STATE_16I
:
666 for (int i
= 0; i
< 4; i
++)
667 border
.i
[i
] = CLAMP(border
.i
[i
],
671 case V3D_SAMPLER_STATE_8U
:
672 for (int i
= 0; i
< 4; i
++)
673 border
.ui
[i
] = CLAMP(border
.ui
[i
],
677 case V3D_SAMPLER_STATE_8I
:
678 for (int i
= 0; i
< 4; i
++)
679 border
.i
[i
] = CLAMP(border
.i
[i
],
687 if (variant
>= V3D_SAMPLER_STATE_32
) {
688 sampler
.border_color_word_0
= border
.ui
[0];
689 sampler
.border_color_word_1
= border
.ui
[1];
690 sampler
.border_color_word_2
= border
.ui
[2];
691 sampler
.border_color_word_3
= border
.ui
[3];
693 sampler
.border_color_word_0
=
694 util_float_to_half(border
.f
[0]);
695 sampler
.border_color_word_1
=
696 util_float_to_half(border
.f
[1]);
697 sampler
.border_color_word_2
=
698 util_float_to_half(border
.f
[2]);
699 sampler
.border_color_word_3
=
700 util_float_to_half(border
.f
[3]);
708 v3d_create_sampler_state(struct pipe_context
*pctx
,
709 const struct pipe_sampler_state
*cso
)
711 UNUSED
struct v3d_context
*v3d
= v3d_context(pctx
);
712 struct v3d_sampler_state
*so
= CALLOC_STRUCT(v3d_sampler_state
);
717 memcpy(so
, cso
, sizeof(*cso
));
719 bool either_nearest
=
720 (cso
->mag_img_filter
== PIPE_TEX_MIPFILTER_NEAREST
||
721 cso
->min_img_filter
== PIPE_TEX_MIPFILTER_NEAREST
);
723 enum V3DX(Wrap_Mode
) wrap_s
= translate_wrap(cso
->wrap_s
,
725 enum V3DX(Wrap_Mode
) wrap_t
= translate_wrap(cso
->wrap_t
,
727 enum V3DX(Wrap_Mode
) wrap_r
= translate_wrap(cso
->wrap_r
,
730 bool uses_border_color
= (wrap_s
== V3D_WRAP_MODE_BORDER
||
731 wrap_t
== V3D_WRAP_MODE_BORDER
||
732 wrap_r
== V3D_WRAP_MODE_BORDER
);
733 so
->border_color_variants
= (uses_border_color
&&
734 (cso
->border_color
.ui
[0] != 0 ||
735 cso
->border_color
.ui
[1] != 0 ||
736 cso
->border_color
.ui
[2] != 0 ||
737 cso
->border_color
.ui
[3] != 0));
739 #if V3D_VERSION >= 40
741 int sampler_align
= so
->border_color_variants
? 32 : 8;
742 int sampler_size
= align(cl_packet_length(SAMPLER_STATE
), sampler_align
);
743 int num_variants
= (so
->border_color_variants
? ARRAY_SIZE(so
->sampler_state_offset
) : 1);
744 u_upload_alloc(v3d
->state_uploader
, 0,
745 sampler_size
* num_variants
,
747 &so
->sampler_state_offset
[0],
751 for (int i
= 0; i
< num_variants
; i
++) {
752 so
->sampler_state_offset
[i
] =
753 so
->sampler_state_offset
[0] + i
* sampler_size
;
754 v3d_upload_sampler_state_variant(map
+ i
* sampler_size
,
755 cso
, i
, either_nearest
);
758 #else /* V3D_VERSION < 40 */
759 v3dx_pack(&so
->p0
, TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1
, p0
) {
760 p0
.s_wrap_mode
= wrap_s
;
761 p0
.t_wrap_mode
= wrap_t
;
762 p0
.r_wrap_mode
= wrap_r
;
765 v3dx_pack(&so
->texture_shader_state
, TEXTURE_SHADER_STATE
, tex
) {
766 tex
.depth_compare_function
= cso
->compare_func
;
767 tex
.fixed_bias
= cso
->lod_bias
;
769 #endif /* V3D_VERSION < 40 */
774 v3d_flag_dirty_sampler_state(struct v3d_context
*v3d
,
775 enum pipe_shader_type shader
)
778 case PIPE_SHADER_VERTEX
:
779 v3d
->dirty
|= VC5_DIRTY_VERTTEX
;
781 case PIPE_SHADER_GEOMETRY
:
782 v3d
->dirty
|= VC5_DIRTY_GEOMTEX
;
784 case PIPE_SHADER_FRAGMENT
:
785 v3d
->dirty
|= VC5_DIRTY_FRAGTEX
;
787 case PIPE_SHADER_COMPUTE
:
788 v3d
->dirty
|= VC5_DIRTY_COMPTEX
;
791 unreachable("Unsupported shader stage");
796 v3d_sampler_states_bind(struct pipe_context
*pctx
,
797 enum pipe_shader_type shader
, unsigned start
,
798 unsigned nr
, void **hwcso
)
800 struct v3d_context
*v3d
= v3d_context(pctx
);
801 struct v3d_texture_stateobj
*stage_tex
= &v3d
->tex
[shader
];
807 for (i
= 0; i
< nr
; i
++) {
810 stage_tex
->samplers
[i
] = hwcso
[i
];
813 for (; i
< stage_tex
->num_samplers
; i
++) {
814 stage_tex
->samplers
[i
] = NULL
;
817 stage_tex
->num_samplers
= new_nr
;
819 v3d_flag_dirty_sampler_state(v3d
, shader
);
823 v3d_sampler_state_delete(struct pipe_context
*pctx
,
826 struct pipe_sampler_state
*psampler
= hwcso
;
827 struct v3d_sampler_state
*sampler
= v3d_sampler_state(psampler
);
829 pipe_resource_reference(&sampler
->sampler_state
, NULL
);
833 #if V3D_VERSION >= 40
835 translate_swizzle(unsigned char pipe_swizzle
)
837 switch (pipe_swizzle
) {
846 return 2 + pipe_swizzle
;
848 unreachable("unknown swizzle");
854 v3d_setup_texture_shader_state(struct V3DX(TEXTURE_SHADER_STATE
) *tex
,
855 struct pipe_resource
*prsc
,
856 int base_level
, int last_level
,
857 int first_layer
, int last_layer
)
859 struct v3d_resource
*rsc
= v3d_resource(prsc
);
860 int msaa_scale
= prsc
->nr_samples
> 1 ? 2 : 1;
862 tex
->image_width
= prsc
->width0
* msaa_scale
;
863 tex
->image_height
= prsc
->height0
* msaa_scale
;
865 #if V3D_VERSION >= 40
866 /* On 4.x, the height of a 1D texture is redefined to be the
867 * upper 14 bits of the width (which is only usable with txf).
869 if (prsc
->target
== PIPE_TEXTURE_1D
||
870 prsc
->target
== PIPE_TEXTURE_1D_ARRAY
) {
871 tex
->image_height
= tex
->image_width
>> 14;
874 tex
->image_width
&= (1 << 14) - 1;
875 tex
->image_height
&= (1 << 14) - 1;
878 if (prsc
->target
== PIPE_TEXTURE_3D
) {
879 tex
->image_depth
= prsc
->depth0
;
881 tex
->image_depth
= (last_layer
- first_layer
) + 1;
884 tex
->base_level
= base_level
;
885 #if V3D_VERSION >= 40
886 tex
->max_level
= last_level
;
887 /* Note that we don't have a job to reference the texture's sBO
888 * at state create time, so any time this sampler view is used
889 * we need to add the texture to the job.
891 tex
->texture_base_pointer
=
894 v3d_layer_offset(prsc
, 0, first_layer
));
896 tex
->array_stride_64_byte_aligned
= rsc
->cube_map_stride
/ 64;
898 /* Since other platform devices may produce UIF images even
899 * when they're not big enough for V3D to assume they're UIF,
900 * we force images with level 0 as UIF to be always treated
903 tex
->level_0_is_strictly_uif
=
904 (rsc
->slices
[0].tiling
== VC5_TILING_UIF_XOR
||
905 rsc
->slices
[0].tiling
== VC5_TILING_UIF_NO_XOR
);
906 tex
->level_0_xor_enable
= (rsc
->slices
[0].tiling
== VC5_TILING_UIF_XOR
);
908 if (tex
->level_0_is_strictly_uif
)
909 tex
->level_0_ub_pad
= rsc
->slices
[0].ub_pad
;
911 #if V3D_VERSION >= 40
912 if (tex
->uif_xor_disable
||
913 tex
->level_0_is_strictly_uif
) {
914 tex
->extended
= true;
916 #endif /* V3D_VERSION >= 40 */
919 static struct pipe_sampler_view
*
920 v3d_create_sampler_view(struct pipe_context
*pctx
, struct pipe_resource
*prsc
,
921 const struct pipe_sampler_view
*cso
)
923 struct v3d_context
*v3d
= v3d_context(pctx
);
924 struct v3d_screen
*screen
= v3d
->screen
;
925 struct v3d_sampler_view
*so
= CALLOC_STRUCT(v3d_sampler_view
);
926 struct v3d_resource
*rsc
= v3d_resource(prsc
);
933 pipe_reference(NULL
, &prsc
->reference
);
935 /* Compute the sampler view's swizzle up front. This will be plugged
936 * into either the sampler (for 16-bit returns) or the shader's
937 * texture key (for 32)
939 uint8_t view_swizzle
[4] = {
945 const uint8_t *fmt_swizzle
=
946 v3d_get_format_swizzle(&screen
->devinfo
, so
->base
.format
);
947 util_format_compose_swizzles(fmt_swizzle
, view_swizzle
, so
->swizzle
);
949 so
->base
.texture
= prsc
;
950 so
->base
.reference
.count
= 1;
951 so
->base
.context
= pctx
;
953 if (rsc
->separate_stencil
&&
954 cso
->format
== PIPE_FORMAT_X32_S8X24_UINT
) {
955 rsc
= rsc
->separate_stencil
;
959 /* If we're sampling depth from depth/stencil, demote the format to
960 * just depth. u_format will end up giving the answers for the
961 * stencil channel, otherwise.
963 enum pipe_format sample_format
= cso
->format
;
964 if (sample_format
== PIPE_FORMAT_S8_UINT_Z24_UNORM
)
965 sample_format
= PIPE_FORMAT_X8Z24_UNORM
;
967 #if V3D_VERSION >= 40
968 const struct util_format_description
*desc
=
969 util_format_description(sample_format
);
971 if (util_format_is_pure_integer(sample_format
) &&
972 !util_format_has_depth(desc
)) {
973 int chan
= util_format_get_first_non_void_channel(sample_format
);
974 if (util_format_is_pure_uint(sample_format
)) {
975 switch (desc
->channel
[chan
].size
) {
977 so
->sampler_variant
= V3D_SAMPLER_STATE_32
;
980 so
->sampler_variant
= V3D_SAMPLER_STATE_16U
;
983 so
->sampler_variant
= V3D_SAMPLER_STATE_1010102U
;
986 so
->sampler_variant
= V3D_SAMPLER_STATE_8U
;
990 switch (desc
->channel
[chan
].size
) {
992 so
->sampler_variant
= V3D_SAMPLER_STATE_32
;
995 so
->sampler_variant
= V3D_SAMPLER_STATE_16I
;
998 so
->sampler_variant
= V3D_SAMPLER_STATE_8I
;
1003 if (v3d_get_tex_return_size(&screen
->devinfo
, sample_format
,
1004 PIPE_TEX_COMPARE_NONE
) == 32) {
1005 if (util_format_is_alpha(sample_format
))
1006 so
->sampler_variant
= V3D_SAMPLER_STATE_32_A
;
1008 so
->sampler_variant
= V3D_SAMPLER_STATE_32
;
1010 if (util_format_is_luminance_alpha(sample_format
))
1011 so
->sampler_variant
= V3D_SAMPLER_STATE_F16_LA
;
1012 else if (util_format_is_alpha(sample_format
))
1013 so
->sampler_variant
= V3D_SAMPLER_STATE_F16_A
;
1014 else if (fmt_swizzle
[0] == PIPE_SWIZZLE_Z
)
1015 so
->sampler_variant
= V3D_SAMPLER_STATE_F16_BGRA
;
1017 so
->sampler_variant
= V3D_SAMPLER_STATE_F16
;
1021 if (util_format_is_unorm(sample_format
)) {
1022 so
->sampler_variant
+= (V3D_SAMPLER_STATE_F16_UNORM
-
1023 V3D_SAMPLER_STATE_F16
);
1024 } else if (util_format_is_snorm(sample_format
)){
1025 so
->sampler_variant
+= (V3D_SAMPLER_STATE_F16_SNORM
-
1026 V3D_SAMPLER_STATE_F16
);
1031 /* V3D still doesn't support sampling from raster textures, so we will
1032 * have to copy to a temporary tiled texture.
1034 if (!rsc
->tiled
&& !(prsc
->target
== PIPE_TEXTURE_1D
||
1035 prsc
->target
== PIPE_TEXTURE_1D_ARRAY
)) {
1036 struct v3d_resource
*shadow_parent
= rsc
;
1037 struct pipe_resource tmpl
= {
1038 .target
= prsc
->target
,
1039 .format
= prsc
->format
,
1040 .width0
= u_minify(prsc
->width0
,
1041 cso
->u
.tex
.first_level
),
1042 .height0
= u_minify(prsc
->height0
,
1043 cso
->u
.tex
.first_level
),
1046 .bind
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
,
1047 .last_level
= cso
->u
.tex
.last_level
- cso
->u
.tex
.first_level
,
1048 .nr_samples
= prsc
->nr_samples
,
1051 /* Create the shadow texture. The rest of the sampler view
1052 * setup will use the shadow.
1054 prsc
= v3d_resource_create(pctx
->screen
, &tmpl
);
1059 rsc
= v3d_resource(prsc
);
1061 /* Flag it as needing update of the contents from the parent. */
1062 rsc
->writes
= shadow_parent
->writes
- 1;
1067 pipe_resource_reference(&so
->texture
, prsc
);
1071 #if V3D_VERSION >= 40
1072 so
->bo
= v3d_bo_alloc(v3d
->screen
,
1073 cl_packet_length(TEXTURE_SHADER_STATE
), "sampler");
1074 map
= v3d_bo_map(so
->bo
);
1075 #else /* V3D_VERSION < 40 */
1076 STATIC_ASSERT(sizeof(so
->texture_shader_state
) >=
1077 cl_packet_length(TEXTURE_SHADER_STATE
));
1078 map
= &so
->texture_shader_state
;
1081 v3dx_pack(map
, TEXTURE_SHADER_STATE
, tex
) {
1082 v3d_setup_texture_shader_state(&tex
, prsc
,
1083 cso
->u
.tex
.first_level
,
1084 cso
->u
.tex
.last_level
,
1085 cso
->u
.tex
.first_layer
,
1086 cso
->u
.tex
.last_layer
);
1088 tex
.srgb
= util_format_is_srgb(cso
->format
);
1090 #if V3D_VERSION >= 40
1091 tex
.swizzle_r
= translate_swizzle(so
->swizzle
[0]);
1092 tex
.swizzle_g
= translate_swizzle(so
->swizzle
[1]);
1093 tex
.swizzle_b
= translate_swizzle(so
->swizzle
[2]);
1094 tex
.swizzle_a
= translate_swizzle(so
->swizzle
[3]);
1097 if (prsc
->nr_samples
> 1 && V3D_VERSION
< 40) {
1098 /* Using texture views to reinterpret formats on our
1099 * MSAA textures won't work, because we don't lay out
1100 * the bits in memory as it's expected -- for example,
1101 * RGBA8 and RGB10_A2 are compatible in the
1102 * ARB_texture_view spec, but in HW we lay them out as
1103 * 32bpp RGBA8 and 64bpp RGBA16F. Just assert for now
1104 * to catch failures.
1106 * We explicitly allow remapping S8Z24 to RGBA8888 for
1107 * v3d_blit.c's stencil blits.
1109 assert((util_format_linear(cso
->format
) ==
1110 util_format_linear(prsc
->format
)) ||
1111 (prsc
->format
== PIPE_FORMAT_S8_UINT_Z24_UNORM
&&
1112 cso
->format
== PIPE_FORMAT_R8G8B8A8_UNORM
));
1113 uint32_t output_image_format
=
1114 v3d_get_rt_format(&screen
->devinfo
, cso
->format
);
1115 uint32_t internal_type
;
1116 uint32_t internal_bpp
;
1117 v3d_get_internal_type_bpp_for_output_format(&screen
->devinfo
,
1118 output_image_format
,
1122 switch (internal_type
) {
1123 case V3D_INTERNAL_TYPE_8
:
1124 tex
.texture_type
= TEXTURE_DATA_FORMAT_RGBA8
;
1126 case V3D_INTERNAL_TYPE_16F
:
1127 tex
.texture_type
= TEXTURE_DATA_FORMAT_RGBA16F
;
1130 unreachable("Bad MSAA texture type");
1133 /* sRGB was stored in the tile buffer as linear and
1134 * would have been encoded to sRGB on resolved tile
1135 * buffer store. Note that this means we would need
1136 * shader code if we wanted to read an MSAA sRGB
1137 * texture without sRGB decode.
1141 tex
.texture_type
= v3d_get_tex_format(&screen
->devinfo
,
1150 v3d_sampler_view_destroy(struct pipe_context
*pctx
,
1151 struct pipe_sampler_view
*psview
)
1153 struct v3d_sampler_view
*sview
= v3d_sampler_view(psview
);
1155 v3d_bo_unreference(&sview
->bo
);
1156 pipe_resource_reference(&psview
->texture
, NULL
);
1157 pipe_resource_reference(&sview
->texture
, NULL
);
1162 v3d_set_sampler_views(struct pipe_context
*pctx
,
1163 enum pipe_shader_type shader
,
1164 unsigned start
, unsigned nr
,
1165 struct pipe_sampler_view
**views
)
1167 struct v3d_context
*v3d
= v3d_context(pctx
);
1168 struct v3d_texture_stateobj
*stage_tex
= &v3d
->tex
[shader
];
1170 unsigned new_nr
= 0;
1174 for (i
= 0; i
< nr
; i
++) {
1177 pipe_sampler_view_reference(&stage_tex
->textures
[i
], views
[i
]);
1180 for (; i
< stage_tex
->num_textures
; i
++) {
1181 pipe_sampler_view_reference(&stage_tex
->textures
[i
], NULL
);
1184 stage_tex
->num_textures
= new_nr
;
1186 v3d_flag_dirty_sampler_state(v3d
, shader
);
1189 static struct pipe_stream_output_target
*
1190 v3d_create_stream_output_target(struct pipe_context
*pctx
,
1191 struct pipe_resource
*prsc
,
1192 unsigned buffer_offset
,
1193 unsigned buffer_size
)
1195 struct v3d_stream_output_target
*target
;
1197 target
= CALLOC_STRUCT(v3d_stream_output_target
);
1201 pipe_reference_init(&target
->base
.reference
, 1);
1202 pipe_resource_reference(&target
->base
.buffer
, prsc
);
1204 target
->base
.context
= pctx
;
1205 target
->base
.buffer_offset
= buffer_offset
;
1206 target
->base
.buffer_size
= buffer_size
;
1208 return &target
->base
;
1212 v3d_stream_output_target_destroy(struct pipe_context
*pctx
,
1213 struct pipe_stream_output_target
*target
)
1215 pipe_resource_reference(&target
->buffer
, NULL
);
1220 v3d_set_stream_output_targets(struct pipe_context
*pctx
,
1221 unsigned num_targets
,
1222 struct pipe_stream_output_target
**targets
,
1223 const unsigned *offsets
)
1225 struct v3d_context
*ctx
= v3d_context(pctx
);
1226 struct v3d_streamout_stateobj
*so
= &ctx
->streamout
;
1229 assert(num_targets
<= ARRAY_SIZE(so
->targets
));
1231 /* Update recorded vertex counts when we are ending the recording of
1232 * transform feedback. We do this when we switch primitive types
1233 * at draw time, but if we haven't switched primitives in our last
1234 * draw we need to do it here as well.
1236 if (num_targets
== 0 && so
->num_targets
> 0)
1237 v3d_update_primitive_counters(ctx
);
1239 for (i
= 0; i
< num_targets
; i
++) {
1240 if (offsets
[i
] != -1)
1241 so
->offsets
[i
] = offsets
[i
];
1243 pipe_so_target_reference(&so
->targets
[i
], targets
[i
]);
1246 for (; i
< so
->num_targets
; i
++)
1247 pipe_so_target_reference(&so
->targets
[i
], NULL
);
1249 so
->num_targets
= num_targets
;
1251 /* Create primitive counters BO if needed */
1252 if (num_targets
> 0 && !ctx
->prim_counts
) {
1253 /* Init all 7 counters and 1 padding to 0 */
1254 uint32_t zeroes
[8] = { 0 };
1255 u_upload_data(ctx
->uploader
,
1256 0, sizeof(zeroes
), 32, zeroes
,
1257 &ctx
->prim_counts_offset
,
1261 ctx
->dirty
|= VC5_DIRTY_STREAMOUT
;
1265 v3d_set_shader_buffers(struct pipe_context
*pctx
,
1266 enum pipe_shader_type shader
,
1267 unsigned start
, unsigned count
,
1268 const struct pipe_shader_buffer
*buffers
,
1269 unsigned writable_bitmask
)
1271 struct v3d_context
*v3d
= v3d_context(pctx
);
1272 struct v3d_ssbo_stateobj
*so
= &v3d
->ssbo
[shader
];
1276 for (unsigned i
= 0; i
< count
; i
++) {
1277 unsigned n
= i
+ start
;
1278 struct pipe_shader_buffer
*buf
= &so
->sb
[n
];
1280 if ((buf
->buffer
== buffers
[i
].buffer
) &&
1281 (buf
->buffer_offset
== buffers
[i
].buffer_offset
) &&
1282 (buf
->buffer_size
== buffers
[i
].buffer_size
))
1287 buf
->buffer_offset
= buffers
[i
].buffer_offset
;
1288 buf
->buffer_size
= buffers
[i
].buffer_size
;
1289 pipe_resource_reference(&buf
->buffer
, buffers
[i
].buffer
);
1292 so
->enabled_mask
|= 1 << n
;
1294 so
->enabled_mask
&= ~(1 << n
);
1297 mask
= ((1 << count
) - 1) << start
;
1299 for (unsigned i
= 0; i
< count
; i
++) {
1300 unsigned n
= i
+ start
;
1301 struct pipe_shader_buffer
*buf
= &so
->sb
[n
];
1303 pipe_resource_reference(&buf
->buffer
, NULL
);
1306 so
->enabled_mask
&= ~mask
;
1309 v3d
->dirty
|= VC5_DIRTY_SSBO
;
1313 v3d_create_image_view_texture_shader_state(struct v3d_context
*v3d
,
1314 struct v3d_shaderimg_stateobj
*so
,
1317 #if V3D_VERSION >= 40
1318 struct v3d_image_view
*iview
= &so
->si
[img
];
1321 u_upload_alloc(v3d
->uploader
, 0, cl_packet_length(TEXTURE_SHADER_STATE
),
1323 &iview
->tex_state_offset
,
1327 struct pipe_resource
*prsc
= iview
->base
.resource
;
1329 v3dx_pack(map
, TEXTURE_SHADER_STATE
, tex
) {
1330 v3d_setup_texture_shader_state(&tex
, prsc
,
1331 iview
->base
.u
.tex
.level
,
1332 iview
->base
.u
.tex
.level
,
1333 iview
->base
.u
.tex
.first_layer
,
1334 iview
->base
.u
.tex
.last_layer
);
1336 tex
.swizzle_r
= translate_swizzle(PIPE_SWIZZLE_X
);
1337 tex
.swizzle_g
= translate_swizzle(PIPE_SWIZZLE_Y
);
1338 tex
.swizzle_b
= translate_swizzle(PIPE_SWIZZLE_Z
);
1339 tex
.swizzle_a
= translate_swizzle(PIPE_SWIZZLE_W
);
1341 tex
.texture_type
= v3d_get_tex_format(&v3d
->screen
->devinfo
,
1342 iview
->base
.format
);
1344 #else /* V3D_VERSION < 40 */
1345 /* V3D 3.x doesn't use support shader image load/store operations on
1346 * textures, so it would get lowered in the shader to general memory
1353 v3d_set_shader_images(struct pipe_context
*pctx
,
1354 enum pipe_shader_type shader
,
1355 unsigned start
, unsigned count
,
1356 const struct pipe_image_view
*images
)
1358 struct v3d_context
*v3d
= v3d_context(pctx
);
1359 struct v3d_shaderimg_stateobj
*so
= &v3d
->shaderimg
[shader
];
1362 for (unsigned i
= 0; i
< count
; i
++) {
1363 unsigned n
= i
+ start
;
1364 struct v3d_image_view
*iview
= &so
->si
[n
];
1366 if ((iview
->base
.resource
== images
[i
].resource
) &&
1367 (iview
->base
.format
== images
[i
].format
) &&
1368 (iview
->base
.access
== images
[i
].access
) &&
1369 !memcmp(&iview
->base
.u
, &images
[i
].u
,
1370 sizeof(iview
->base
.u
)))
1373 util_copy_image_view(&iview
->base
, &images
[i
]);
1375 if (iview
->base
.resource
) {
1376 so
->enabled_mask
|= 1 << n
;
1377 v3d_create_image_view_texture_shader_state(v3d
,
1381 so
->enabled_mask
&= ~(1 << n
);
1382 pipe_resource_reference(&iview
->tex_state
, NULL
);
1386 for (unsigned i
= 0; i
< count
; i
++) {
1387 unsigned n
= i
+ start
;
1388 struct v3d_image_view
*iview
= &so
->si
[n
];
1390 pipe_resource_reference(&iview
->base
.resource
, NULL
);
1391 pipe_resource_reference(&iview
->tex_state
, NULL
);
1395 so
->enabled_mask
= 0;
1397 so
->enabled_mask
&= ~(((1 << count
) - 1) << start
);
1400 v3d
->dirty
|= VC5_DIRTY_SHADER_IMAGE
;
1404 v3dX(state_init
)(struct pipe_context
*pctx
)
1406 pctx
->set_blend_color
= v3d_set_blend_color
;
1407 pctx
->set_stencil_ref
= v3d_set_stencil_ref
;
1408 pctx
->set_clip_state
= v3d_set_clip_state
;
1409 pctx
->set_sample_mask
= v3d_set_sample_mask
;
1410 pctx
->set_constant_buffer
= v3d_set_constant_buffer
;
1411 pctx
->set_framebuffer_state
= v3d_set_framebuffer_state
;
1412 pctx
->set_polygon_stipple
= v3d_set_polygon_stipple
;
1413 pctx
->set_scissor_states
= v3d_set_scissor_states
;
1414 pctx
->set_viewport_states
= v3d_set_viewport_states
;
1416 pctx
->set_vertex_buffers
= v3d_set_vertex_buffers
;
1418 pctx
->create_blend_state
= v3d_create_blend_state
;
1419 pctx
->bind_blend_state
= v3d_blend_state_bind
;
1420 pctx
->delete_blend_state
= v3d_generic_cso_state_delete
;
1422 pctx
->create_rasterizer_state
= v3d_create_rasterizer_state
;
1423 pctx
->bind_rasterizer_state
= v3d_rasterizer_state_bind
;
1424 pctx
->delete_rasterizer_state
= v3d_generic_cso_state_delete
;
1426 pctx
->create_depth_stencil_alpha_state
= v3d_create_depth_stencil_alpha_state
;
1427 pctx
->bind_depth_stencil_alpha_state
= v3d_zsa_state_bind
;
1428 pctx
->delete_depth_stencil_alpha_state
= v3d_generic_cso_state_delete
;
1430 pctx
->create_vertex_elements_state
= v3d_vertex_state_create
;
1431 pctx
->delete_vertex_elements_state
= v3d_vertex_state_delete
;
1432 pctx
->bind_vertex_elements_state
= v3d_vertex_state_bind
;
1434 pctx
->create_sampler_state
= v3d_create_sampler_state
;
1435 pctx
->delete_sampler_state
= v3d_sampler_state_delete
;
1436 pctx
->bind_sampler_states
= v3d_sampler_states_bind
;
1438 pctx
->create_sampler_view
= v3d_create_sampler_view
;
1439 pctx
->sampler_view_destroy
= v3d_sampler_view_destroy
;
1440 pctx
->set_sampler_views
= v3d_set_sampler_views
;
1442 pctx
->set_shader_buffers
= v3d_set_shader_buffers
;
1443 pctx
->set_shader_images
= v3d_set_shader_images
;
1445 pctx
->create_stream_output_target
= v3d_create_stream_output_target
;
1446 pctx
->stream_output_target_destroy
= v3d_stream_output_target_destroy
;
1447 pctx
->set_stream_output_targets
= v3d_set_stream_output_targets
;