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 "freedreno_resource.h" 30bf215546Sopenharmony_ci#include "fd4_image.h" 31bf215546Sopenharmony_ci#include "fd4_format.h" 32bf215546Sopenharmony_ci#include "fd4_texture.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 fd4_image { 45bf215546Sopenharmony_ci enum pipe_format pfmt; 46bf215546Sopenharmony_ci enum a4xx_color_fmt fmt; 47bf215546Sopenharmony_ci enum a4xx_tex_fmt texfmt; 48bf215546Sopenharmony_ci enum a4xx_tex_type type; 49bf215546Sopenharmony_ci bool srgb; 50bf215546Sopenharmony_ci uint32_t cpp; 51bf215546Sopenharmony_ci uint32_t width; 52bf215546Sopenharmony_ci uint32_t height; 53bf215546Sopenharmony_ci uint32_t depth; 54bf215546Sopenharmony_ci uint32_t pitch; 55bf215546Sopenharmony_ci uint32_t array_pitch; 56bf215546Sopenharmony_ci uint32_t pitchalign; 57bf215546Sopenharmony_ci struct fd_bo *bo; 58bf215546Sopenharmony_ci uint32_t offset; 59bf215546Sopenharmony_ci bool buffer; 60bf215546Sopenharmony_ci uint32_t texconst4; 61bf215546Sopenharmony_ci}; 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_cistatic void translate_image(struct fd4_image *img, struct pipe_image_view *pimg) 64bf215546Sopenharmony_ci{ 65bf215546Sopenharmony_ci enum pipe_format format = pimg->format; 66bf215546Sopenharmony_ci struct pipe_resource *prsc = pimg->resource; 67bf215546Sopenharmony_ci struct fd_resource *rsc = fd_resource(prsc); 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci if (!pimg->resource) { 70bf215546Sopenharmony_ci memset(img, 0, sizeof(*img)); 71bf215546Sopenharmony_ci return; 72bf215546Sopenharmony_ci } 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci img->pfmt = format; 75bf215546Sopenharmony_ci img->fmt = fd4_pipe2color(format); 76bf215546Sopenharmony_ci img->texfmt = fd4_pipe2tex(format); 77bf215546Sopenharmony_ci img->type = fd4_tex_type(prsc->target); 78bf215546Sopenharmony_ci img->srgb = util_format_is_srgb(format); 79bf215546Sopenharmony_ci img->bo = rsc->bo; 80bf215546Sopenharmony_ci img->texconst4 = 0; 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci /* Treat cube textures as 2d-array: */ 83bf215546Sopenharmony_ci if (img->type == A4XX_TEX_CUBE) 84bf215546Sopenharmony_ci img->type = A4XX_TEX_2D; 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci if (prsc->target == PIPE_BUFFER) { 87bf215546Sopenharmony_ci img->buffer = true; 88bf215546Sopenharmony_ci img->offset = pimg->u.buf.offset; 89bf215546Sopenharmony_ci img->cpp = util_format_get_blocksize(format); 90bf215546Sopenharmony_ci img->array_pitch = 0; 91bf215546Sopenharmony_ci img->pitch = 0; 92bf215546Sopenharmony_ci img->pitchalign = 0; 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci /* size is encoded with low 16b in WIDTH and high bits in 95bf215546Sopenharmony_ci * HEIGHT, in units of elements: 96bf215546Sopenharmony_ci */ 97bf215546Sopenharmony_ci unsigned sz = pimg->u.buf.size / img->cpp; 98bf215546Sopenharmony_ci img->width = sz & MASK(16); 99bf215546Sopenharmony_ci img->height = sz >> 16; 100bf215546Sopenharmony_ci img->depth = 0; 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci /* Note that the blob sets the PITCH to the CPP in the SSBO descriptor, 103bf215546Sopenharmony_ci * but that messes up the sampler we create, so skip that. 104bf215546Sopenharmony_ci */ 105bf215546Sopenharmony_ci } else { 106bf215546Sopenharmony_ci img->buffer = false; 107bf215546Sopenharmony_ci img->cpp = rsc->layout.cpp; 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci unsigned lvl = pimg->u.tex.level; 110bf215546Sopenharmony_ci img->offset = fd_resource_offset(rsc, lvl, pimg->u.tex.first_layer); 111bf215546Sopenharmony_ci img->pitch = fd_resource_pitch(rsc, lvl); 112bf215546Sopenharmony_ci img->pitchalign = rsc->layout.pitchalign - 5; 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci img->width = u_minify(prsc->width0, lvl); 115bf215546Sopenharmony_ci img->height = u_minify(prsc->height0, lvl); 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci unsigned layers = pimg->u.tex.last_layer - pimg->u.tex.first_layer + 1; 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci switch (prsc->target) { 120bf215546Sopenharmony_ci case PIPE_TEXTURE_RECT: 121bf215546Sopenharmony_ci case PIPE_TEXTURE_1D: 122bf215546Sopenharmony_ci case PIPE_TEXTURE_2D: 123bf215546Sopenharmony_ci img->array_pitch = rsc->layout.layer_size; 124bf215546Sopenharmony_ci img->depth = 1; 125bf215546Sopenharmony_ci break; 126bf215546Sopenharmony_ci case PIPE_TEXTURE_1D_ARRAY: 127bf215546Sopenharmony_ci case PIPE_TEXTURE_2D_ARRAY: 128bf215546Sopenharmony_ci img->array_pitch = rsc->layout.layer_size; 129bf215546Sopenharmony_ci img->depth = layers; 130bf215546Sopenharmony_ci break; 131bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE: 132bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE_ARRAY: 133bf215546Sopenharmony_ci img->array_pitch = rsc->layout.layer_size; 134bf215546Sopenharmony_ci img->depth = layers; 135bf215546Sopenharmony_ci break; 136bf215546Sopenharmony_ci case PIPE_TEXTURE_3D: 137bf215546Sopenharmony_ci img->array_pitch = fd_resource_slice(rsc, lvl)->size0; 138bf215546Sopenharmony_ci img->depth = u_minify(prsc->depth0, lvl); 139bf215546Sopenharmony_ci if (layers == 1 && img->depth > 1) { 140bf215546Sopenharmony_ci img->type = A4XX_TEX_2D; 141bf215546Sopenharmony_ci img->depth = 1; 142bf215546Sopenharmony_ci } else { 143bf215546Sopenharmony_ci img->texconst4 = A4XX_TEX_CONST_4_LAYERSZ(img->array_pitch); 144bf215546Sopenharmony_ci } 145bf215546Sopenharmony_ci break; 146bf215546Sopenharmony_ci default: 147bf215546Sopenharmony_ci img->array_pitch = 0; 148bf215546Sopenharmony_ci img->depth = 0; 149bf215546Sopenharmony_ci break; 150bf215546Sopenharmony_ci } 151bf215546Sopenharmony_ci } 152bf215546Sopenharmony_ci} 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_cistatic void emit_image_tex(struct fd_ringbuffer *ring, unsigned slot, 155bf215546Sopenharmony_ci struct fd4_image *img, enum pipe_shader_type shader) 156bf215546Sopenharmony_ci{ 157bf215546Sopenharmony_ci OUT_PKT3(ring, CP_LOAD_STATE4, 2 + 8); 158bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(slot) | 159bf215546Sopenharmony_ci CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) | 160bf215546Sopenharmony_ci CP_LOAD_STATE4_0_STATE_BLOCK(texsb[shader]) | 161bf215546Sopenharmony_ci CP_LOAD_STATE4_0_NUM_UNIT(1)); 162bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS) | 163bf215546Sopenharmony_ci CP_LOAD_STATE4_1_EXT_SRC_ADDR(0)); 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci OUT_RING(ring, A4XX_TEX_CONST_0_FMT(img->texfmt) | 166bf215546Sopenharmony_ci A4XX_TEX_CONST_0_TYPE(img->type) | 167bf215546Sopenharmony_ci fd4_tex_swiz(img->pfmt, PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, 168bf215546Sopenharmony_ci PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W) | 169bf215546Sopenharmony_ci COND(img->srgb, A4XX_TEX_CONST_0_SRGB)); 170bf215546Sopenharmony_ci OUT_RING(ring, A4XX_TEX_CONST_1_WIDTH(img->width) | 171bf215546Sopenharmony_ci A4XX_TEX_CONST_1_HEIGHT(img->height)); 172bf215546Sopenharmony_ci OUT_RING(ring, A4XX_TEX_CONST_2_PITCHALIGN(img->pitchalign) | 173bf215546Sopenharmony_ci A4XX_TEX_CONST_2_PITCH(img->pitch) | 174bf215546Sopenharmony_ci COND(img->buffer, A4XX_TEX_CONST_2_BUFFER)); 175bf215546Sopenharmony_ci OUT_RING(ring, A4XX_TEX_CONST_3_DEPTH(img->depth) | 176bf215546Sopenharmony_ci A4XX_TEX_CONST_3_LAYERSZ(img->array_pitch)); 177bf215546Sopenharmony_ci if (img->bo) { 178bf215546Sopenharmony_ci OUT_RELOC(ring, img->bo, img->offset, img->texconst4, 0); 179bf215546Sopenharmony_ci } else { 180bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 181bf215546Sopenharmony_ci } 182bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 183bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 184bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci /* Per fd4_emit.c, some of the hw likes samplers in pairs */ 187bf215546Sopenharmony_ci OUT_PKT3(ring, CP_LOAD_STATE4, 2 + 4); 188bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(slot) | 189bf215546Sopenharmony_ci CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) | 190bf215546Sopenharmony_ci CP_LOAD_STATE4_0_STATE_BLOCK(texsb[shader]) | 191bf215546Sopenharmony_ci CP_LOAD_STATE4_0_NUM_UNIT(2)); 192bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(ST4_SHADER) | 193bf215546Sopenharmony_ci CP_LOAD_STATE4_1_EXT_SRC_ADDR(0)); 194bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 195bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 196bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 197bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 198bf215546Sopenharmony_ci} 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_cistatic void emit_image_ssbo(struct fd_ringbuffer *ring, unsigned slot, 201bf215546Sopenharmony_ci struct fd4_image *img, enum pipe_shader_type shader) 202bf215546Sopenharmony_ci{ 203bf215546Sopenharmony_ci OUT_PKT3(ring, CP_LOAD_STATE4, 2 + 4); 204bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(slot) | 205bf215546Sopenharmony_ci CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) | 206bf215546Sopenharmony_ci CP_LOAD_STATE4_0_STATE_BLOCK(imgsb[shader]) | 207bf215546Sopenharmony_ci CP_LOAD_STATE4_0_NUM_UNIT(1)); 208bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(0) | 209bf215546Sopenharmony_ci CP_LOAD_STATE4_1_EXT_SRC_ADDR(0)); 210bf215546Sopenharmony_ci OUT_RELOC(ring, img->bo, img->offset, 0, 0); 211bf215546Sopenharmony_ci OUT_RING(ring, A4XX_SSBO_0_1_PITCH(img->pitch)); 212bf215546Sopenharmony_ci OUT_RING(ring, A4XX_SSBO_0_2_ARRAY_PITCH(img->array_pitch)); 213bf215546Sopenharmony_ci OUT_RING(ring, A4XX_SSBO_0_3_CPP(img->cpp)); 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci OUT_PKT3(ring, CP_LOAD_STATE4, 2 + 2); 216bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(slot) | 217bf215546Sopenharmony_ci CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) | 218bf215546Sopenharmony_ci CP_LOAD_STATE4_0_STATE_BLOCK(imgsb[shader]) | 219bf215546Sopenharmony_ci CP_LOAD_STATE4_0_NUM_UNIT(1)); 220bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(1) | 221bf215546Sopenharmony_ci CP_LOAD_STATE4_1_EXT_SRC_ADDR(0)); 222bf215546Sopenharmony_ci OUT_RING(ring, A4XX_SSBO_1_0_CPP(img->cpp) | 223bf215546Sopenharmony_ci A4XX_SSBO_1_0_FMT(img->fmt) | 224bf215546Sopenharmony_ci A4XX_SSBO_1_0_WIDTH(img->width)); 225bf215546Sopenharmony_ci OUT_RING(ring, A4XX_SSBO_1_1_HEIGHT(img->height) | 226bf215546Sopenharmony_ci A4XX_SSBO_1_1_DEPTH(img->depth)); 227bf215546Sopenharmony_ci} 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci/* Emit required "SSBO" and sampler state. The sampler state is used by the 230bf215546Sopenharmony_ci * hw for imageLoad(), and "SSBO" state for imageStore(). Returns max sampler 231bf215546Sopenharmony_ci * used. 232bf215546Sopenharmony_ci */ 233bf215546Sopenharmony_civoid 234bf215546Sopenharmony_cifd4_emit_images(struct fd_context *ctx, struct fd_ringbuffer *ring, 235bf215546Sopenharmony_ci enum pipe_shader_type shader, 236bf215546Sopenharmony_ci const struct ir3_shader_variant *v) 237bf215546Sopenharmony_ci{ 238bf215546Sopenharmony_ci struct fd_shaderimg_stateobj *so = &ctx->shaderimg[shader]; 239bf215546Sopenharmony_ci unsigned enabled_mask = so->enabled_mask; 240bf215546Sopenharmony_ci const struct ir3_ibo_mapping *m = &v->image_mapping; 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_ci while (enabled_mask) { 243bf215546Sopenharmony_ci unsigned index = u_bit_scan(&enabled_mask); 244bf215546Sopenharmony_ci struct fd4_image img; 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci translate_image(&img, &so->si[index]); 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci if (m->image_to_tex[index] != IBO_INVALID) 249bf215546Sopenharmony_ci emit_image_tex(ring, m->image_to_tex[index] + m->tex_base, &img, shader); 250bf215546Sopenharmony_ci emit_image_ssbo(ring, v->num_ssbos + index, &img, shader); 251bf215546Sopenharmony_ci } 252bf215546Sopenharmony_ci} 253