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/u_format.h"
27 #include "util/u_inlines.h"
28 #include "util/u_math.h"
29 #include "util/u_memory.h"
30 #include "util/u_half.h"
31 #include "util/u_helpers.h"
33 #include "vc5_context.h"
34 #include "vc5_tiling.h"
35 #include "broadcom/common/v3d_macros.h"
36 #include "broadcom/cle/v3dx_pack.h"
39 vc5_generic_cso_state_create(const void *src
, uint32_t size
)
41 void *dst
= calloc(1, size
);
44 memcpy(dst
, src
, size
);
49 vc5_generic_cso_state_delete(struct pipe_context
*pctx
, void *hwcso
)
55 vc5_set_blend_color(struct pipe_context
*pctx
,
56 const struct pipe_blend_color
*blend_color
)
58 struct vc5_context
*vc5
= vc5_context(pctx
);
59 vc5
->blend_color
.f
= *blend_color
;
60 for (int i
= 0; i
< 4; i
++) {
61 vc5
->blend_color
.hf
[i
] =
62 util_float_to_half(blend_color
->color
[i
]);
64 vc5
->dirty
|= VC5_DIRTY_BLEND_COLOR
;
68 vc5_set_stencil_ref(struct pipe_context
*pctx
,
69 const struct pipe_stencil_ref
*stencil_ref
)
71 struct vc5_context
*vc5
= vc5_context(pctx
);
72 vc5
->stencil_ref
= *stencil_ref
;
73 vc5
->dirty
|= VC5_DIRTY_STENCIL_REF
;
77 vc5_set_clip_state(struct pipe_context
*pctx
,
78 const struct pipe_clip_state
*clip
)
80 struct vc5_context
*vc5
= vc5_context(pctx
);
82 vc5
->dirty
|= VC5_DIRTY_CLIP
;
86 vc5_set_sample_mask(struct pipe_context
*pctx
, unsigned sample_mask
)
88 struct vc5_context
*vc5
= vc5_context(pctx
);
89 vc5
->sample_mask
= sample_mask
& ((1 << VC5_MAX_SAMPLES
) - 1);
90 vc5
->dirty
|= VC5_DIRTY_SAMPLE_MASK
;
94 float_to_187_half(float f
)
100 vc5_create_rasterizer_state(struct pipe_context
*pctx
,
101 const struct pipe_rasterizer_state
*cso
)
103 struct vc5_rasterizer_state
*so
;
105 so
= CALLOC_STRUCT(vc5_rasterizer_state
);
111 /* Workaround: HW-2726 PTB does not handle zero-size points (BCM2835,
114 so
->point_size
= MAX2(cso
->point_size
, .125f
);
116 if (cso
->offset_tri
) {
117 so
->offset_units
= float_to_187_half(cso
->offset_units
);
118 so
->offset_factor
= float_to_187_half(cso
->offset_scale
);
124 /* Blend state is baked into shaders. */
126 vc5_create_blend_state(struct pipe_context
*pctx
,
127 const struct pipe_blend_state
*cso
)
129 return vc5_generic_cso_state_create(cso
, sizeof(*cso
));
133 translate_stencil_op(enum pipe_stencil_op op
)
136 case PIPE_STENCIL_OP_KEEP
: return V3D_STENCIL_OP_KEEP
;
137 case PIPE_STENCIL_OP_ZERO
: return V3D_STENCIL_OP_ZERO
;
138 case PIPE_STENCIL_OP_REPLACE
: return V3D_STENCIL_OP_REPLACE
;
139 case PIPE_STENCIL_OP_INCR
: return V3D_STENCIL_OP_INCR
;
140 case PIPE_STENCIL_OP_DECR
: return V3D_STENCIL_OP_DECR
;
141 case PIPE_STENCIL_OP_INCR_WRAP
: return V3D_STENCIL_OP_INCWRAP
;
142 case PIPE_STENCIL_OP_DECR_WRAP
: return V3D_STENCIL_OP_DECWRAP
;
143 case PIPE_STENCIL_OP_INVERT
: return V3D_STENCIL_OP_INVERT
;
145 unreachable("bad stencil op");
149 vc5_create_depth_stencil_alpha_state(struct pipe_context
*pctx
,
150 const struct pipe_depth_stencil_alpha_state
*cso
)
152 struct vc5_depth_stencil_alpha_state
*so
;
154 so
= CALLOC_STRUCT(vc5_depth_stencil_alpha_state
);
160 if (cso
->depth
.enabled
) {
161 /* We only handle early Z in the < direction because otherwise
162 * we'd have to runtime guess which direction to set in the
166 ((cso
->depth
.func
== PIPE_FUNC_LESS
||
167 cso
->depth
.func
== PIPE_FUNC_LEQUAL
) &&
168 (!cso
->stencil
[0].enabled
||
169 (cso
->stencil
[0].zfail_op
== PIPE_STENCIL_OP_KEEP
&&
170 cso
->stencil
[0].func
== PIPE_FUNC_ALWAYS
&&
171 (!cso
->stencil
[1].enabled
||
172 (cso
->stencil
[1].zfail_op
== PIPE_STENCIL_OP_KEEP
&&
173 cso
->stencil
[1].func
== PIPE_FUNC_ALWAYS
)))));
176 const struct pipe_stencil_state
*front
= &cso
->stencil
[0];
177 const struct pipe_stencil_state
*back
= &cso
->stencil
[1];
179 if (front
->enabled
) {
180 v3dx_pack(&so
->stencil_front
, STENCIL_CONFIG
, config
) {
181 config
.front_config
= true;
182 /* If !back->enabled, then the front values should be
183 * used for both front and back-facing primitives.
185 config
.back_config
= !back
->enabled
;
187 config
.stencil_write_mask
= front
->writemask
;
188 config
.stencil_test_mask
= front
->valuemask
;
190 config
.stencil_test_function
= front
->func
;
191 config
.stencil_pass_op
=
192 translate_stencil_op(front
->zpass_op
);
193 config
.depth_test_fail_op
=
194 translate_stencil_op(front
->zfail_op
);
195 config
.stencil_test_fail_op
=
196 translate_stencil_op(front
->fail_op
);
200 v3dx_pack(&so
->stencil_back
, STENCIL_CONFIG
, config
) {
201 config
.front_config
= false;
202 config
.back_config
= true;
204 config
.stencil_write_mask
= back
->writemask
;
205 config
.stencil_test_mask
= back
->valuemask
;
207 config
.stencil_test_function
= back
->func
;
208 config
.stencil_pass_op
=
209 translate_stencil_op(back
->zpass_op
);
210 config
.depth_test_fail_op
=
211 translate_stencil_op(back
->zfail_op
);
212 config
.stencil_test_fail_op
=
213 translate_stencil_op(back
->fail_op
);
221 vc5_set_polygon_stipple(struct pipe_context
*pctx
,
222 const struct pipe_poly_stipple
*stipple
)
224 struct vc5_context
*vc5
= vc5_context(pctx
);
225 vc5
->stipple
= *stipple
;
226 vc5
->dirty
|= VC5_DIRTY_STIPPLE
;
230 vc5_set_scissor_states(struct pipe_context
*pctx
,
232 unsigned num_scissors
,
233 const struct pipe_scissor_state
*scissor
)
235 struct vc5_context
*vc5
= vc5_context(pctx
);
237 vc5
->scissor
= *scissor
;
238 vc5
->dirty
|= VC5_DIRTY_SCISSOR
;
242 vc5_set_viewport_states(struct pipe_context
*pctx
,
244 unsigned num_viewports
,
245 const struct pipe_viewport_state
*viewport
)
247 struct vc5_context
*vc5
= vc5_context(pctx
);
248 vc5
->viewport
= *viewport
;
249 vc5
->dirty
|= VC5_DIRTY_VIEWPORT
;
253 vc5_set_vertex_buffers(struct pipe_context
*pctx
,
254 unsigned start_slot
, unsigned count
,
255 const struct pipe_vertex_buffer
*vb
)
257 struct vc5_context
*vc5
= vc5_context(pctx
);
258 struct vc5_vertexbuf_stateobj
*so
= &vc5
->vertexbuf
;
260 util_set_vertex_buffers_mask(so
->vb
, &so
->enabled_mask
, vb
,
262 so
->count
= util_last_bit(so
->enabled_mask
);
264 vc5
->dirty
|= VC5_DIRTY_VTXBUF
;
268 vc5_blend_state_bind(struct pipe_context
*pctx
, void *hwcso
)
270 struct vc5_context
*vc5
= vc5_context(pctx
);
272 vc5
->dirty
|= VC5_DIRTY_BLEND
;
276 vc5_rasterizer_state_bind(struct pipe_context
*pctx
, void *hwcso
)
278 struct vc5_context
*vc5
= vc5_context(pctx
);
279 vc5
->rasterizer
= hwcso
;
280 vc5
->dirty
|= VC5_DIRTY_RASTERIZER
;
284 vc5_zsa_state_bind(struct pipe_context
*pctx
, void *hwcso
)
286 struct vc5_context
*vc5
= vc5_context(pctx
);
288 vc5
->dirty
|= VC5_DIRTY_ZSA
;
292 vc5_vertex_state_create(struct pipe_context
*pctx
, unsigned num_elements
,
293 const struct pipe_vertex_element
*elements
)
295 struct vc5_context
*vc5
= vc5_context(pctx
);
296 struct vc5_vertex_stateobj
*so
= CALLOC_STRUCT(vc5_vertex_stateobj
);
301 memcpy(so
->pipe
, elements
, sizeof(*elements
) * num_elements
);
302 so
->num_elements
= num_elements
;
304 for (int i
= 0; i
< so
->num_elements
; i
++) {
305 const struct pipe_vertex_element
*elem
= &elements
[i
];
306 const struct util_format_description
*desc
=
307 util_format_description(elem
->src_format
);
308 uint32_t r_size
= desc
->channel
[0].size
;
310 const uint32_t size
=
311 cl_packet_length(GL_SHADER_STATE_ATTRIBUTE_RECORD
);
313 v3dx_pack(&so
->attrs
[i
* size
],
314 GL_SHADER_STATE_ATTRIBUTE_RECORD
, attr
) {
315 /* vec_size == 0 means 4 */
316 attr
.vec_size
= desc
->nr_channels
& 3;
317 attr
.signed_int_type
= (desc
->channel
[0].type
==
318 UTIL_FORMAT_TYPE_SIGNED
);
320 attr
.normalized_int_type
= desc
->channel
[0].normalized
;
321 attr
.read_as_int_uint
= desc
->channel
[0].pure_integer
;
322 attr
.instance_divisor
= elem
->instance_divisor
;
324 switch (desc
->channel
[0].type
) {
325 case UTIL_FORMAT_TYPE_FLOAT
:
327 attr
.type
= ATTRIBUTE_FLOAT
;
329 assert(r_size
== 16);
330 attr
.type
= ATTRIBUTE_HALF_FLOAT
;
334 case UTIL_FORMAT_TYPE_SIGNED
:
335 case UTIL_FORMAT_TYPE_UNSIGNED
:
338 attr
.type
= ATTRIBUTE_INT
;
341 attr
.type
= ATTRIBUTE_SHORT
;
344 attr
.type
= ATTRIBUTE_INT2_10_10_10
;
347 attr
.type
= ATTRIBUTE_BYTE
;
351 "format %s unsupported\n",
353 attr
.type
= ATTRIBUTE_BYTE
;
360 "format %s unsupported\n",
367 /* Set up the default attribute values in case any of the vertex
370 so
->default_attribute_values
= vc5_bo_alloc(vc5
->screen
,
373 "default attributes");
374 uint32_t *attrs
= vc5_bo_map(so
->default_attribute_values
);
375 for (int i
= 0; i
< VC5_MAX_ATTRIBUTES
; i
++) {
376 attrs
[i
* 4 + 0] = 0;
377 attrs
[i
* 4 + 1] = 0;
378 attrs
[i
* 4 + 2] = 0;
379 if (i
< so
->num_elements
&&
380 util_format_is_pure_integer(so
->pipe
[i
].src_format
)) {
381 attrs
[i
* 4 + 3] = 1;
383 attrs
[i
* 4 + 3] = fui(1.0);
391 vc5_vertex_state_bind(struct pipe_context
*pctx
, void *hwcso
)
393 struct vc5_context
*vc5
= vc5_context(pctx
);
395 vc5
->dirty
|= VC5_DIRTY_VTXSTATE
;
399 vc5_set_constant_buffer(struct pipe_context
*pctx
, uint shader
, uint index
,
400 const struct pipe_constant_buffer
*cb
)
402 struct vc5_context
*vc5
= vc5_context(pctx
);
403 struct vc5_constbuf_stateobj
*so
= &vc5
->constbuf
[shader
];
405 util_copy_constant_buffer(&so
->cb
[index
], cb
);
407 /* Note that the state tracker can unbind constant buffers by
411 so
->enabled_mask
&= ~(1 << index
);
412 so
->dirty_mask
&= ~(1 << index
);
416 so
->enabled_mask
|= 1 << index
;
417 so
->dirty_mask
|= 1 << index
;
418 vc5
->dirty
|= VC5_DIRTY_CONSTBUF
;
422 vc5_set_framebuffer_state(struct pipe_context
*pctx
,
423 const struct pipe_framebuffer_state
*framebuffer
)
425 struct vc5_context
*vc5
= vc5_context(pctx
);
426 struct pipe_framebuffer_state
*cso
= &vc5
->framebuffer
;
431 for (i
= 0; i
< framebuffer
->nr_cbufs
; i
++)
432 pipe_surface_reference(&cso
->cbufs
[i
], framebuffer
->cbufs
[i
]);
433 for (; i
< vc5
->framebuffer
.nr_cbufs
; i
++)
434 pipe_surface_reference(&cso
->cbufs
[i
], NULL
);
436 cso
->nr_cbufs
= framebuffer
->nr_cbufs
;
438 pipe_surface_reference(&cso
->zsbuf
, framebuffer
->zsbuf
);
440 cso
->width
= framebuffer
->width
;
441 cso
->height
= framebuffer
->height
;
443 vc5
->swap_color_rb
= 0;
444 vc5
->blend_dst_alpha_one
= 0;
445 for (int i
= 0; i
< vc5
->framebuffer
.nr_cbufs
; i
++) {
446 struct pipe_surface
*cbuf
= vc5
->framebuffer
.cbufs
[i
];
450 const struct util_format_description
*desc
=
451 util_format_description(cbuf
->format
);
453 /* For BGRA8 formats (DRI window system default format), we
454 * need to swap R and B, since the HW's format is RGBA8.
456 if (desc
->swizzle
[0] == PIPE_SWIZZLE_Z
&&
457 cbuf
->format
!= PIPE_FORMAT_B5G6R5_UNORM
) {
458 vc5
->swap_color_rb
|= 1 << i
;
461 if (desc
->swizzle
[3] == PIPE_SWIZZLE_1
)
462 vc5
->blend_dst_alpha_one
|= 1 << i
;
465 vc5
->dirty
|= VC5_DIRTY_FRAMEBUFFER
;
468 static struct vc5_texture_stateobj
*
469 vc5_get_stage_tex(struct vc5_context
*vc5
, enum pipe_shader_type shader
)
472 case PIPE_SHADER_FRAGMENT
:
473 vc5
->dirty
|= VC5_DIRTY_FRAGTEX
;
474 return &vc5
->fragtex
;
476 case PIPE_SHADER_VERTEX
:
477 vc5
->dirty
|= VC5_DIRTY_VERTTEX
;
478 return &vc5
->verttex
;
481 fprintf(stderr
, "Unknown shader target %d\n", shader
);
486 static uint32_t translate_wrap(uint32_t pipe_wrap
, bool using_nearest
)
489 case PIPE_TEX_WRAP_REPEAT
:
491 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
:
493 case PIPE_TEX_WRAP_MIRROR_REPEAT
:
495 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
:
497 case PIPE_TEX_WRAP_CLAMP
:
498 return (using_nearest
? 1 : 3);
500 unreachable("Unknown wrap mode");
506 vc5_create_sampler_state(struct pipe_context
*pctx
,
507 const struct pipe_sampler_state
*cso
)
509 MAYBE_UNUSED
struct vc5_context
*vc5
= vc5_context(pctx
);
510 struct vc5_sampler_state
*so
= CALLOC_STRUCT(vc5_sampler_state
);
515 memcpy(so
, cso
, sizeof(*cso
));
517 bool either_nearest
=
518 (cso
->mag_img_filter
== PIPE_TEX_MIPFILTER_NEAREST
||
519 cso
->min_img_filter
== PIPE_TEX_MIPFILTER_NEAREST
);
521 #if V3D_VERSION >= 40
522 so
->bo
= vc5_bo_alloc(vc5
->screen
, cl_packet_length(SAMPLER_STATE
),
524 void *map
= vc5_bo_map(so
->bo
);
526 v3dx_pack(map
, SAMPLER_STATE
, sampler
) {
527 sampler
.wrap_i_border
= false;
529 sampler
.wrap_s
= translate_wrap(cso
->wrap_s
, either_nearest
);
530 sampler
.wrap_t
= translate_wrap(cso
->wrap_t
, either_nearest
);
531 sampler
.wrap_r
= translate_wrap(cso
->wrap_r
, either_nearest
);
533 sampler
.fixed_bias
= cso
->lod_bias
;
534 sampler
.depth_compare_function
= cso
->compare_func
;
536 sampler
.min_filter_nearest
=
537 cso
->min_img_filter
== PIPE_TEX_FILTER_NEAREST
;
538 sampler
.mag_filter_nearest
=
539 cso
->mag_img_filter
== PIPE_TEX_FILTER_NEAREST
;
540 sampler
.mip_filter_nearest
=
541 cso
->min_mip_filter
!= PIPE_TEX_MIPFILTER_LINEAR
;
543 sampler
.min_level_of_detail
= MIN2(MAX2(0, cso
->min_lod
),
545 sampler
.max_level_of_detail
= MIN2(cso
->max_lod
, 15);
547 if (cso
->min_mip_filter
== PIPE_TEX_MIPFILTER_NONE
) {
548 sampler
.min_level_of_detail
= 0;
549 sampler
.max_level_of_detail
= 0;
552 if (cso
->max_anisotropy
) {
553 sampler
.anisotropy_enable
= true;
555 if (cso
->max_anisotropy
> 8)
556 sampler
.maximum_anisotropy
= 3;
557 else if (cso
->max_anisotropy
> 4)
558 sampler
.maximum_anisotropy
= 2;
559 else if (cso
->max_anisotropy
> 2)
560 sampler
.maximum_anisotropy
= 1;
563 sampler
.border_colour_mode
= V3D_BORDER_COLOUR_FOLLOWS
;
564 /* XXX: The border colour field is in the TMU blending format
565 * (32, f16, or i16), and we need to customize it based on
568 * XXX: for compat alpha formats, we need the alpha field to
569 * be in the red channel.
571 sampler
.border_colour_red
=
572 util_float_to_half(cso
->border_color
.f
[0]);
573 sampler
.border_colour_green
=
574 util_float_to_half(cso
->border_color
.f
[1]);
575 sampler
.border_colour_blue
=
576 util_float_to_half(cso
->border_color
.f
[2]);
577 sampler
.border_colour_alpha
=
578 util_float_to_half(cso
->border_color
.f
[3]);
581 #else /* V3D_VERSION < 40 */
582 v3dx_pack(&so
->p0
, TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1
, p0
) {
583 p0
.s_wrap_mode
= translate_wrap(cso
->wrap_s
, either_nearest
);
584 p0
.t_wrap_mode
= translate_wrap(cso
->wrap_t
, either_nearest
);
585 p0
.r_wrap_mode
= translate_wrap(cso
->wrap_r
, either_nearest
);
588 v3dx_pack(&so
->texture_shader_state
, TEXTURE_SHADER_STATE
, tex
) {
589 tex
.depth_compare_function
= cso
->compare_func
;
590 tex
.fixed_bias
= cso
->lod_bias
;
592 #endif /* V3D_VERSION < 40 */
597 vc5_sampler_states_bind(struct pipe_context
*pctx
,
598 enum pipe_shader_type shader
, unsigned start
,
599 unsigned nr
, void **hwcso
)
601 struct vc5_context
*vc5
= vc5_context(pctx
);
602 struct vc5_texture_stateobj
*stage_tex
= vc5_get_stage_tex(vc5
, shader
);
608 for (i
= 0; i
< nr
; i
++) {
611 stage_tex
->samplers
[i
] = hwcso
[i
];
614 for (; i
< stage_tex
->num_samplers
; i
++) {
615 stage_tex
->samplers
[i
] = NULL
;
618 stage_tex
->num_samplers
= new_nr
;
622 vc5_sampler_state_delete(struct pipe_context
*pctx
,
625 struct pipe_sampler_state
*psampler
= hwcso
;
626 struct vc5_sampler_state
*sampler
= vc5_sampler_state(psampler
);
628 vc5_bo_unreference(&sampler
->bo
);
632 #if V3D_VERSION >= 40
634 translate_swizzle(unsigned char pipe_swizzle
)
636 switch (pipe_swizzle
) {
645 return 2 + pipe_swizzle
;
647 unreachable("unknown swizzle");
652 static struct pipe_sampler_view
*
653 vc5_create_sampler_view(struct pipe_context
*pctx
, struct pipe_resource
*prsc
,
654 const struct pipe_sampler_view
*cso
)
656 struct vc5_context
*vc5
= vc5_context(pctx
);
657 struct vc5_screen
*screen
= vc5
->screen
;
658 struct vc5_sampler_view
*so
= CALLOC_STRUCT(vc5_sampler_view
);
659 struct vc5_resource
*rsc
= vc5_resource(prsc
);
666 pipe_reference(NULL
, &prsc
->reference
);
668 /* Compute the sampler view's swizzle up front. This will be plugged
669 * into either the sampler (for 16-bit returns) or the shader's
670 * texture key (for 32)
672 uint8_t view_swizzle
[4] = {
678 const uint8_t *fmt_swizzle
=
679 vc5_get_format_swizzle(&screen
->devinfo
, so
->base
.format
);
680 util_format_compose_swizzles(fmt_swizzle
, view_swizzle
, so
->swizzle
);
682 so
->base
.texture
= prsc
;
683 so
->base
.reference
.count
= 1;
684 so
->base
.context
= pctx
;
686 int msaa_scale
= prsc
->nr_samples
> 1 ? 2 : 1;
688 #if V3D_VERSION >= 40
689 so
->bo
= vc5_bo_alloc(vc5
->screen
, cl_packet_length(SAMPLER_STATE
),
691 void *map
= vc5_bo_map(so
->bo
);
693 v3dx_pack(map
, TEXTURE_SHADER_STATE
, tex
) {
694 #else /* V3D_VERSION < 40 */
695 v3dx_pack(&so
->texture_shader_state
, TEXTURE_SHADER_STATE
, tex
) {
698 tex
.image_width
= prsc
->width0
* msaa_scale
;
699 tex
.image_height
= prsc
->height0
* msaa_scale
;
701 #if V3D_VERSION >= 40
702 /* On 4.x, the height of a 1D texture is redefined to be the
703 * upper 14 bits of the width (which is only usable with txf).
705 if (prsc
->target
== PIPE_TEXTURE_1D
||
706 prsc
->target
== PIPE_TEXTURE_1D_ARRAY
) {
707 tex
.image_height
= tex
.image_width
>> 14;
711 if (prsc
->target
== PIPE_TEXTURE_3D
) {
712 tex
.image_depth
= prsc
->depth0
;
714 tex
.image_depth
= (cso
->u
.tex
.last_layer
-
715 cso
->u
.tex
.first_layer
) + 1;
718 tex
.srgb
= util_format_is_srgb(cso
->format
);
720 tex
.base_level
= cso
->u
.tex
.first_level
;
721 #if V3D_VERSION >= 40
722 tex
.max_level
= cso
->u
.tex
.last_level
;
723 /* Note that we don't have a job to reference the texture's sBO
724 * at state create time, so any time this sampler view is used
725 * we need to add the texture to the job.
727 tex
.texture_base_pointer
= cl_address(NULL
,
729 rsc
->slices
[0].offset
),
731 tex
.swizzle_r
= translate_swizzle(so
->swizzle
[0]);
732 tex
.swizzle_g
= translate_swizzle(so
->swizzle
[1]);
733 tex
.swizzle_b
= translate_swizzle(so
->swizzle
[2]);
734 tex
.swizzle_a
= translate_swizzle(so
->swizzle
[3]);
736 tex
.array_stride_64_byte_aligned
= rsc
->cube_map_stride
/ 64;
738 if (prsc
->nr_samples
> 1) {
739 /* Using texture views to reinterpret formats on our
740 * MSAA textures won't work, because we don't lay out
741 * the bits in memory as it's expected -- for example,
742 * RGBA8 and RGB10_A2 are compatible in the
743 * ARB_texture_view spec, but in HW we lay them out as
744 * 32bpp RGBA8 and 64bpp RGBA16F. Just assert for now
747 assert(util_format_linear(cso
->format
) ==
748 util_format_linear(prsc
->format
));
749 uint32_t output_image_format
=
750 vc5_get_rt_format(&screen
->devinfo
, cso
->format
);
751 uint32_t internal_type
;
752 uint32_t internal_bpp
;
753 vc5_get_internal_type_bpp_for_output_format(&screen
->devinfo
,
758 switch (internal_type
) {
759 case V3D_INTERNAL_TYPE_8
:
760 tex
.texture_type
= TEXTURE_DATA_FORMAT_RGBA8
;
762 case V3D_INTERNAL_TYPE_16F
:
763 tex
.texture_type
= TEXTURE_DATA_FORMAT_RGBA16F
;
766 unreachable("Bad MSAA texture type");
769 /* sRGB was stored in the tile buffer as linear and
770 * would have been encoded to sRGB on resolved tile
771 * buffer store. Note that this means we would need
772 * shader code if we wanted to read an MSAA sRGB
773 * texture without sRGB decode.
777 tex
.texture_type
= vc5_get_tex_format(&screen
->devinfo
,
781 /* Since other platform devices may produce UIF images even
782 * when they're not big enough for V3D to assume they're UIF,
783 * we force images with level 0 as UIF to be always treated
786 tex
.level_0_is_strictly_uif
= (rsc
->slices
[0].tiling
==
787 VC5_TILING_UIF_XOR
||
788 rsc
->slices
[0].tiling
==
789 VC5_TILING_UIF_NO_XOR
);
790 tex
.level_0_xor_enable
= (rsc
->slices
[0].tiling
==
793 if (tex
.level_0_is_strictly_uif
)
794 tex
.level_0_ub_pad
= rsc
->slices
[0].ub_pad
;
796 #if V3D_VERSION >= 40
797 if (tex
.uif_xor_disable
||
798 tex
.level_0_is_strictly_uif
) {
801 #endif /* V3D_VERSION >= 40 */
808 vc5_sampler_view_destroy(struct pipe_context
*pctx
,
809 struct pipe_sampler_view
*psview
)
811 struct vc5_sampler_view
*sview
= vc5_sampler_view(psview
);
813 vc5_bo_unreference(&sview
->bo
);
814 pipe_resource_reference(&psview
->texture
, NULL
);
819 vc5_set_sampler_views(struct pipe_context
*pctx
,
820 enum pipe_shader_type shader
,
821 unsigned start
, unsigned nr
,
822 struct pipe_sampler_view
**views
)
824 struct vc5_context
*vc5
= vc5_context(pctx
);
825 struct vc5_texture_stateobj
*stage_tex
= vc5_get_stage_tex(vc5
, shader
);
831 for (i
= 0; i
< nr
; i
++) {
834 pipe_sampler_view_reference(&stage_tex
->textures
[i
], views
[i
]);
837 for (; i
< stage_tex
->num_textures
; i
++) {
838 pipe_sampler_view_reference(&stage_tex
->textures
[i
], NULL
);
841 stage_tex
->num_textures
= new_nr
;
844 static struct pipe_stream_output_target
*
845 vc5_create_stream_output_target(struct pipe_context
*pctx
,
846 struct pipe_resource
*prsc
,
847 unsigned buffer_offset
,
848 unsigned buffer_size
)
850 struct pipe_stream_output_target
*target
;
852 target
= CALLOC_STRUCT(pipe_stream_output_target
);
856 pipe_reference_init(&target
->reference
, 1);
857 pipe_resource_reference(&target
->buffer
, prsc
);
859 target
->context
= pctx
;
860 target
->buffer_offset
= buffer_offset
;
861 target
->buffer_size
= buffer_size
;
867 vc5_stream_output_target_destroy(struct pipe_context
*pctx
,
868 struct pipe_stream_output_target
*target
)
870 pipe_resource_reference(&target
->buffer
, NULL
);
875 vc5_set_stream_output_targets(struct pipe_context
*pctx
,
876 unsigned num_targets
,
877 struct pipe_stream_output_target
**targets
,
878 const unsigned *offsets
)
880 struct vc5_context
*ctx
= vc5_context(pctx
);
881 struct vc5_streamout_stateobj
*so
= &ctx
->streamout
;
884 assert(num_targets
<= ARRAY_SIZE(so
->targets
));
886 for (i
= 0; i
< num_targets
; i
++)
887 pipe_so_target_reference(&so
->targets
[i
], targets
[i
]);
889 for (; i
< so
->num_targets
; i
++)
890 pipe_so_target_reference(&so
->targets
[i
], NULL
);
892 so
->num_targets
= num_targets
;
894 ctx
->dirty
|= VC5_DIRTY_STREAMOUT
;
898 v3dX(state_init
)(struct pipe_context
*pctx
)
900 pctx
->set_blend_color
= vc5_set_blend_color
;
901 pctx
->set_stencil_ref
= vc5_set_stencil_ref
;
902 pctx
->set_clip_state
= vc5_set_clip_state
;
903 pctx
->set_sample_mask
= vc5_set_sample_mask
;
904 pctx
->set_constant_buffer
= vc5_set_constant_buffer
;
905 pctx
->set_framebuffer_state
= vc5_set_framebuffer_state
;
906 pctx
->set_polygon_stipple
= vc5_set_polygon_stipple
;
907 pctx
->set_scissor_states
= vc5_set_scissor_states
;
908 pctx
->set_viewport_states
= vc5_set_viewport_states
;
910 pctx
->set_vertex_buffers
= vc5_set_vertex_buffers
;
912 pctx
->create_blend_state
= vc5_create_blend_state
;
913 pctx
->bind_blend_state
= vc5_blend_state_bind
;
914 pctx
->delete_blend_state
= vc5_generic_cso_state_delete
;
916 pctx
->create_rasterizer_state
= vc5_create_rasterizer_state
;
917 pctx
->bind_rasterizer_state
= vc5_rasterizer_state_bind
;
918 pctx
->delete_rasterizer_state
= vc5_generic_cso_state_delete
;
920 pctx
->create_depth_stencil_alpha_state
= vc5_create_depth_stencil_alpha_state
;
921 pctx
->bind_depth_stencil_alpha_state
= vc5_zsa_state_bind
;
922 pctx
->delete_depth_stencil_alpha_state
= vc5_generic_cso_state_delete
;
924 pctx
->create_vertex_elements_state
= vc5_vertex_state_create
;
925 pctx
->delete_vertex_elements_state
= vc5_generic_cso_state_delete
;
926 pctx
->bind_vertex_elements_state
= vc5_vertex_state_bind
;
928 pctx
->create_sampler_state
= vc5_create_sampler_state
;
929 pctx
->delete_sampler_state
= vc5_sampler_state_delete
;
930 pctx
->bind_sampler_states
= vc5_sampler_states_bind
;
932 pctx
->create_sampler_view
= vc5_create_sampler_view
;
933 pctx
->sampler_view_destroy
= vc5_sampler_view_destroy
;
934 pctx
->set_sampler_views
= vc5_set_sampler_views
;
936 pctx
->create_stream_output_target
= vc5_create_stream_output_target
;
937 pctx
->stream_output_target_destroy
= vc5_stream_output_target_destroy
;
938 pctx
->set_stream_output_targets
= vc5_set_stream_output_targets
;