2 * Copyright (C) 2017 Rob Clark <robclark@freedesktop.org>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * Rob Clark <robclark@freedesktop.org>
27 #include "pipe/p_state.h"
29 #include "freedreno_resource.h"
30 #include "fd5_image.h"
31 #include "fd5_format.h"
32 #include "fd5_texture.h"
34 static enum a4xx_state_block texsb
[] = {
35 [PIPE_SHADER_COMPUTE
] = SB4_CS_TEX
,
36 [PIPE_SHADER_FRAGMENT
] = SB4_FS_TEX
,
39 static enum a4xx_state_block imgsb
[] = {
40 [PIPE_SHADER_COMPUTE
] = SB4_CS_SSBO
,
41 [PIPE_SHADER_FRAGMENT
] = SB4_SSBO
,
45 enum pipe_format pfmt
;
46 enum a5xx_tex_fmt fmt
;
47 enum a5xx_tex_type type
;
59 static void translate_image(struct fd5_image
*img
, struct pipe_image_view
*pimg
)
61 enum pipe_format format
= pimg
->format
;
62 struct pipe_resource
*prsc
= pimg
->resource
;
63 struct fd_resource
*rsc
= fd_resource(prsc
);
66 if (!pimg
->resource
) {
67 memset(img
, 0, sizeof(*img
));
72 img
->fmt
= fd5_pipe2tex(format
);
73 img
->type
= fd5_tex_type(prsc
->target
);
74 img
->srgb
= util_format_is_srgb(format
);
75 img
->cpp
= rsc
->layout
.cpp
;
78 if (prsc
->target
== PIPE_BUFFER
) {
80 img
->offset
= pimg
->u
.buf
.offset
;
81 img
->pitch
= pimg
->u
.buf
.size
;
83 lvl
= pimg
->u
.tex
.level
;
84 img
->offset
= fd_resource_offset(rsc
, lvl
, pimg
->u
.tex
.first_layer
);
85 img
->pitch
= fd_resource_pitch(rsc
, lvl
);
88 img
->width
= u_minify(prsc
->width0
, lvl
);
89 img
->height
= u_minify(prsc
->height0
, lvl
);
91 unsigned layers
= pimg
->u
.tex
.last_layer
- pimg
->u
.tex
.first_layer
+ 1;
93 switch (prsc
->target
) {
94 case PIPE_TEXTURE_RECT
:
97 img
->array_pitch
= rsc
->layout
.layer_size
;
100 case PIPE_TEXTURE_1D_ARRAY
:
101 case PIPE_TEXTURE_2D_ARRAY
:
102 img
->array_pitch
= rsc
->layout
.layer_size
;
105 case PIPE_TEXTURE_CUBE
:
106 case PIPE_TEXTURE_CUBE_ARRAY
:
107 img
->array_pitch
= rsc
->layout
.layer_size
;
110 case PIPE_TEXTURE_3D
:
111 img
->array_pitch
= fd_resource_slice(rsc
, lvl
)->size0
;
112 img
->depth
= u_minify(prsc
->depth0
, lvl
);
115 img
->array_pitch
= 0;
121 static void emit_image_tex(struct fd_ringbuffer
*ring
, unsigned slot
,
122 struct fd5_image
*img
, enum pipe_shader_type shader
)
124 OUT_PKT7(ring
, CP_LOAD_STATE4
, 3 + 12);
125 OUT_RING(ring
, CP_LOAD_STATE4_0_DST_OFF(slot
) |
126 CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT
) |
127 CP_LOAD_STATE4_0_STATE_BLOCK(texsb
[shader
]) |
128 CP_LOAD_STATE4_0_NUM_UNIT(1));
129 OUT_RING(ring
, CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS
) |
130 CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));
131 OUT_RING(ring
, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
133 OUT_RING(ring
, A5XX_TEX_CONST_0_FMT(img
->fmt
) |
134 fd5_tex_swiz(img
->pfmt
, PIPE_SWIZZLE_X
, PIPE_SWIZZLE_Y
,
135 PIPE_SWIZZLE_Z
, PIPE_SWIZZLE_W
) |
136 COND(img
->srgb
, A5XX_TEX_CONST_0_SRGB
));
137 OUT_RING(ring
, A5XX_TEX_CONST_1_WIDTH(img
->width
) |
138 A5XX_TEX_CONST_1_HEIGHT(img
->height
));
139 OUT_RING(ring
, A5XX_TEX_CONST_2_TYPE(img
->type
) |
140 A5XX_TEX_CONST_2_PITCH(img
->pitch
));
141 OUT_RING(ring
, A5XX_TEX_CONST_3_ARRAY_PITCH(img
->array_pitch
));
143 OUT_RELOC(ring
, img
->bo
, img
->offset
,
144 (uint64_t)A5XX_TEX_CONST_5_DEPTH(img
->depth
) << 32, 0);
146 OUT_RING(ring
, 0x00000000);
147 OUT_RING(ring
, A5XX_TEX_CONST_5_DEPTH(img
->depth
));
149 OUT_RING(ring
, 0x00000000);
150 OUT_RING(ring
, 0x00000000);
151 OUT_RING(ring
, 0x00000000);
152 OUT_RING(ring
, 0x00000000);
153 OUT_RING(ring
, 0x00000000);
154 OUT_RING(ring
, 0x00000000);
157 static void emit_image_ssbo(struct fd_ringbuffer
*ring
, unsigned slot
,
158 struct fd5_image
*img
, enum pipe_shader_type shader
)
160 OUT_PKT7(ring
, CP_LOAD_STATE4
, 3 + 2);
161 OUT_RING(ring
, CP_LOAD_STATE4_0_DST_OFF(slot
) |
162 CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT
) |
163 CP_LOAD_STATE4_0_STATE_BLOCK(imgsb
[shader
]) |
164 CP_LOAD_STATE4_0_NUM_UNIT(1));
165 OUT_RING(ring
, CP_LOAD_STATE4_1_STATE_TYPE(1) |
166 CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));
167 OUT_RING(ring
, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
168 OUT_RING(ring
, A5XX_SSBO_1_0_FMT(img
->fmt
) |
169 A5XX_SSBO_1_0_WIDTH(img
->width
));
170 OUT_RING(ring
, A5XX_SSBO_1_1_HEIGHT(img
->height
) |
171 A5XX_SSBO_1_1_DEPTH(img
->depth
));
173 OUT_PKT7(ring
, CP_LOAD_STATE4
, 3 + 2);
174 OUT_RING(ring
, CP_LOAD_STATE4_0_DST_OFF(slot
) |
175 CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT
) |
176 CP_LOAD_STATE4_0_STATE_BLOCK(imgsb
[shader
]) |
177 CP_LOAD_STATE4_0_NUM_UNIT(1));
178 OUT_RING(ring
, CP_LOAD_STATE4_1_STATE_TYPE(2) |
179 CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));
180 OUT_RING(ring
, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
182 OUT_RELOC(ring
, img
->bo
, img
->offset
, 0, 0);
184 OUT_RING(ring
, 0x00000000);
185 OUT_RING(ring
, 0x00000000);
189 /* Emit required "SSBO" and sampler state. The sampler state is used by the
190 * hw for imageLoad(), and "SSBO" state for imageStore(). Returns max sampler
194 fd5_emit_images(struct fd_context
*ctx
, struct fd_ringbuffer
*ring
,
195 enum pipe_shader_type shader
, const struct ir3_shader_variant
*v
)
197 struct fd_shaderimg_stateobj
*so
= &ctx
->shaderimg
[shader
];
198 unsigned enabled_mask
= so
->enabled_mask
;
199 const struct ir3_ibo_mapping
*m
= &v
->image_mapping
;
201 while (enabled_mask
) {
202 unsigned index
= u_bit_scan(&enabled_mask
);
203 struct fd5_image img
;
205 translate_image(&img
, &so
->si
[index
]);
207 emit_image_tex(ring
, m
->image_to_tex
[index
] + m
->tex_base
, &img
, shader
);
208 emit_image_ssbo(ring
, v
->shader
->nir
->info
.num_ssbos
+ index
, &img
, shader
);