1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (C) 2017 Rob Clark <robclark@freedesktop.org> 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21bf215546Sopenharmony_ci * SOFTWARE. 22bf215546Sopenharmony_ci * 23bf215546Sopenharmony_ci * Authors: 24bf215546Sopenharmony_ci * Rob Clark <robclark@freedesktop.org> 25bf215546Sopenharmony_ci */ 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "pipe/p_state.h" 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "fd5_format.h" 30bf215546Sopenharmony_ci#include "fd5_image.h" 31bf215546Sopenharmony_ci#include "fd5_texture.h" 32bf215546Sopenharmony_ci#include "freedreno_resource.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_cistatic enum a4xx_state_block texsb[] = { 35bf215546Sopenharmony_ci [PIPE_SHADER_COMPUTE] = SB4_CS_TEX, 36bf215546Sopenharmony_ci [PIPE_SHADER_FRAGMENT] = SB4_FS_TEX, 37bf215546Sopenharmony_ci}; 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_cistatic enum a4xx_state_block imgsb[] = { 40bf215546Sopenharmony_ci [PIPE_SHADER_COMPUTE] = SB4_CS_SSBO, 41bf215546Sopenharmony_ci [PIPE_SHADER_FRAGMENT] = SB4_SSBO, 42bf215546Sopenharmony_ci}; 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_cistruct fd5_image { 45bf215546Sopenharmony_ci enum pipe_format pfmt; 46bf215546Sopenharmony_ci enum a5xx_tex_fmt fmt; 47bf215546Sopenharmony_ci enum a5xx_tex_type type; 48bf215546Sopenharmony_ci bool srgb; 49bf215546Sopenharmony_ci uint32_t cpp; 50bf215546Sopenharmony_ci uint32_t width; 51bf215546Sopenharmony_ci uint32_t height; 52bf215546Sopenharmony_ci uint32_t depth; 53bf215546Sopenharmony_ci uint32_t pitch; 54bf215546Sopenharmony_ci uint32_t array_pitch; 55bf215546Sopenharmony_ci struct fd_bo *bo; 56bf215546Sopenharmony_ci uint32_t offset; 57bf215546Sopenharmony_ci bool buffer; 58bf215546Sopenharmony_ci}; 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_cistatic void 61bf215546Sopenharmony_citranslate_image(struct fd5_image *img, struct pipe_image_view *pimg) 62bf215546Sopenharmony_ci{ 63bf215546Sopenharmony_ci enum pipe_format format = pimg->format; 64bf215546Sopenharmony_ci struct pipe_resource *prsc = pimg->resource; 65bf215546Sopenharmony_ci struct fd_resource *rsc = fd_resource(prsc); 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci if (!pimg->resource) { 68bf215546Sopenharmony_ci memset(img, 0, sizeof(*img)); 69bf215546Sopenharmony_ci return; 70bf215546Sopenharmony_ci } 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci img->pfmt = format; 73bf215546Sopenharmony_ci img->fmt = fd5_pipe2tex(format); 74bf215546Sopenharmony_ci img->type = fd5_tex_type(prsc->target); 75bf215546Sopenharmony_ci img->srgb = util_format_is_srgb(format); 76bf215546Sopenharmony_ci img->cpp = rsc->layout.cpp; 77bf215546Sopenharmony_ci img->bo = rsc->bo; 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci /* Treat cube textures as 2d-array: */ 80bf215546Sopenharmony_ci if (img->type == A5XX_TEX_CUBE) 81bf215546Sopenharmony_ci img->type = A5XX_TEX_2D; 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci if (prsc->target == PIPE_BUFFER) { 84bf215546Sopenharmony_ci img->buffer = true; 85bf215546Sopenharmony_ci img->offset = pimg->u.buf.offset; 86bf215546Sopenharmony_ci img->pitch = 0; 87bf215546Sopenharmony_ci img->array_pitch = 0; 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci /* size is encoded with low 15b in WIDTH and high bits in 90bf215546Sopenharmony_ci * HEIGHT, in units of elements: 91bf215546Sopenharmony_ci */ 92bf215546Sopenharmony_ci unsigned sz = pimg->u.buf.size / util_format_get_blocksize(format); 93bf215546Sopenharmony_ci img->width = sz & MASK(15); 94bf215546Sopenharmony_ci img->height = sz >> 15; 95bf215546Sopenharmony_ci img->depth = 0; 96bf215546Sopenharmony_ci } else { 97bf215546Sopenharmony_ci img->buffer = false; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci unsigned lvl = pimg->u.tex.level; 100bf215546Sopenharmony_ci img->offset = fd_resource_offset(rsc, lvl, pimg->u.tex.first_layer); 101bf215546Sopenharmony_ci img->pitch = fd_resource_pitch(rsc, lvl); 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci img->width = u_minify(prsc->width0, lvl); 104bf215546Sopenharmony_ci img->height = u_minify(prsc->height0, lvl); 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci unsigned layers = pimg->u.tex.last_layer - pimg->u.tex.first_layer + 1; 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci switch (prsc->target) { 109bf215546Sopenharmony_ci case PIPE_TEXTURE_RECT: 110bf215546Sopenharmony_ci case PIPE_TEXTURE_1D: 111bf215546Sopenharmony_ci case PIPE_TEXTURE_2D: 112bf215546Sopenharmony_ci img->array_pitch = rsc->layout.layer_size; 113bf215546Sopenharmony_ci img->depth = 1; 114bf215546Sopenharmony_ci break; 115bf215546Sopenharmony_ci case PIPE_TEXTURE_1D_ARRAY: 116bf215546Sopenharmony_ci case PIPE_TEXTURE_2D_ARRAY: 117bf215546Sopenharmony_ci img->array_pitch = rsc->layout.layer_size; 118bf215546Sopenharmony_ci img->depth = layers; 119bf215546Sopenharmony_ci break; 120bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE: 121bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE_ARRAY: 122bf215546Sopenharmony_ci img->array_pitch = rsc->layout.layer_size; 123bf215546Sopenharmony_ci img->depth = layers; 124bf215546Sopenharmony_ci break; 125bf215546Sopenharmony_ci case PIPE_TEXTURE_3D: 126bf215546Sopenharmony_ci img->array_pitch = fd_resource_slice(rsc, lvl)->size0; 127bf215546Sopenharmony_ci img->depth = u_minify(prsc->depth0, lvl); 128bf215546Sopenharmony_ci break; 129bf215546Sopenharmony_ci default: 130bf215546Sopenharmony_ci img->array_pitch = 0; 131bf215546Sopenharmony_ci img->depth = 0; 132bf215546Sopenharmony_ci break; 133bf215546Sopenharmony_ci } 134bf215546Sopenharmony_ci } 135bf215546Sopenharmony_ci} 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_cistatic void 138bf215546Sopenharmony_ciemit_image_tex(struct fd_ringbuffer *ring, unsigned slot, struct fd5_image *img, 139bf215546Sopenharmony_ci enum pipe_shader_type shader) 140bf215546Sopenharmony_ci{ 141bf215546Sopenharmony_ci OUT_PKT7(ring, CP_LOAD_STATE4, 3 + 12); 142bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(slot) | 143bf215546Sopenharmony_ci CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) | 144bf215546Sopenharmony_ci CP_LOAD_STATE4_0_STATE_BLOCK(texsb[shader]) | 145bf215546Sopenharmony_ci CP_LOAD_STATE4_0_NUM_UNIT(1)); 146bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS) | 147bf215546Sopenharmony_ci CP_LOAD_STATE4_1_EXT_SRC_ADDR(0)); 148bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0)); 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci OUT_RING(ring, A5XX_TEX_CONST_0_FMT(img->fmt) | 151bf215546Sopenharmony_ci fd5_tex_swiz(img->pfmt, PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, 152bf215546Sopenharmony_ci PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W) | 153bf215546Sopenharmony_ci COND(img->srgb, A5XX_TEX_CONST_0_SRGB)); 154bf215546Sopenharmony_ci OUT_RING(ring, A5XX_TEX_CONST_1_WIDTH(img->width) | 155bf215546Sopenharmony_ci A5XX_TEX_CONST_1_HEIGHT(img->height)); 156bf215546Sopenharmony_ci OUT_RING(ring, 157bf215546Sopenharmony_ci COND(img->buffer, A5XX_TEX_CONST_2_BUFFER) | 158bf215546Sopenharmony_ci A5XX_TEX_CONST_2_TYPE(img->type) | 159bf215546Sopenharmony_ci A5XX_TEX_CONST_2_PITCH(img->pitch)); 160bf215546Sopenharmony_ci OUT_RING(ring, A5XX_TEX_CONST_3_ARRAY_PITCH(img->array_pitch)); 161bf215546Sopenharmony_ci if (img->bo) { 162bf215546Sopenharmony_ci OUT_RELOC(ring, img->bo, img->offset, 163bf215546Sopenharmony_ci (uint64_t)A5XX_TEX_CONST_5_DEPTH(img->depth) << 32, 0); 164bf215546Sopenharmony_ci } else { 165bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 166bf215546Sopenharmony_ci OUT_RING(ring, A5XX_TEX_CONST_5_DEPTH(img->depth)); 167bf215546Sopenharmony_ci } 168bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 169bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 170bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 171bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 172bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 173bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 174bf215546Sopenharmony_ci} 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_cistatic void 177bf215546Sopenharmony_ciemit_image_ssbo(struct fd_ringbuffer *ring, unsigned slot, 178bf215546Sopenharmony_ci struct fd5_image *img, enum pipe_shader_type shader) 179bf215546Sopenharmony_ci{ 180bf215546Sopenharmony_ci OUT_PKT7(ring, CP_LOAD_STATE4, 3 + 2); 181bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(slot) | 182bf215546Sopenharmony_ci CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) | 183bf215546Sopenharmony_ci CP_LOAD_STATE4_0_STATE_BLOCK(imgsb[shader]) | 184bf215546Sopenharmony_ci CP_LOAD_STATE4_0_NUM_UNIT(1)); 185bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS) | 186bf215546Sopenharmony_ci CP_LOAD_STATE4_1_EXT_SRC_ADDR(0)); 187bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0)); 188bf215546Sopenharmony_ci OUT_RING(ring, 189bf215546Sopenharmony_ci A5XX_SSBO_1_0_FMT(img->fmt) | A5XX_SSBO_1_0_WIDTH(img->width)); 190bf215546Sopenharmony_ci OUT_RING(ring, A5XX_SSBO_1_1_HEIGHT(img->height) | 191bf215546Sopenharmony_ci A5XX_SSBO_1_1_DEPTH(img->depth)); 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci OUT_PKT7(ring, CP_LOAD_STATE4, 3 + 2); 194bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(slot) | 195bf215546Sopenharmony_ci CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) | 196bf215546Sopenharmony_ci CP_LOAD_STATE4_0_STATE_BLOCK(imgsb[shader]) | 197bf215546Sopenharmony_ci CP_LOAD_STATE4_0_NUM_UNIT(1)); 198bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(ST4_UBO) | 199bf215546Sopenharmony_ci CP_LOAD_STATE4_1_EXT_SRC_ADDR(0)); 200bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0)); 201bf215546Sopenharmony_ci if (img->bo) { 202bf215546Sopenharmony_ci OUT_RELOC(ring, img->bo, img->offset, 0, 0); 203bf215546Sopenharmony_ci } else { 204bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 205bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 206bf215546Sopenharmony_ci } 207bf215546Sopenharmony_ci} 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci/* Emit required "SSBO" and sampler state. The sampler state is used by the 210bf215546Sopenharmony_ci * hw for imageLoad(), and "SSBO" state for imageStore(). Returns max sampler 211bf215546Sopenharmony_ci * used. 212bf215546Sopenharmony_ci */ 213bf215546Sopenharmony_civoid 214bf215546Sopenharmony_cifd5_emit_images(struct fd_context *ctx, struct fd_ringbuffer *ring, 215bf215546Sopenharmony_ci enum pipe_shader_type shader, 216bf215546Sopenharmony_ci const struct ir3_shader_variant *v) 217bf215546Sopenharmony_ci{ 218bf215546Sopenharmony_ci struct fd_shaderimg_stateobj *so = &ctx->shaderimg[shader]; 219bf215546Sopenharmony_ci unsigned enabled_mask = so->enabled_mask; 220bf215546Sopenharmony_ci const struct ir3_ibo_mapping *m = &v->image_mapping; 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci while (enabled_mask) { 223bf215546Sopenharmony_ci unsigned index = u_bit_scan(&enabled_mask); 224bf215546Sopenharmony_ci struct fd5_image img; 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci translate_image(&img, &so->si[index]); 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci emit_image_tex(ring, m->image_to_tex[index] + m->tex_base, &img, shader); 229bf215546Sopenharmony_ci emit_image_ssbo(ring, v->num_ssbos + index, &img, 230bf215546Sopenharmony_ci shader); 231bf215546Sopenharmony_ci } 232bf215546Sopenharmony_ci} 233