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_fetchsize fetchsize
;
48 enum a5xx_tex_type type
;
60 static void translate_image(struct fd5_image
*img
, struct pipe_image_view
*pimg
)
62 enum pipe_format format
= pimg
->format
;
63 struct pipe_resource
*prsc
= pimg
->resource
;
64 struct fd_resource
*rsc
= fd_resource(prsc
);
65 struct fdl_slice
*slice
= NULL
;
68 if (!pimg
->resource
) {
69 memset(img
, 0, sizeof(*img
));
74 img
->fmt
= fd5_pipe2tex(format
);
75 img
->fetchsize
= fd5_pipe2fetchsize(format
);
76 img
->type
= fd5_tex_type(prsc
->target
);
77 img
->srgb
= util_format_is_srgb(format
);
78 img
->cpp
= rsc
->layout
.cpp
;
81 if (prsc
->target
== PIPE_BUFFER
) {
83 img
->offset
= pimg
->u
.buf
.offset
;
84 img
->pitch
= pimg
->u
.buf
.size
;
86 lvl
= pimg
->u
.tex
.level
;
87 slice
= fd_resource_slice(rsc
, lvl
);
88 img
->offset
= fd_resource_offset(rsc
, lvl
, pimg
->u
.tex
.first_layer
);
89 img
->pitch
= slice
->pitch
* rsc
->layout
.cpp
;
92 img
->width
= u_minify(prsc
->width0
, lvl
);
93 img
->height
= u_minify(prsc
->height0
, lvl
);
95 unsigned layers
= pimg
->u
.tex
.last_layer
- pimg
->u
.tex
.first_layer
+ 1;
97 switch (prsc
->target
) {
98 case PIPE_TEXTURE_RECT
:
100 case PIPE_TEXTURE_2D
:
101 img
->array_pitch
= rsc
->layout
.layer_size
;
104 case PIPE_TEXTURE_1D_ARRAY
:
105 case PIPE_TEXTURE_2D_ARRAY
:
106 img
->array_pitch
= rsc
->layout
.layer_size
;
109 case PIPE_TEXTURE_CUBE
:
110 case PIPE_TEXTURE_CUBE_ARRAY
:
111 img
->array_pitch
= rsc
->layout
.layer_size
;
114 case PIPE_TEXTURE_3D
:
115 img
->array_pitch
= slice
->size0
;
116 img
->depth
= u_minify(prsc
->depth0
, lvl
);
119 img
->array_pitch
= 0;
125 static void emit_image_tex(struct fd_ringbuffer
*ring
, unsigned slot
,
126 struct fd5_image
*img
, enum pipe_shader_type shader
)
128 OUT_PKT7(ring
, CP_LOAD_STATE4
, 3 + 12);
129 OUT_RING(ring
, CP_LOAD_STATE4_0_DST_OFF(slot
) |
130 CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT
) |
131 CP_LOAD_STATE4_0_STATE_BLOCK(texsb
[shader
]) |
132 CP_LOAD_STATE4_0_NUM_UNIT(1));
133 OUT_RING(ring
, CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS
) |
134 CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));
135 OUT_RING(ring
, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
137 OUT_RING(ring
, A5XX_TEX_CONST_0_FMT(img
->fmt
) |
138 fd5_tex_swiz(img
->pfmt
, PIPE_SWIZZLE_X
, PIPE_SWIZZLE_Y
,
139 PIPE_SWIZZLE_Z
, PIPE_SWIZZLE_W
) |
140 COND(img
->srgb
, A5XX_TEX_CONST_0_SRGB
));
141 OUT_RING(ring
, A5XX_TEX_CONST_1_WIDTH(img
->width
) |
142 A5XX_TEX_CONST_1_HEIGHT(img
->height
));
143 OUT_RING(ring
, A5XX_TEX_CONST_2_FETCHSIZE(img
->fetchsize
) |
144 A5XX_TEX_CONST_2_TYPE(img
->type
) |
145 A5XX_TEX_CONST_2_PITCH(img
->pitch
));
146 OUT_RING(ring
, A5XX_TEX_CONST_3_ARRAY_PITCH(img
->array_pitch
));
148 OUT_RELOC(ring
, img
->bo
, img
->offset
,
149 (uint64_t)A5XX_TEX_CONST_5_DEPTH(img
->depth
) << 32, 0);
151 OUT_RING(ring
, 0x00000000);
152 OUT_RING(ring
, A5XX_TEX_CONST_5_DEPTH(img
->depth
));
154 OUT_RING(ring
, 0x00000000);
155 OUT_RING(ring
, 0x00000000);
156 OUT_RING(ring
, 0x00000000);
157 OUT_RING(ring
, 0x00000000);
158 OUT_RING(ring
, 0x00000000);
159 OUT_RING(ring
, 0x00000000);
162 static void emit_image_ssbo(struct fd_ringbuffer
*ring
, unsigned slot
,
163 struct fd5_image
*img
, enum pipe_shader_type shader
)
165 OUT_PKT7(ring
, CP_LOAD_STATE4
, 3 + 2);
166 OUT_RING(ring
, CP_LOAD_STATE4_0_DST_OFF(slot
) |
167 CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT
) |
168 CP_LOAD_STATE4_0_STATE_BLOCK(imgsb
[shader
]) |
169 CP_LOAD_STATE4_0_NUM_UNIT(1));
170 OUT_RING(ring
, CP_LOAD_STATE4_1_STATE_TYPE(1) |
171 CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));
172 OUT_RING(ring
, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
173 OUT_RING(ring
, A5XX_SSBO_1_0_FMT(img
->fmt
) |
174 A5XX_SSBO_1_0_WIDTH(img
->width
));
175 OUT_RING(ring
, A5XX_SSBO_1_1_HEIGHT(img
->height
) |
176 A5XX_SSBO_1_1_DEPTH(img
->depth
));
178 OUT_PKT7(ring
, CP_LOAD_STATE4
, 3 + 2);
179 OUT_RING(ring
, CP_LOAD_STATE4_0_DST_OFF(slot
) |
180 CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT
) |
181 CP_LOAD_STATE4_0_STATE_BLOCK(imgsb
[shader
]) |
182 CP_LOAD_STATE4_0_NUM_UNIT(1));
183 OUT_RING(ring
, CP_LOAD_STATE4_1_STATE_TYPE(2) |
184 CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));
185 OUT_RING(ring
, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
187 OUT_RELOCW(ring
, img
->bo
, img
->offset
, 0, 0);
189 OUT_RING(ring
, 0x00000000);
190 OUT_RING(ring
, 0x00000000);
194 /* Emit required "SSBO" and sampler state. The sampler state is used by the
195 * hw for imageLoad(), and "SSBO" state for imageStore(). Returns max sampler
199 fd5_emit_images(struct fd_context
*ctx
, struct fd_ringbuffer
*ring
,
200 enum pipe_shader_type shader
, const struct ir3_shader_variant
*v
)
202 struct fd_shaderimg_stateobj
*so
= &ctx
->shaderimg
[shader
];
203 unsigned enabled_mask
= so
->enabled_mask
;
204 const struct ir3_ibo_mapping
*m
= &v
->image_mapping
;
206 while (enabled_mask
) {
207 unsigned index
= u_bit_scan(&enabled_mask
);
208 struct fd5_image img
;
210 translate_image(&img
, &so
->si
[index
]);
212 emit_image_tex(ring
, m
->image_to_tex
[index
] + m
->tex_base
, &img
, shader
);
213 emit_image_ssbo(ring
, m
->image_to_ibo
[index
], &img
, shader
);