1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2008 Ben Skeggs 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 shall be included in 12bf215546Sopenharmony_ci * all copies or substantial portions of the Software. 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 21bf215546Sopenharmony_ci */ 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ci#include "nvc0/nvc0_context.h" 24bf215546Sopenharmony_ci#include "nvc0/nvc0_resource.h" 25bf215546Sopenharmony_ci#include "nvc0/gm107_texture.xml.h" 26bf215546Sopenharmony_ci#include "nvc0/nvc0_compute.xml.h" 27bf215546Sopenharmony_ci#include "nv50/g80_texture.xml.h" 28bf215546Sopenharmony_ci#include "nv50/g80_defs.xml.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "util/format/u_format.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#define NVE4_TIC_ENTRY_INVALID 0x000fffff 33bf215546Sopenharmony_ci#define NVE4_TSC_ENTRY_INVALID 0xfff00000 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_cistatic inline uint32_t 36bf215546Sopenharmony_cinv50_tic_swizzle(const struct nvc0_format *fmt, unsigned swz, bool tex_int) 37bf215546Sopenharmony_ci{ 38bf215546Sopenharmony_ci switch (swz) { 39bf215546Sopenharmony_ci case PIPE_SWIZZLE_X : return fmt->tic.src_x; 40bf215546Sopenharmony_ci case PIPE_SWIZZLE_Y: return fmt->tic.src_y; 41bf215546Sopenharmony_ci case PIPE_SWIZZLE_Z : return fmt->tic.src_z; 42bf215546Sopenharmony_ci case PIPE_SWIZZLE_W: return fmt->tic.src_w; 43bf215546Sopenharmony_ci case PIPE_SWIZZLE_1: 44bf215546Sopenharmony_ci return tex_int ? G80_TIC_SOURCE_ONE_INT : G80_TIC_SOURCE_ONE_FLOAT; 45bf215546Sopenharmony_ci case PIPE_SWIZZLE_0: 46bf215546Sopenharmony_ci default: 47bf215546Sopenharmony_ci return G80_TIC_SOURCE_ZERO; 48bf215546Sopenharmony_ci } 49bf215546Sopenharmony_ci} 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_cistruct pipe_sampler_view * 52bf215546Sopenharmony_cinvc0_create_sampler_view(struct pipe_context *pipe, 53bf215546Sopenharmony_ci struct pipe_resource *res, 54bf215546Sopenharmony_ci const struct pipe_sampler_view *templ) 55bf215546Sopenharmony_ci{ 56bf215546Sopenharmony_ci uint32_t flags = 0; 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci if (templ->target == PIPE_TEXTURE_RECT || templ->target == PIPE_BUFFER) 59bf215546Sopenharmony_ci flags |= NV50_TEXVIEW_SCALED_COORDS; 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci return nvc0_create_texture_view(pipe, res, templ, flags); 62bf215546Sopenharmony_ci} 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_cistatic struct pipe_sampler_view * 65bf215546Sopenharmony_cigm107_create_texture_view(struct pipe_context *pipe, 66bf215546Sopenharmony_ci struct pipe_resource *texture, 67bf215546Sopenharmony_ci const struct pipe_sampler_view *templ, 68bf215546Sopenharmony_ci uint32_t flags) 69bf215546Sopenharmony_ci{ 70bf215546Sopenharmony_ci const struct util_format_description *desc; 71bf215546Sopenharmony_ci const struct nvc0_format *fmt; 72bf215546Sopenharmony_ci uint64_t address; 73bf215546Sopenharmony_ci uint32_t *tic; 74bf215546Sopenharmony_ci uint32_t swz[4]; 75bf215546Sopenharmony_ci uint32_t width, height; 76bf215546Sopenharmony_ci uint32_t depth; 77bf215546Sopenharmony_ci struct nv50_tic_entry *view; 78bf215546Sopenharmony_ci struct nv50_miptree *mt; 79bf215546Sopenharmony_ci bool tex_int; 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci view = MALLOC_STRUCT(nv50_tic_entry); 82bf215546Sopenharmony_ci if (!view) 83bf215546Sopenharmony_ci return NULL; 84bf215546Sopenharmony_ci mt = nv50_miptree(texture); 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci view->pipe = *templ; 87bf215546Sopenharmony_ci view->pipe.reference.count = 1; 88bf215546Sopenharmony_ci view->pipe.texture = NULL; 89bf215546Sopenharmony_ci view->pipe.context = pipe; 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci view->id = -1; 92bf215546Sopenharmony_ci view->bindless = 0; 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci pipe_resource_reference(&view->pipe.texture, texture); 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci tic = &view->tic[0]; 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci desc = util_format_description(view->pipe.format); 99bf215546Sopenharmony_ci tex_int = util_format_is_pure_integer(view->pipe.format); 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci fmt = &nvc0_format_table[view->pipe.format]; 102bf215546Sopenharmony_ci swz[0] = nv50_tic_swizzle(fmt, view->pipe.swizzle_r, tex_int); 103bf215546Sopenharmony_ci swz[1] = nv50_tic_swizzle(fmt, view->pipe.swizzle_g, tex_int); 104bf215546Sopenharmony_ci swz[2] = nv50_tic_swizzle(fmt, view->pipe.swizzle_b, tex_int); 105bf215546Sopenharmony_ci swz[3] = nv50_tic_swizzle(fmt, view->pipe.swizzle_a, tex_int); 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci tic[0] = fmt->tic.format << GM107_TIC2_0_COMPONENTS_SIZES__SHIFT; 108bf215546Sopenharmony_ci tic[0] |= fmt->tic.type_r << GM107_TIC2_0_R_DATA_TYPE__SHIFT; 109bf215546Sopenharmony_ci tic[0] |= fmt->tic.type_g << GM107_TIC2_0_G_DATA_TYPE__SHIFT; 110bf215546Sopenharmony_ci tic[0] |= fmt->tic.type_b << GM107_TIC2_0_B_DATA_TYPE__SHIFT; 111bf215546Sopenharmony_ci tic[0] |= fmt->tic.type_a << GM107_TIC2_0_A_DATA_TYPE__SHIFT; 112bf215546Sopenharmony_ci tic[0] |= swz[0] << GM107_TIC2_0_X_SOURCE__SHIFT; 113bf215546Sopenharmony_ci tic[0] |= swz[1] << GM107_TIC2_0_Y_SOURCE__SHIFT; 114bf215546Sopenharmony_ci tic[0] |= swz[2] << GM107_TIC2_0_Z_SOURCE__SHIFT; 115bf215546Sopenharmony_ci tic[0] |= swz[3] << GM107_TIC2_0_W_SOURCE__SHIFT; 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci address = mt->base.address; 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci tic[3] = GM107_TIC2_3_LOD_ANISO_QUALITY_2; 120bf215546Sopenharmony_ci tic[4] = GM107_TIC2_4_SECTOR_PROMOTION_PROMOTE_TO_2_V; 121bf215546Sopenharmony_ci tic[4] |= GM107_TIC2_4_BORDER_SIZE_SAMPLER_COLOR; 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) 124bf215546Sopenharmony_ci tic[4] |= GM107_TIC2_4_SRGB_CONVERSION; 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci if (!(flags & NV50_TEXVIEW_SCALED_COORDS)) 127bf215546Sopenharmony_ci tic[5] = GM107_TIC2_5_NORMALIZED_COORDS; 128bf215546Sopenharmony_ci else 129bf215546Sopenharmony_ci tic[5] = 0; 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci /* check for linear storage type */ 132bf215546Sopenharmony_ci if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) { 133bf215546Sopenharmony_ci if (texture->target == PIPE_BUFFER) { 134bf215546Sopenharmony_ci assert(!(tic[5] & GM107_TIC2_5_NORMALIZED_COORDS)); 135bf215546Sopenharmony_ci width = view->pipe.u.buf.size / (desc->block.bits / 8) - 1; 136bf215546Sopenharmony_ci address += 137bf215546Sopenharmony_ci view->pipe.u.buf.offset; 138bf215546Sopenharmony_ci tic[2] = GM107_TIC2_2_HEADER_VERSION_ONE_D_BUFFER; 139bf215546Sopenharmony_ci tic[3] |= width >> 16; 140bf215546Sopenharmony_ci tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_ONE_D_BUFFER; 141bf215546Sopenharmony_ci tic[4] |= width & 0xffff; 142bf215546Sopenharmony_ci } else { 143bf215546Sopenharmony_ci assert(!(mt->level[0].pitch & 0x1f)); 144bf215546Sopenharmony_ci /* must be 2D texture without mip maps */ 145bf215546Sopenharmony_ci tic[2] = GM107_TIC2_2_HEADER_VERSION_PITCH; 146bf215546Sopenharmony_ci tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_TWO_D_NO_MIPMAP; 147bf215546Sopenharmony_ci tic[3] |= mt->level[0].pitch >> 5; 148bf215546Sopenharmony_ci tic[4] |= mt->base.base.width0 - 1; 149bf215546Sopenharmony_ci tic[5] |= 0 << GM107_TIC2_5_DEPTH_MINUS_ONE__SHIFT; 150bf215546Sopenharmony_ci tic[5] |= mt->base.base.height0 - 1; 151bf215546Sopenharmony_ci } 152bf215546Sopenharmony_ci tic[1] = address; 153bf215546Sopenharmony_ci tic[2] |= address >> 32; 154bf215546Sopenharmony_ci tic[6] = 0; 155bf215546Sopenharmony_ci tic[7] = 0; 156bf215546Sopenharmony_ci return &view->pipe; 157bf215546Sopenharmony_ci } 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci tic[2] = GM107_TIC2_2_HEADER_VERSION_BLOCKLINEAR; 160bf215546Sopenharmony_ci tic[3] |= 161bf215546Sopenharmony_ci ((mt->level[0].tile_mode & 0x0f0) >> 4 << 3) | 162bf215546Sopenharmony_ci ((mt->level[0].tile_mode & 0xf00) >> 8 << 6); 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci depth = MAX2(mt->base.base.array_size, mt->base.base.depth0); 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci if (mt->base.base.array_size > 1) { 167bf215546Sopenharmony_ci /* there doesn't seem to be a base layer field in TIC */ 168bf215546Sopenharmony_ci address += view->pipe.u.tex.first_layer * mt->layer_stride; 169bf215546Sopenharmony_ci depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1; 170bf215546Sopenharmony_ci } 171bf215546Sopenharmony_ci tic[1] = address; 172bf215546Sopenharmony_ci tic[2] |= address >> 32; 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci switch (templ->target) { 175bf215546Sopenharmony_ci case PIPE_TEXTURE_1D: 176bf215546Sopenharmony_ci tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_ONE_D; 177bf215546Sopenharmony_ci break; 178bf215546Sopenharmony_ci case PIPE_TEXTURE_2D: 179bf215546Sopenharmony_ci tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_TWO_D; 180bf215546Sopenharmony_ci break; 181bf215546Sopenharmony_ci case PIPE_TEXTURE_RECT: 182bf215546Sopenharmony_ci tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_TWO_D; 183bf215546Sopenharmony_ci break; 184bf215546Sopenharmony_ci case PIPE_TEXTURE_3D: 185bf215546Sopenharmony_ci tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_THREE_D; 186bf215546Sopenharmony_ci break; 187bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE: 188bf215546Sopenharmony_ci depth /= 6; 189bf215546Sopenharmony_ci tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_CUBEMAP; 190bf215546Sopenharmony_ci break; 191bf215546Sopenharmony_ci case PIPE_TEXTURE_1D_ARRAY: 192bf215546Sopenharmony_ci tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_ONE_D_ARRAY; 193bf215546Sopenharmony_ci break; 194bf215546Sopenharmony_ci case PIPE_TEXTURE_2D_ARRAY: 195bf215546Sopenharmony_ci tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_TWO_D_ARRAY; 196bf215546Sopenharmony_ci break; 197bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE_ARRAY: 198bf215546Sopenharmony_ci depth /= 6; 199bf215546Sopenharmony_ci tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_CUBE_ARRAY; 200bf215546Sopenharmony_ci break; 201bf215546Sopenharmony_ci default: 202bf215546Sopenharmony_ci unreachable("unexpected/invalid texture target"); 203bf215546Sopenharmony_ci } 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci tic[3] |= (flags & NV50_TEXVIEW_FILTER_MSAA8) ? 206bf215546Sopenharmony_ci GM107_TIC2_3_USE_HEADER_OPT_CONTROL : 207bf215546Sopenharmony_ci GM107_TIC2_3_LOD_ANISO_QUALITY_HIGH | 208bf215546Sopenharmony_ci GM107_TIC2_3_LOD_ISO_QUALITY_HIGH; 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci if (flags & (NV50_TEXVIEW_ACCESS_RESOLVE | NV50_TEXVIEW_IMAGE_GM107)) { 211bf215546Sopenharmony_ci width = mt->base.base.width0 << mt->ms_x; 212bf215546Sopenharmony_ci height = mt->base.base.height0 << mt->ms_y; 213bf215546Sopenharmony_ci } else { 214bf215546Sopenharmony_ci width = mt->base.base.width0; 215bf215546Sopenharmony_ci height = mt->base.base.height0; 216bf215546Sopenharmony_ci } 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci tic[4] |= width - 1; 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci tic[5] |= (height - 1) & 0xffff; 221bf215546Sopenharmony_ci tic[5] |= (depth - 1) << GM107_TIC2_5_DEPTH_MINUS_ONE__SHIFT; 222bf215546Sopenharmony_ci tic[3] |= mt->base.base.last_level << GM107_TIC2_3_MAX_MIP_LEVEL__SHIFT; 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci /* sampling points: (?) */ 225bf215546Sopenharmony_ci if ((flags & NV50_TEXVIEW_ACCESS_RESOLVE) && mt->ms_x > 1) { 226bf215546Sopenharmony_ci tic[6] = GM107_TIC2_6_ANISO_FINE_SPREAD_MODIFIER_CONST_TWO; 227bf215546Sopenharmony_ci tic[6] |= GM107_TIC2_6_MAX_ANISOTROPY_2_TO_1; 228bf215546Sopenharmony_ci } else { 229bf215546Sopenharmony_ci tic[6] = GM107_TIC2_6_ANISO_FINE_SPREAD_FUNC_TWO; 230bf215546Sopenharmony_ci tic[6] |= GM107_TIC2_6_ANISO_COARSE_SPREAD_FUNC_ONE; 231bf215546Sopenharmony_ci } 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level; 234bf215546Sopenharmony_ci tic[7] |= mt->ms_mode << GM107_TIC2_7_MULTI_SAMPLE_COUNT__SHIFT; 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci return &view->pipe; 237bf215546Sopenharmony_ci} 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_cistruct pipe_sampler_view * 240bf215546Sopenharmony_cigm107_create_texture_view_from_image(struct pipe_context *pipe, 241bf215546Sopenharmony_ci const struct pipe_image_view *view) 242bf215546Sopenharmony_ci{ 243bf215546Sopenharmony_ci struct nv04_resource *res = nv04_resource(view->resource); 244bf215546Sopenharmony_ci struct pipe_sampler_view templ = {}; 245bf215546Sopenharmony_ci enum pipe_texture_target target; 246bf215546Sopenharmony_ci uint32_t flags = 0; 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci if (!res) 249bf215546Sopenharmony_ci return NULL; 250bf215546Sopenharmony_ci target = res->base.target; 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci if (target == PIPE_TEXTURE_CUBE || target == PIPE_TEXTURE_CUBE_ARRAY) 253bf215546Sopenharmony_ci target = PIPE_TEXTURE_2D_ARRAY; 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci templ.target = target; 256bf215546Sopenharmony_ci templ.format = view->format; 257bf215546Sopenharmony_ci templ.swizzle_r = PIPE_SWIZZLE_X; 258bf215546Sopenharmony_ci templ.swizzle_g = PIPE_SWIZZLE_Y; 259bf215546Sopenharmony_ci templ.swizzle_b = PIPE_SWIZZLE_Z; 260bf215546Sopenharmony_ci templ.swizzle_a = PIPE_SWIZZLE_W; 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci if (target == PIPE_BUFFER) { 263bf215546Sopenharmony_ci templ.u.buf.offset = view->u.buf.offset; 264bf215546Sopenharmony_ci templ.u.buf.size = view->u.buf.size; 265bf215546Sopenharmony_ci } else { 266bf215546Sopenharmony_ci templ.u.tex.first_layer = view->u.tex.first_layer; 267bf215546Sopenharmony_ci templ.u.tex.last_layer = view->u.tex.last_layer; 268bf215546Sopenharmony_ci templ.u.tex.first_level = templ.u.tex.last_level = view->u.tex.level; 269bf215546Sopenharmony_ci } 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci flags = NV50_TEXVIEW_SCALED_COORDS | NV50_TEXVIEW_IMAGE_GM107; 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_ci return nvc0_create_texture_view(pipe, &res->base, &templ, flags); 274bf215546Sopenharmony_ci} 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_cistatic struct pipe_sampler_view * 277bf215546Sopenharmony_cigf100_create_texture_view(struct pipe_context *pipe, 278bf215546Sopenharmony_ci struct pipe_resource *texture, 279bf215546Sopenharmony_ci const struct pipe_sampler_view *templ, 280bf215546Sopenharmony_ci uint32_t flags) 281bf215546Sopenharmony_ci{ 282bf215546Sopenharmony_ci const struct util_format_description *desc; 283bf215546Sopenharmony_ci const struct nvc0_format *fmt; 284bf215546Sopenharmony_ci uint64_t address; 285bf215546Sopenharmony_ci uint32_t *tic; 286bf215546Sopenharmony_ci uint32_t swz[4]; 287bf215546Sopenharmony_ci uint32_t width, height; 288bf215546Sopenharmony_ci uint32_t depth; 289bf215546Sopenharmony_ci uint32_t tex_fmt; 290bf215546Sopenharmony_ci struct nv50_tic_entry *view; 291bf215546Sopenharmony_ci struct nv50_miptree *mt; 292bf215546Sopenharmony_ci bool tex_int; 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci view = MALLOC_STRUCT(nv50_tic_entry); 295bf215546Sopenharmony_ci if (!view) 296bf215546Sopenharmony_ci return NULL; 297bf215546Sopenharmony_ci mt = nv50_miptree(texture); 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci view->pipe = *templ; 300bf215546Sopenharmony_ci view->pipe.reference.count = 1; 301bf215546Sopenharmony_ci view->pipe.texture = NULL; 302bf215546Sopenharmony_ci view->pipe.context = pipe; 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci view->id = -1; 305bf215546Sopenharmony_ci view->bindless = 0; 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci pipe_resource_reference(&view->pipe.texture, texture); 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci tic = &view->tic[0]; 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_ci desc = util_format_description(view->pipe.format); 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci fmt = &nvc0_format_table[view->pipe.format]; 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci tex_int = util_format_is_pure_integer(view->pipe.format); 316bf215546Sopenharmony_ci tex_fmt = fmt->tic.format & 0x3f; 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci swz[0] = nv50_tic_swizzle(fmt, view->pipe.swizzle_r, tex_int); 319bf215546Sopenharmony_ci swz[1] = nv50_tic_swizzle(fmt, view->pipe.swizzle_g, tex_int); 320bf215546Sopenharmony_ci swz[2] = nv50_tic_swizzle(fmt, view->pipe.swizzle_b, tex_int); 321bf215546Sopenharmony_ci swz[3] = nv50_tic_swizzle(fmt, view->pipe.swizzle_a, tex_int); 322bf215546Sopenharmony_ci tic[0] = (tex_fmt << G80_TIC_0_COMPONENTS_SIZES__SHIFT) | 323bf215546Sopenharmony_ci (fmt->tic.type_r << G80_TIC_0_R_DATA_TYPE__SHIFT) | 324bf215546Sopenharmony_ci (fmt->tic.type_g << G80_TIC_0_G_DATA_TYPE__SHIFT) | 325bf215546Sopenharmony_ci (fmt->tic.type_b << G80_TIC_0_B_DATA_TYPE__SHIFT) | 326bf215546Sopenharmony_ci (fmt->tic.type_a << G80_TIC_0_A_DATA_TYPE__SHIFT) | 327bf215546Sopenharmony_ci (swz[0] << G80_TIC_0_X_SOURCE__SHIFT) | 328bf215546Sopenharmony_ci (swz[1] << G80_TIC_0_Y_SOURCE__SHIFT) | 329bf215546Sopenharmony_ci (swz[2] << G80_TIC_0_Z_SOURCE__SHIFT) | 330bf215546Sopenharmony_ci (swz[3] << G80_TIC_0_W_SOURCE__SHIFT) | 331bf215546Sopenharmony_ci ((fmt->tic.format & 0x40) << (GK20A_TIC_0_USE_COMPONENT_SIZES_EXTENDED__SHIFT - 6)); 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci address = mt->base.address; 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci tic[2] = 0x10001000 | G80_TIC_2_BORDER_SOURCE_COLOR; 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) 338bf215546Sopenharmony_ci tic[2] |= G80_TIC_2_SRGB_CONVERSION; 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci if (!(flags & NV50_TEXVIEW_SCALED_COORDS)) 341bf215546Sopenharmony_ci tic[2] |= G80_TIC_2_NORMALIZED_COORDS; 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci /* check for linear storage type */ 344bf215546Sopenharmony_ci if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) { 345bf215546Sopenharmony_ci if (texture->target == PIPE_BUFFER) { 346bf215546Sopenharmony_ci assert(!(tic[2] & G80_TIC_2_NORMALIZED_COORDS)); 347bf215546Sopenharmony_ci address += 348bf215546Sopenharmony_ci view->pipe.u.buf.offset; 349bf215546Sopenharmony_ci tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_ONE_D_BUFFER; 350bf215546Sopenharmony_ci tic[3] = 0; 351bf215546Sopenharmony_ci tic[4] = /* width */ 352bf215546Sopenharmony_ci view->pipe.u.buf.size / (desc->block.bits / 8); 353bf215546Sopenharmony_ci tic[5] = 0; 354bf215546Sopenharmony_ci } else { 355bf215546Sopenharmony_ci /* must be 2D texture without mip maps */ 356bf215546Sopenharmony_ci tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_TWO_D_NO_MIPMAP; 357bf215546Sopenharmony_ci tic[3] = mt->level[0].pitch; 358bf215546Sopenharmony_ci tic[4] = mt->base.base.width0; 359bf215546Sopenharmony_ci tic[5] = (1 << 16) | mt->base.base.height0; 360bf215546Sopenharmony_ci } 361bf215546Sopenharmony_ci tic[6] = 362bf215546Sopenharmony_ci tic[7] = 0; 363bf215546Sopenharmony_ci tic[1] = address; 364bf215546Sopenharmony_ci tic[2] |= address >> 32; 365bf215546Sopenharmony_ci return &view->pipe; 366bf215546Sopenharmony_ci } 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci tic[2] |= 369bf215546Sopenharmony_ci ((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) | 370bf215546Sopenharmony_ci ((mt->level[0].tile_mode & 0xf00) << (25 - 8)); 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci depth = MAX2(mt->base.base.array_size, mt->base.base.depth0); 373bf215546Sopenharmony_ci 374bf215546Sopenharmony_ci if (mt->base.base.array_size > 1) { 375bf215546Sopenharmony_ci /* there doesn't seem to be a base layer field in TIC */ 376bf215546Sopenharmony_ci address += view->pipe.u.tex.first_layer * mt->layer_stride; 377bf215546Sopenharmony_ci depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1; 378bf215546Sopenharmony_ci } 379bf215546Sopenharmony_ci tic[1] = address; 380bf215546Sopenharmony_ci tic[2] |= address >> 32; 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci switch (templ->target) { 383bf215546Sopenharmony_ci case PIPE_TEXTURE_1D: 384bf215546Sopenharmony_ci tic[2] |= G80_TIC_2_TEXTURE_TYPE_ONE_D; 385bf215546Sopenharmony_ci break; 386bf215546Sopenharmony_ci case PIPE_TEXTURE_2D: 387bf215546Sopenharmony_ci tic[2] |= G80_TIC_2_TEXTURE_TYPE_TWO_D; 388bf215546Sopenharmony_ci break; 389bf215546Sopenharmony_ci case PIPE_TEXTURE_RECT: 390bf215546Sopenharmony_ci tic[2] |= G80_TIC_2_TEXTURE_TYPE_TWO_D; 391bf215546Sopenharmony_ci break; 392bf215546Sopenharmony_ci case PIPE_TEXTURE_3D: 393bf215546Sopenharmony_ci tic[2] |= G80_TIC_2_TEXTURE_TYPE_THREE_D; 394bf215546Sopenharmony_ci break; 395bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE: 396bf215546Sopenharmony_ci depth /= 6; 397bf215546Sopenharmony_ci tic[2] |= G80_TIC_2_TEXTURE_TYPE_CUBEMAP; 398bf215546Sopenharmony_ci break; 399bf215546Sopenharmony_ci case PIPE_TEXTURE_1D_ARRAY: 400bf215546Sopenharmony_ci tic[2] |= G80_TIC_2_TEXTURE_TYPE_ONE_D_ARRAY; 401bf215546Sopenharmony_ci break; 402bf215546Sopenharmony_ci case PIPE_TEXTURE_2D_ARRAY: 403bf215546Sopenharmony_ci tic[2] |= G80_TIC_2_TEXTURE_TYPE_TWO_D_ARRAY; 404bf215546Sopenharmony_ci break; 405bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE_ARRAY: 406bf215546Sopenharmony_ci depth /= 6; 407bf215546Sopenharmony_ci tic[2] |= G80_TIC_2_TEXTURE_TYPE_CUBE_ARRAY; 408bf215546Sopenharmony_ci break; 409bf215546Sopenharmony_ci default: 410bf215546Sopenharmony_ci unreachable("unexpected/invalid texture target"); 411bf215546Sopenharmony_ci } 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci tic[3] = (flags & NV50_TEXVIEW_FILTER_MSAA8) ? 0x20000000 : 0x00300000; 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_ci if (flags & NV50_TEXVIEW_ACCESS_RESOLVE) { 416bf215546Sopenharmony_ci width = mt->base.base.width0 << mt->ms_x; 417bf215546Sopenharmony_ci height = mt->base.base.height0 << mt->ms_y; 418bf215546Sopenharmony_ci } else { 419bf215546Sopenharmony_ci width = mt->base.base.width0; 420bf215546Sopenharmony_ci height = mt->base.base.height0; 421bf215546Sopenharmony_ci } 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci tic[4] = (1 << 31) | width; 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci tic[5] = height & 0xffff; 426bf215546Sopenharmony_ci tic[5] |= depth << 16; 427bf215546Sopenharmony_ci tic[5] |= mt->base.base.last_level << 28; 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci /* sampling points: (?) */ 430bf215546Sopenharmony_ci if (flags & NV50_TEXVIEW_ACCESS_RESOLVE) 431bf215546Sopenharmony_ci tic[6] = (mt->ms_x > 1) ? 0x88000000 : 0x03000000; 432bf215546Sopenharmony_ci else 433bf215546Sopenharmony_ci tic[6] = 0x03000000; 434bf215546Sopenharmony_ci 435bf215546Sopenharmony_ci tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level; 436bf215546Sopenharmony_ci tic[7] |= mt->ms_mode << 12; 437bf215546Sopenharmony_ci 438bf215546Sopenharmony_ci return &view->pipe; 439bf215546Sopenharmony_ci} 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_cistruct pipe_sampler_view * 442bf215546Sopenharmony_cinvc0_create_texture_view(struct pipe_context *pipe, 443bf215546Sopenharmony_ci struct pipe_resource *texture, 444bf215546Sopenharmony_ci const struct pipe_sampler_view *templ, 445bf215546Sopenharmony_ci uint32_t flags) 446bf215546Sopenharmony_ci{ 447bf215546Sopenharmony_ci if (nvc0_context(pipe)->screen->tic.maxwell) 448bf215546Sopenharmony_ci return gm107_create_texture_view(pipe, texture, templ, flags); 449bf215546Sopenharmony_ci return gf100_create_texture_view(pipe, texture, templ, flags); 450bf215546Sopenharmony_ci} 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_cibool 453bf215546Sopenharmony_cinvc0_update_tic(struct nvc0_context *nvc0, struct nv50_tic_entry *tic, 454bf215546Sopenharmony_ci struct nv04_resource *res) 455bf215546Sopenharmony_ci{ 456bf215546Sopenharmony_ci uint64_t address = res->address; 457bf215546Sopenharmony_ci if (res->base.target != PIPE_BUFFER) 458bf215546Sopenharmony_ci return false; 459bf215546Sopenharmony_ci address += tic->pipe.u.buf.offset; 460bf215546Sopenharmony_ci if (tic->tic[1] == (uint32_t)address && 461bf215546Sopenharmony_ci (tic->tic[2] & 0xff) == address >> 32) 462bf215546Sopenharmony_ci return false; 463bf215546Sopenharmony_ci 464bf215546Sopenharmony_ci tic->tic[1] = address; 465bf215546Sopenharmony_ci tic->tic[2] &= 0xffffff00; 466bf215546Sopenharmony_ci tic->tic[2] |= address >> 32; 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci if (tic->id >= 0) { 469bf215546Sopenharmony_ci nvc0->base.push_data(&nvc0->base, nvc0->screen->txc, tic->id * 32, 470bf215546Sopenharmony_ci NV_VRAM_DOMAIN(&nvc0->screen->base), 32, 471bf215546Sopenharmony_ci tic->tic); 472bf215546Sopenharmony_ci return true; 473bf215546Sopenharmony_ci } 474bf215546Sopenharmony_ci 475bf215546Sopenharmony_ci return false; 476bf215546Sopenharmony_ci} 477bf215546Sopenharmony_ci 478bf215546Sopenharmony_cibool 479bf215546Sopenharmony_cinvc0_validate_tic(struct nvc0_context *nvc0, int s) 480bf215546Sopenharmony_ci{ 481bf215546Sopenharmony_ci uint32_t commands[32]; 482bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 483bf215546Sopenharmony_ci unsigned i; 484bf215546Sopenharmony_ci unsigned n = 0; 485bf215546Sopenharmony_ci bool need_flush = false; 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_ci for (i = 0; i < nvc0->num_textures[s]; ++i) { 488bf215546Sopenharmony_ci struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]); 489bf215546Sopenharmony_ci struct nv04_resource *res; 490bf215546Sopenharmony_ci const bool dirty = !!(nvc0->textures_dirty[s] & (1 << i)); 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci if (!tic) { 493bf215546Sopenharmony_ci if (dirty) 494bf215546Sopenharmony_ci commands[n++] = (i << 1) | 0; 495bf215546Sopenharmony_ci continue; 496bf215546Sopenharmony_ci } 497bf215546Sopenharmony_ci res = nv04_resource(tic->pipe.texture); 498bf215546Sopenharmony_ci need_flush |= nvc0_update_tic(nvc0, tic, res); 499bf215546Sopenharmony_ci 500bf215546Sopenharmony_ci if (tic->id < 0) { 501bf215546Sopenharmony_ci tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic); 502bf215546Sopenharmony_ci 503bf215546Sopenharmony_ci nvc0->base.push_data(&nvc0->base, nvc0->screen->txc, tic->id * 32, 504bf215546Sopenharmony_ci NV_VRAM_DOMAIN(&nvc0->screen->base), 32, 505bf215546Sopenharmony_ci tic->tic); 506bf215546Sopenharmony_ci need_flush = true; 507bf215546Sopenharmony_ci } else 508bf215546Sopenharmony_ci if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) { 509bf215546Sopenharmony_ci if (unlikely(s == 5)) 510bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_CP(TEX_CACHE_CTL), 1); 511bf215546Sopenharmony_ci else 512bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1); 513bf215546Sopenharmony_ci PUSH_DATA (push, (tic->id << 4) | 1); 514bf215546Sopenharmony_ci NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_cache_flush_count, 1); 515bf215546Sopenharmony_ci } 516bf215546Sopenharmony_ci nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32); 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_ci res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; 519bf215546Sopenharmony_ci res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; 520bf215546Sopenharmony_ci 521bf215546Sopenharmony_ci if (!dirty) 522bf215546Sopenharmony_ci continue; 523bf215546Sopenharmony_ci commands[n++] = (tic->id << 9) | (i << 1) | 1; 524bf215546Sopenharmony_ci 525bf215546Sopenharmony_ci if (unlikely(s == 5)) 526bf215546Sopenharmony_ci BCTX_REFN(nvc0->bufctx_cp, CP_TEX(i), res, RD); 527bf215546Sopenharmony_ci else 528bf215546Sopenharmony_ci BCTX_REFN(nvc0->bufctx_3d, 3D_TEX(s, i), res, RD); 529bf215546Sopenharmony_ci } 530bf215546Sopenharmony_ci for (; i < nvc0->state.num_textures[s]; ++i) 531bf215546Sopenharmony_ci commands[n++] = (i << 1) | 0; 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_ci nvc0->state.num_textures[s] = nvc0->num_textures[s]; 534bf215546Sopenharmony_ci 535bf215546Sopenharmony_ci if (n) { 536bf215546Sopenharmony_ci if (unlikely(s == 5)) 537bf215546Sopenharmony_ci BEGIN_NIC0(push, NVC0_CP(BIND_TIC), n); 538bf215546Sopenharmony_ci else 539bf215546Sopenharmony_ci BEGIN_NIC0(push, NVC0_3D(BIND_TIC(s)), n); 540bf215546Sopenharmony_ci PUSH_DATAp(push, commands, n); 541bf215546Sopenharmony_ci } 542bf215546Sopenharmony_ci nvc0->textures_dirty[s] = 0; 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_ci return need_flush; 545bf215546Sopenharmony_ci} 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_cistatic bool 548bf215546Sopenharmony_cinve4_validate_tic(struct nvc0_context *nvc0, unsigned s) 549bf215546Sopenharmony_ci{ 550bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 551bf215546Sopenharmony_ci unsigned i; 552bf215546Sopenharmony_ci bool need_flush = false; 553bf215546Sopenharmony_ci 554bf215546Sopenharmony_ci for (i = 0; i < nvc0->num_textures[s]; ++i) { 555bf215546Sopenharmony_ci struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]); 556bf215546Sopenharmony_ci struct nv04_resource *res; 557bf215546Sopenharmony_ci const bool dirty = !!(nvc0->textures_dirty[s] & (1 << i)); 558bf215546Sopenharmony_ci 559bf215546Sopenharmony_ci if (!tic) { 560bf215546Sopenharmony_ci nvc0->tex_handles[s][i] |= NVE4_TIC_ENTRY_INVALID; 561bf215546Sopenharmony_ci continue; 562bf215546Sopenharmony_ci } 563bf215546Sopenharmony_ci res = nv04_resource(tic->pipe.texture); 564bf215546Sopenharmony_ci need_flush |= nvc0_update_tic(nvc0, tic, res); 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_ci if (tic->id < 0) { 567bf215546Sopenharmony_ci tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic); 568bf215546Sopenharmony_ci 569bf215546Sopenharmony_ci nvc0->base.push_data(&nvc0->base, nvc0->screen->txc, tic->id * 32, 570bf215546Sopenharmony_ci NV_VRAM_DOMAIN(&nvc0->screen->base), 32, 571bf215546Sopenharmony_ci tic->tic); 572bf215546Sopenharmony_ci need_flush = true; 573bf215546Sopenharmony_ci } else 574bf215546Sopenharmony_ci if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) { 575bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1); 576bf215546Sopenharmony_ci PUSH_DATA (push, (tic->id << 4) | 1); 577bf215546Sopenharmony_ci } 578bf215546Sopenharmony_ci nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32); 579bf215546Sopenharmony_ci 580bf215546Sopenharmony_ci res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; 581bf215546Sopenharmony_ci res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; 582bf215546Sopenharmony_ci 583bf215546Sopenharmony_ci nvc0->tex_handles[s][i] &= ~NVE4_TIC_ENTRY_INVALID; 584bf215546Sopenharmony_ci nvc0->tex_handles[s][i] |= tic->id; 585bf215546Sopenharmony_ci if (dirty) 586bf215546Sopenharmony_ci BCTX_REFN(nvc0->bufctx_3d, 3D_TEX(s, i), res, RD); 587bf215546Sopenharmony_ci } 588bf215546Sopenharmony_ci for (; i < nvc0->state.num_textures[s]; ++i) { 589bf215546Sopenharmony_ci nvc0->tex_handles[s][i] |= NVE4_TIC_ENTRY_INVALID; 590bf215546Sopenharmony_ci nvc0->textures_dirty[s] |= 1 << i; 591bf215546Sopenharmony_ci } 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_ci nvc0->state.num_textures[s] = nvc0->num_textures[s]; 594bf215546Sopenharmony_ci 595bf215546Sopenharmony_ci return need_flush; 596bf215546Sopenharmony_ci} 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_civoid nvc0_validate_textures(struct nvc0_context *nvc0) 599bf215546Sopenharmony_ci{ 600bf215546Sopenharmony_ci bool need_flush = false; 601bf215546Sopenharmony_ci int i; 602bf215546Sopenharmony_ci 603bf215546Sopenharmony_ci for (i = 0; i < 5; i++) { 604bf215546Sopenharmony_ci if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) 605bf215546Sopenharmony_ci need_flush |= nve4_validate_tic(nvc0, i); 606bf215546Sopenharmony_ci else 607bf215546Sopenharmony_ci need_flush |= nvc0_validate_tic(nvc0, i); 608bf215546Sopenharmony_ci } 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci if (need_flush) { 611bf215546Sopenharmony_ci BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TIC_FLUSH), 1); 612bf215546Sopenharmony_ci PUSH_DATA (nvc0->base.pushbuf, 0); 613bf215546Sopenharmony_ci } 614bf215546Sopenharmony_ci 615bf215546Sopenharmony_ci /* Invalidate all CP textures because they are aliased. */ 616bf215546Sopenharmony_ci for (int i = 0; i < nvc0->num_textures[5]; i++) 617bf215546Sopenharmony_ci nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_TEX(i)); 618bf215546Sopenharmony_ci nvc0->textures_dirty[5] = ~0; 619bf215546Sopenharmony_ci nvc0->dirty_cp |= NVC0_NEW_CP_TEXTURES; 620bf215546Sopenharmony_ci} 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_cibool 623bf215546Sopenharmony_cinvc0_validate_tsc(struct nvc0_context *nvc0, int s) 624bf215546Sopenharmony_ci{ 625bf215546Sopenharmony_ci uint32_t commands[16]; 626bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 627bf215546Sopenharmony_ci unsigned i; 628bf215546Sopenharmony_ci unsigned n = 0; 629bf215546Sopenharmony_ci bool need_flush = false; 630bf215546Sopenharmony_ci 631bf215546Sopenharmony_ci for (i = 0; i < nvc0->num_samplers[s]; ++i) { 632bf215546Sopenharmony_ci struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]); 633bf215546Sopenharmony_ci 634bf215546Sopenharmony_ci if (!(nvc0->samplers_dirty[s] & (1 << i))) 635bf215546Sopenharmony_ci continue; 636bf215546Sopenharmony_ci if (!tsc) { 637bf215546Sopenharmony_ci commands[n++] = (i << 4) | 0; 638bf215546Sopenharmony_ci continue; 639bf215546Sopenharmony_ci } 640bf215546Sopenharmony_ci nvc0->seamless_cube_map = tsc->seamless_cube_map; 641bf215546Sopenharmony_ci if (tsc->id < 0) { 642bf215546Sopenharmony_ci tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc); 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_ci nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->txc, 645bf215546Sopenharmony_ci 65536 + tsc->id * 32, NV_VRAM_DOMAIN(&nvc0->screen->base), 646bf215546Sopenharmony_ci 32, tsc->tsc); 647bf215546Sopenharmony_ci need_flush = true; 648bf215546Sopenharmony_ci } 649bf215546Sopenharmony_ci nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32); 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ci commands[n++] = (tsc->id << 12) | (i << 4) | 1; 652bf215546Sopenharmony_ci } 653bf215546Sopenharmony_ci for (; i < nvc0->state.num_samplers[s]; ++i) 654bf215546Sopenharmony_ci commands[n++] = (i << 4) | 0; 655bf215546Sopenharmony_ci 656bf215546Sopenharmony_ci nvc0->state.num_samplers[s] = nvc0->num_samplers[s]; 657bf215546Sopenharmony_ci 658bf215546Sopenharmony_ci // TXF, in unlinked tsc mode, will always use sampler 0. So we have to 659bf215546Sopenharmony_ci // ensure that it remains bound. Its contents don't matter, all samplers we 660bf215546Sopenharmony_ci // ever create have the SRGB_CONVERSION bit set, so as long as the first 661bf215546Sopenharmony_ci // entry is initialized, we're good to go. This is the only bit that has 662bf215546Sopenharmony_ci // any effect on what TXF does. 663bf215546Sopenharmony_ci if ((nvc0->samplers_dirty[s] & 1) && !nvc0->samplers[s][0]) { 664bf215546Sopenharmony_ci if (n == 0) 665bf215546Sopenharmony_ci n = 1; 666bf215546Sopenharmony_ci // We're guaranteed that the first command refers to the first slot, so 667bf215546Sopenharmony_ci // we're not overwriting a valid entry. 668bf215546Sopenharmony_ci commands[0] = (0 << 12) | (0 << 4) | 1; 669bf215546Sopenharmony_ci } 670bf215546Sopenharmony_ci 671bf215546Sopenharmony_ci if (n) { 672bf215546Sopenharmony_ci if (unlikely(s == 5)) 673bf215546Sopenharmony_ci BEGIN_NIC0(push, NVC0_CP(BIND_TSC), n); 674bf215546Sopenharmony_ci else 675bf215546Sopenharmony_ci BEGIN_NIC0(push, NVC0_3D(BIND_TSC(s)), n); 676bf215546Sopenharmony_ci PUSH_DATAp(push, commands, n); 677bf215546Sopenharmony_ci } 678bf215546Sopenharmony_ci nvc0->samplers_dirty[s] = 0; 679bf215546Sopenharmony_ci 680bf215546Sopenharmony_ci return need_flush; 681bf215546Sopenharmony_ci} 682bf215546Sopenharmony_ci 683bf215546Sopenharmony_cibool 684bf215546Sopenharmony_cinve4_validate_tsc(struct nvc0_context *nvc0, int s) 685bf215546Sopenharmony_ci{ 686bf215546Sopenharmony_ci unsigned i; 687bf215546Sopenharmony_ci bool need_flush = false; 688bf215546Sopenharmony_ci 689bf215546Sopenharmony_ci for (i = 0; i < nvc0->num_samplers[s]; ++i) { 690bf215546Sopenharmony_ci struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]); 691bf215546Sopenharmony_ci 692bf215546Sopenharmony_ci if (!tsc) { 693bf215546Sopenharmony_ci nvc0->tex_handles[s][i] |= NVE4_TSC_ENTRY_INVALID; 694bf215546Sopenharmony_ci continue; 695bf215546Sopenharmony_ci } 696bf215546Sopenharmony_ci if (tsc->id < 0) { 697bf215546Sopenharmony_ci tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc); 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci nve4_p2mf_push_linear(&nvc0->base, nvc0->screen->txc, 700bf215546Sopenharmony_ci 65536 + tsc->id * 32, 701bf215546Sopenharmony_ci NV_VRAM_DOMAIN(&nvc0->screen->base), 702bf215546Sopenharmony_ci 32, tsc->tsc); 703bf215546Sopenharmony_ci need_flush = true; 704bf215546Sopenharmony_ci } 705bf215546Sopenharmony_ci nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32); 706bf215546Sopenharmony_ci 707bf215546Sopenharmony_ci nvc0->tex_handles[s][i] &= ~NVE4_TSC_ENTRY_INVALID; 708bf215546Sopenharmony_ci nvc0->tex_handles[s][i] |= tsc->id << 20; 709bf215546Sopenharmony_ci } 710bf215546Sopenharmony_ci for (; i < nvc0->state.num_samplers[s]; ++i) { 711bf215546Sopenharmony_ci nvc0->tex_handles[s][i] |= NVE4_TSC_ENTRY_INVALID; 712bf215546Sopenharmony_ci nvc0->samplers_dirty[s] |= 1 << i; 713bf215546Sopenharmony_ci } 714bf215546Sopenharmony_ci 715bf215546Sopenharmony_ci nvc0->state.num_samplers[s] = nvc0->num_samplers[s]; 716bf215546Sopenharmony_ci 717bf215546Sopenharmony_ci return need_flush; 718bf215546Sopenharmony_ci} 719bf215546Sopenharmony_ci 720bf215546Sopenharmony_civoid nvc0_validate_samplers(struct nvc0_context *nvc0) 721bf215546Sopenharmony_ci{ 722bf215546Sopenharmony_ci bool need_flush = false; 723bf215546Sopenharmony_ci int i; 724bf215546Sopenharmony_ci 725bf215546Sopenharmony_ci for (i = 0; i < 5; i++) { 726bf215546Sopenharmony_ci if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) 727bf215546Sopenharmony_ci need_flush |= nve4_validate_tsc(nvc0, i); 728bf215546Sopenharmony_ci else 729bf215546Sopenharmony_ci need_flush |= nvc0_validate_tsc(nvc0, i); 730bf215546Sopenharmony_ci } 731bf215546Sopenharmony_ci 732bf215546Sopenharmony_ci if (need_flush) { 733bf215546Sopenharmony_ci BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TSC_FLUSH), 1); 734bf215546Sopenharmony_ci PUSH_DATA (nvc0->base.pushbuf, 0); 735bf215546Sopenharmony_ci } 736bf215546Sopenharmony_ci 737bf215546Sopenharmony_ci /* Invalidate all CP samplers because they are aliased. */ 738bf215546Sopenharmony_ci nvc0->samplers_dirty[5] = ~0; 739bf215546Sopenharmony_ci nvc0->dirty_cp |= NVC0_NEW_CP_SAMPLERS; 740bf215546Sopenharmony_ci} 741bf215546Sopenharmony_ci 742bf215546Sopenharmony_civoid 743bf215546Sopenharmony_cinvc0_upload_tsc0(struct nvc0_context *nvc0) 744bf215546Sopenharmony_ci{ 745bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 746bf215546Sopenharmony_ci u32 data[8] = { G80_TSC_0_SRGB_CONVERSION }; 747bf215546Sopenharmony_ci nvc0->base.push_data(&nvc0->base, nvc0->screen->txc, 748bf215546Sopenharmony_ci 65536 /*+ tsc->id * 32*/, 749bf215546Sopenharmony_ci NV_VRAM_DOMAIN(&nvc0->screen->base), 32, data); 750bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(TSC_FLUSH), 1); 751bf215546Sopenharmony_ci PUSH_DATA (push, 0); 752bf215546Sopenharmony_ci} 753bf215546Sopenharmony_ci 754bf215546Sopenharmony_ci/* Upload the "diagonal" entries for the possible texture sources ($t == $s). 755bf215546Sopenharmony_ci * At some point we might want to get a list of the combinations used by a 756bf215546Sopenharmony_ci * shader and fill in those entries instead of having it extract the handles. 757bf215546Sopenharmony_ci */ 758bf215546Sopenharmony_civoid 759bf215546Sopenharmony_cinve4_set_tex_handles(struct nvc0_context *nvc0) 760bf215546Sopenharmony_ci{ 761bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 762bf215546Sopenharmony_ci struct nvc0_screen *screen = nvc0->screen; 763bf215546Sopenharmony_ci unsigned s; 764bf215546Sopenharmony_ci 765bf215546Sopenharmony_ci if (nvc0->screen->base.class_3d < NVE4_3D_CLASS) 766bf215546Sopenharmony_ci return; 767bf215546Sopenharmony_ci 768bf215546Sopenharmony_ci for (s = 0; s < 5; ++s) { 769bf215546Sopenharmony_ci uint32_t dirty = nvc0->textures_dirty[s] | nvc0->samplers_dirty[s]; 770bf215546Sopenharmony_ci if (!dirty) 771bf215546Sopenharmony_ci continue; 772bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); 773bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_CB_AUX_SIZE); 774bf215546Sopenharmony_ci PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s)); 775bf215546Sopenharmony_ci PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s)); 776bf215546Sopenharmony_ci do { 777bf215546Sopenharmony_ci int i = ffs(dirty) - 1; 778bf215546Sopenharmony_ci dirty &= ~(1 << i); 779bf215546Sopenharmony_ci 780bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CB_POS), 2); 781bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_CB_AUX_TEX_INFO(i)); 782bf215546Sopenharmony_ci PUSH_DATA (push, nvc0->tex_handles[s][i]); 783bf215546Sopenharmony_ci } while (dirty); 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci nvc0->textures_dirty[s] = 0; 786bf215546Sopenharmony_ci nvc0->samplers_dirty[s] = 0; 787bf215546Sopenharmony_ci } 788bf215546Sopenharmony_ci} 789bf215546Sopenharmony_ci 790bf215546Sopenharmony_cistatic uint64_t 791bf215546Sopenharmony_cinve4_create_texture_handle(struct pipe_context *pipe, 792bf215546Sopenharmony_ci struct pipe_sampler_view *view, 793bf215546Sopenharmony_ci const struct pipe_sampler_state *sampler) 794bf215546Sopenharmony_ci{ 795bf215546Sopenharmony_ci /* We have to create persistent handles that won't change for these objects 796bf215546Sopenharmony_ci * That means that we have to upload them into place and lock them so that 797bf215546Sopenharmony_ci * they can't be kicked out later. 798bf215546Sopenharmony_ci */ 799bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 800bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 801bf215546Sopenharmony_ci struct nv50_tic_entry *tic = nv50_tic_entry(view); 802bf215546Sopenharmony_ci struct nv50_tsc_entry *tsc = pipe->create_sampler_state(pipe, sampler); 803bf215546Sopenharmony_ci struct pipe_sampler_view *v = NULL; 804bf215546Sopenharmony_ci 805bf215546Sopenharmony_ci tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc); 806bf215546Sopenharmony_ci if (tsc->id < 0) 807bf215546Sopenharmony_ci goto fail; 808bf215546Sopenharmony_ci 809bf215546Sopenharmony_ci if (tic->id < 0) { 810bf215546Sopenharmony_ci tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic); 811bf215546Sopenharmony_ci if (tic->id < 0) 812bf215546Sopenharmony_ci goto fail; 813bf215546Sopenharmony_ci 814bf215546Sopenharmony_ci nve4_p2mf_push_linear(&nvc0->base, nvc0->screen->txc, tic->id * 32, 815bf215546Sopenharmony_ci NV_VRAM_DOMAIN(&nvc0->screen->base), 32, 816bf215546Sopenharmony_ci tic->tic); 817bf215546Sopenharmony_ci 818bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(TIC_FLUSH), 0); 819bf215546Sopenharmony_ci } 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci nve4_p2mf_push_linear(&nvc0->base, nvc0->screen->txc, 822bf215546Sopenharmony_ci 65536 + tsc->id * 32, 823bf215546Sopenharmony_ci NV_VRAM_DOMAIN(&nvc0->screen->base), 824bf215546Sopenharmony_ci 32, tsc->tsc); 825bf215546Sopenharmony_ci 826bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(TSC_FLUSH), 0); 827bf215546Sopenharmony_ci 828bf215546Sopenharmony_ci // Add an extra reference to this sampler view effectively held by this 829bf215546Sopenharmony_ci // texture handle. This is to deal with the sampler view being dereferenced 830bf215546Sopenharmony_ci // before the handle is. However we need the view to still be live until the 831bf215546Sopenharmony_ci // handle to it is deleted. 832bf215546Sopenharmony_ci pipe_sampler_view_reference(&v, view); 833bf215546Sopenharmony_ci p_atomic_inc(&tic->bindless); 834bf215546Sopenharmony_ci 835bf215546Sopenharmony_ci nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32); 836bf215546Sopenharmony_ci nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32); 837bf215546Sopenharmony_ci 838bf215546Sopenharmony_ci return 0x100000000ULL | (tsc->id << 20) | tic->id; 839bf215546Sopenharmony_ci 840bf215546Sopenharmony_cifail: 841bf215546Sopenharmony_ci pipe->delete_sampler_state(pipe, tsc); 842bf215546Sopenharmony_ci return 0; 843bf215546Sopenharmony_ci} 844bf215546Sopenharmony_ci 845bf215546Sopenharmony_cistatic bool 846bf215546Sopenharmony_ciview_bound(struct nvc0_context *nvc0, struct pipe_sampler_view *view) { 847bf215546Sopenharmony_ci for (int s = 0; s < 6; s++) { 848bf215546Sopenharmony_ci for (int i = 0; i < nvc0->num_textures[s]; i++) 849bf215546Sopenharmony_ci if (nvc0->textures[s][i] == view) 850bf215546Sopenharmony_ci return true; 851bf215546Sopenharmony_ci } 852bf215546Sopenharmony_ci return false; 853bf215546Sopenharmony_ci} 854bf215546Sopenharmony_ci 855bf215546Sopenharmony_cistatic void 856bf215546Sopenharmony_cinve4_delete_texture_handle(struct pipe_context *pipe, uint64_t handle) 857bf215546Sopenharmony_ci{ 858bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 859bf215546Sopenharmony_ci uint32_t tic = handle & NVE4_TIC_ENTRY_INVALID; 860bf215546Sopenharmony_ci uint32_t tsc = (handle & NVE4_TSC_ENTRY_INVALID) >> 20; 861bf215546Sopenharmony_ci struct nv50_tic_entry *entry = nvc0->screen->tic.entries[tic]; 862bf215546Sopenharmony_ci 863bf215546Sopenharmony_ci if (entry) { 864bf215546Sopenharmony_ci struct pipe_sampler_view *view = &entry->pipe; 865bf215546Sopenharmony_ci assert(entry->bindless); 866bf215546Sopenharmony_ci p_atomic_dec(&entry->bindless); 867bf215546Sopenharmony_ci if (!view_bound(nvc0, view)) 868bf215546Sopenharmony_ci nvc0_screen_tic_unlock(nvc0->screen, entry); 869bf215546Sopenharmony_ci pipe_sampler_view_reference(&view, NULL); 870bf215546Sopenharmony_ci } 871bf215546Sopenharmony_ci 872bf215546Sopenharmony_ci pipe->delete_sampler_state(pipe, nvc0->screen->tsc.entries[tsc]); 873bf215546Sopenharmony_ci} 874bf215546Sopenharmony_ci 875bf215546Sopenharmony_cistatic void 876bf215546Sopenharmony_cinve4_make_texture_handle_resident(struct pipe_context *pipe, 877bf215546Sopenharmony_ci uint64_t handle, bool resident) 878bf215546Sopenharmony_ci{ 879bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 880bf215546Sopenharmony_ci if (resident) { 881bf215546Sopenharmony_ci struct nvc0_resident *res = calloc(1, sizeof(struct nvc0_resident)); 882bf215546Sopenharmony_ci struct nv50_tic_entry *tic = 883bf215546Sopenharmony_ci nvc0->screen->tic.entries[handle & NVE4_TIC_ENTRY_INVALID]; 884bf215546Sopenharmony_ci assert(tic); 885bf215546Sopenharmony_ci assert(tic->bindless); 886bf215546Sopenharmony_ci 887bf215546Sopenharmony_ci res->handle = handle; 888bf215546Sopenharmony_ci res->buf = nv04_resource(tic->pipe.texture); 889bf215546Sopenharmony_ci res->flags = NOUVEAU_BO_RD; 890bf215546Sopenharmony_ci list_add(&res->list, &nvc0->tex_head); 891bf215546Sopenharmony_ci } else { 892bf215546Sopenharmony_ci list_for_each_entry_safe(struct nvc0_resident, pos, &nvc0->tex_head, list) { 893bf215546Sopenharmony_ci if (pos->handle == handle) { 894bf215546Sopenharmony_ci list_del(&pos->list); 895bf215546Sopenharmony_ci free(pos); 896bf215546Sopenharmony_ci break; 897bf215546Sopenharmony_ci } 898bf215546Sopenharmony_ci } 899bf215546Sopenharmony_ci } 900bf215546Sopenharmony_ci} 901bf215546Sopenharmony_ci 902bf215546Sopenharmony_cistatic const uint8_t nve4_su_format_map[PIPE_FORMAT_COUNT]; 903bf215546Sopenharmony_cistatic const uint16_t nve4_su_format_aux_map[PIPE_FORMAT_COUNT]; 904bf215546Sopenharmony_cistatic const uint16_t nve4_suldp_lib_offset[PIPE_FORMAT_COUNT]; 905bf215546Sopenharmony_ci 906bf215546Sopenharmony_cistatic void 907bf215546Sopenharmony_cinvc0_get_surface_dims(const struct pipe_image_view *view, 908bf215546Sopenharmony_ci int *width, int *height, int *depth) 909bf215546Sopenharmony_ci{ 910bf215546Sopenharmony_ci struct nv04_resource *res = nv04_resource(view->resource); 911bf215546Sopenharmony_ci int level; 912bf215546Sopenharmony_ci 913bf215546Sopenharmony_ci *width = *height = *depth = 1; 914bf215546Sopenharmony_ci if (res->base.target == PIPE_BUFFER) { 915bf215546Sopenharmony_ci *width = view->u.buf.size / util_format_get_blocksize(view->format); 916bf215546Sopenharmony_ci return; 917bf215546Sopenharmony_ci } 918bf215546Sopenharmony_ci 919bf215546Sopenharmony_ci level = view->u.tex.level; 920bf215546Sopenharmony_ci *width = u_minify(view->resource->width0, level); 921bf215546Sopenharmony_ci *height = u_minify(view->resource->height0, level); 922bf215546Sopenharmony_ci *depth = u_minify(view->resource->depth0, level); 923bf215546Sopenharmony_ci 924bf215546Sopenharmony_ci switch (res->base.target) { 925bf215546Sopenharmony_ci case PIPE_TEXTURE_1D_ARRAY: 926bf215546Sopenharmony_ci case PIPE_TEXTURE_2D_ARRAY: 927bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE: 928bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE_ARRAY: 929bf215546Sopenharmony_ci *depth = view->u.tex.last_layer - view->u.tex.first_layer + 1; 930bf215546Sopenharmony_ci break; 931bf215546Sopenharmony_ci case PIPE_TEXTURE_1D: 932bf215546Sopenharmony_ci case PIPE_TEXTURE_2D: 933bf215546Sopenharmony_ci case PIPE_TEXTURE_RECT: 934bf215546Sopenharmony_ci case PIPE_TEXTURE_3D: 935bf215546Sopenharmony_ci break; 936bf215546Sopenharmony_ci default: 937bf215546Sopenharmony_ci assert(!"unexpected texture target"); 938bf215546Sopenharmony_ci break; 939bf215546Sopenharmony_ci } 940bf215546Sopenharmony_ci} 941bf215546Sopenharmony_ci 942bf215546Sopenharmony_civoid 943bf215546Sopenharmony_cinvc0_mark_image_range_valid(const struct pipe_image_view *view) 944bf215546Sopenharmony_ci{ 945bf215546Sopenharmony_ci struct nv04_resource *res = (struct nv04_resource *)view->resource; 946bf215546Sopenharmony_ci 947bf215546Sopenharmony_ci assert(view->resource->target == PIPE_BUFFER); 948bf215546Sopenharmony_ci 949bf215546Sopenharmony_ci util_range_add(&res->base, &res->valid_buffer_range, 950bf215546Sopenharmony_ci view->u.buf.offset, 951bf215546Sopenharmony_ci view->u.buf.offset + view->u.buf.size); 952bf215546Sopenharmony_ci} 953bf215546Sopenharmony_ci 954bf215546Sopenharmony_civoid 955bf215546Sopenharmony_cinve4_set_surface_info(struct nouveau_pushbuf *push, 956bf215546Sopenharmony_ci const struct pipe_image_view *view, 957bf215546Sopenharmony_ci struct nvc0_context *nvc0) 958bf215546Sopenharmony_ci{ 959bf215546Sopenharmony_ci struct nvc0_screen *screen = nvc0->screen; 960bf215546Sopenharmony_ci struct nv04_resource *res; 961bf215546Sopenharmony_ci uint64_t address; 962bf215546Sopenharmony_ci uint32_t *const info = push->cur; 963bf215546Sopenharmony_ci int width, height, depth; 964bf215546Sopenharmony_ci uint8_t log2cpp; 965bf215546Sopenharmony_ci 966bf215546Sopenharmony_ci if (view && !nve4_su_format_map[view->format]) 967bf215546Sopenharmony_ci NOUVEAU_ERR("unsupported surface format, try is_format_supported() !\n"); 968bf215546Sopenharmony_ci 969bf215546Sopenharmony_ci push->cur += 16; 970bf215546Sopenharmony_ci 971bf215546Sopenharmony_ci if (!view || !nve4_su_format_map[view->format]) { 972bf215546Sopenharmony_ci memset(info, 0, 16 * sizeof(*info)); 973bf215546Sopenharmony_ci 974bf215546Sopenharmony_ci info[0] = 0xbadf0000; 975bf215546Sopenharmony_ci info[1] = 0x80004000; 976bf215546Sopenharmony_ci info[12] = nve4_suldp_lib_offset[PIPE_FORMAT_R32G32B32A32_UINT] + 977bf215546Sopenharmony_ci screen->lib_code->start; 978bf215546Sopenharmony_ci return; 979bf215546Sopenharmony_ci } 980bf215546Sopenharmony_ci res = nv04_resource(view->resource); 981bf215546Sopenharmony_ci 982bf215546Sopenharmony_ci address = res->address; 983bf215546Sopenharmony_ci 984bf215546Sopenharmony_ci /* get surface dimensions based on the target. */ 985bf215546Sopenharmony_ci nvc0_get_surface_dims(view, &width, &height, &depth); 986bf215546Sopenharmony_ci 987bf215546Sopenharmony_ci info[8] = width; 988bf215546Sopenharmony_ci info[9] = height; 989bf215546Sopenharmony_ci info[10] = depth; 990bf215546Sopenharmony_ci switch (res->base.target) { 991bf215546Sopenharmony_ci case PIPE_TEXTURE_1D_ARRAY: 992bf215546Sopenharmony_ci info[11] = 1; 993bf215546Sopenharmony_ci break; 994bf215546Sopenharmony_ci case PIPE_TEXTURE_2D: 995bf215546Sopenharmony_ci case PIPE_TEXTURE_RECT: 996bf215546Sopenharmony_ci info[11] = 2; 997bf215546Sopenharmony_ci break; 998bf215546Sopenharmony_ci case PIPE_TEXTURE_3D: 999bf215546Sopenharmony_ci info[11] = 3; 1000bf215546Sopenharmony_ci break; 1001bf215546Sopenharmony_ci case PIPE_TEXTURE_2D_ARRAY: 1002bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE: 1003bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE_ARRAY: 1004bf215546Sopenharmony_ci info[11] = 4; 1005bf215546Sopenharmony_ci break; 1006bf215546Sopenharmony_ci default: 1007bf215546Sopenharmony_ci info[11] = 0; 1008bf215546Sopenharmony_ci break; 1009bf215546Sopenharmony_ci } 1010bf215546Sopenharmony_ci log2cpp = (0xf000 & nve4_su_format_aux_map[view->format]) >> 12; 1011bf215546Sopenharmony_ci 1012bf215546Sopenharmony_ci /* Stick the blockwidth (ie. number of bytes per pixel) to check if the 1013bf215546Sopenharmony_ci * format doesn't mismatch. */ 1014bf215546Sopenharmony_ci info[12] = util_format_get_blocksize(view->format); 1015bf215546Sopenharmony_ci 1016bf215546Sopenharmony_ci /* limit in bytes for raw access */ 1017bf215546Sopenharmony_ci info[13] = (0x06 << 22) | ((width << log2cpp) - 1); 1018bf215546Sopenharmony_ci 1019bf215546Sopenharmony_ci info[1] = nve4_su_format_map[view->format]; 1020bf215546Sopenharmony_ci 1021bf215546Sopenharmony_ci#if 0 1022bf215546Sopenharmony_ci switch (util_format_get_blocksizebits(view->format)) { 1023bf215546Sopenharmony_ci case 16: info[1] |= 1 << 16; break; 1024bf215546Sopenharmony_ci case 32: info[1] |= 2 << 16; break; 1025bf215546Sopenharmony_ci case 64: info[1] |= 3 << 16; break; 1026bf215546Sopenharmony_ci case 128: info[1] |= 4 << 16; break; 1027bf215546Sopenharmony_ci default: 1028bf215546Sopenharmony_ci break; 1029bf215546Sopenharmony_ci } 1030bf215546Sopenharmony_ci#else 1031bf215546Sopenharmony_ci info[1] |= log2cpp << 16; 1032bf215546Sopenharmony_ci info[1] |= 0x4000; 1033bf215546Sopenharmony_ci info[1] |= (0x0f00 & nve4_su_format_aux_map[view->format]); 1034bf215546Sopenharmony_ci#endif 1035bf215546Sopenharmony_ci 1036bf215546Sopenharmony_ci if (res->base.target == PIPE_BUFFER) { 1037bf215546Sopenharmony_ci address += view->u.buf.offset; 1038bf215546Sopenharmony_ci 1039bf215546Sopenharmony_ci info[0] = address >> 8; 1040bf215546Sopenharmony_ci info[2] = width - 1; 1041bf215546Sopenharmony_ci info[2] |= (0xff & nve4_su_format_aux_map[view->format]) << 22; 1042bf215546Sopenharmony_ci info[3] = 0; 1043bf215546Sopenharmony_ci info[4] = 0; 1044bf215546Sopenharmony_ci info[5] = 0; 1045bf215546Sopenharmony_ci info[6] = 0; 1046bf215546Sopenharmony_ci info[7] = 0; 1047bf215546Sopenharmony_ci info[14] = 0; 1048bf215546Sopenharmony_ci info[15] = 0; 1049bf215546Sopenharmony_ci } else { 1050bf215546Sopenharmony_ci struct nv50_miptree *mt = nv50_miptree(&res->base); 1051bf215546Sopenharmony_ci struct nv50_miptree_level *lvl = &mt->level[view->u.tex.level]; 1052bf215546Sopenharmony_ci unsigned z = view->u.tex.first_layer; 1053bf215546Sopenharmony_ci 1054bf215546Sopenharmony_ci if (!mt->layout_3d) { 1055bf215546Sopenharmony_ci address += mt->layer_stride * z; 1056bf215546Sopenharmony_ci z = 0; 1057bf215546Sopenharmony_ci } 1058bf215546Sopenharmony_ci 1059bf215546Sopenharmony_ci address += lvl->offset; 1060bf215546Sopenharmony_ci 1061bf215546Sopenharmony_ci info[0] = address >> 8; 1062bf215546Sopenharmony_ci info[2] = (width << mt->ms_x) - 1; 1063bf215546Sopenharmony_ci /* NOTE: this is really important: */ 1064bf215546Sopenharmony_ci info[2] |= (0xff & nve4_su_format_aux_map[view->format]) << 22; 1065bf215546Sopenharmony_ci info[3] = (0x88 << 24) | (lvl->pitch / 64); 1066bf215546Sopenharmony_ci info[4] = (height << mt->ms_y) - 1; 1067bf215546Sopenharmony_ci info[4] |= (lvl->tile_mode & 0x0f0) << 25; 1068bf215546Sopenharmony_ci info[4] |= NVC0_TILE_SHIFT_Y(lvl->tile_mode) << 22; 1069bf215546Sopenharmony_ci info[5] = mt->layer_stride >> 8; 1070bf215546Sopenharmony_ci info[6] = depth - 1; 1071bf215546Sopenharmony_ci info[6] |= (lvl->tile_mode & 0xf00) << 21; 1072bf215546Sopenharmony_ci info[6] |= NVC0_TILE_SHIFT_Z(lvl->tile_mode) << 22; 1073bf215546Sopenharmony_ci info[7] = mt->layout_3d ? 1 : 0; 1074bf215546Sopenharmony_ci info[7] |= z << 16; 1075bf215546Sopenharmony_ci info[14] = mt->ms_x; 1076bf215546Sopenharmony_ci info[15] = mt->ms_y; 1077bf215546Sopenharmony_ci } 1078bf215546Sopenharmony_ci} 1079bf215546Sopenharmony_ci 1080bf215546Sopenharmony_cistatic inline void 1081bf215546Sopenharmony_cinvc0_set_surface_info(struct nouveau_pushbuf *push, 1082bf215546Sopenharmony_ci const struct pipe_image_view *view, uint64_t address, 1083bf215546Sopenharmony_ci int width, int height, int depth) 1084bf215546Sopenharmony_ci{ 1085bf215546Sopenharmony_ci struct nv04_resource *res; 1086bf215546Sopenharmony_ci uint32_t *const info = push->cur; 1087bf215546Sopenharmony_ci 1088bf215546Sopenharmony_ci push->cur += 16; 1089bf215546Sopenharmony_ci 1090bf215546Sopenharmony_ci /* Make sure to always initialize the surface information area because it's 1091bf215546Sopenharmony_ci * used to check if the given image is bound or not. */ 1092bf215546Sopenharmony_ci memset(info, 0, 16 * sizeof(*info)); 1093bf215546Sopenharmony_ci 1094bf215546Sopenharmony_ci if (!view || !view->resource) 1095bf215546Sopenharmony_ci return; 1096bf215546Sopenharmony_ci res = nv04_resource(view->resource); 1097bf215546Sopenharmony_ci 1098bf215546Sopenharmony_ci /* Stick the image dimensions for the imageSize() builtin. */ 1099bf215546Sopenharmony_ci info[8] = width; 1100bf215546Sopenharmony_ci info[9] = height; 1101bf215546Sopenharmony_ci info[10] = depth; 1102bf215546Sopenharmony_ci 1103bf215546Sopenharmony_ci /* Stick the blockwidth (ie. number of bytes per pixel) to calculate pixel 1104bf215546Sopenharmony_ci * offset and to check if the format doesn't mismatch. */ 1105bf215546Sopenharmony_ci info[12] = ffs(util_format_get_blocksize(view->format)) - 1; 1106bf215546Sopenharmony_ci 1107bf215546Sopenharmony_ci if (res->base.target == PIPE_BUFFER) { 1108bf215546Sopenharmony_ci info[0] = address >> 8; 1109bf215546Sopenharmony_ci info[2] = width; 1110bf215546Sopenharmony_ci } else { 1111bf215546Sopenharmony_ci struct nv50_miptree *mt = nv50_miptree(&res->base); 1112bf215546Sopenharmony_ci struct nv50_miptree_level *lvl = &mt->level[view->u.tex.level]; 1113bf215546Sopenharmony_ci unsigned z = mt->layout_3d ? view->u.tex.first_layer : 0; 1114bf215546Sopenharmony_ci unsigned nby = align(util_format_get_nblocksy(view->format, height), 1115bf215546Sopenharmony_ci NVC0_TILE_SIZE_Y(lvl->tile_mode)); 1116bf215546Sopenharmony_ci 1117bf215546Sopenharmony_ci /* NOTE: this does not precisely match nve4; the values are made to be 1118bf215546Sopenharmony_ci * easier for the shader to consume. 1119bf215546Sopenharmony_ci */ 1120bf215546Sopenharmony_ci info[0] = address >> 8; 1121bf215546Sopenharmony_ci info[2] = (NVC0_TILE_SHIFT_X(lvl->tile_mode) - info[12]) << 24; 1122bf215546Sopenharmony_ci info[4] = NVC0_TILE_SHIFT_Y(lvl->tile_mode) << 24 | nby; 1123bf215546Sopenharmony_ci info[5] = mt->layer_stride >> 8; 1124bf215546Sopenharmony_ci info[6] = NVC0_TILE_SHIFT_Z(lvl->tile_mode) << 24; 1125bf215546Sopenharmony_ci info[7] = z; 1126bf215546Sopenharmony_ci info[14] = mt->ms_x; 1127bf215546Sopenharmony_ci info[15] = mt->ms_y; 1128bf215546Sopenharmony_ci } 1129bf215546Sopenharmony_ci} 1130bf215546Sopenharmony_ci 1131bf215546Sopenharmony_civoid 1132bf215546Sopenharmony_cinvc0_validate_suf(struct nvc0_context *nvc0, int s) 1133bf215546Sopenharmony_ci{ 1134bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 1135bf215546Sopenharmony_ci struct nvc0_screen *screen = nvc0->screen; 1136bf215546Sopenharmony_ci 1137bf215546Sopenharmony_ci for (int i = 0; i < NVC0_MAX_IMAGES; ++i) { 1138bf215546Sopenharmony_ci struct pipe_image_view *view = &nvc0->images[s][i]; 1139bf215546Sopenharmony_ci int width = 0, height = 0, depth = 0; 1140bf215546Sopenharmony_ci uint64_t address = 0; 1141bf215546Sopenharmony_ci 1142bf215546Sopenharmony_ci if (s == 5) 1143bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_CP(IMAGE(i)), 6); 1144bf215546Sopenharmony_ci else 1145bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(IMAGE(i)), 6); 1146bf215546Sopenharmony_ci 1147bf215546Sopenharmony_ci if (view->resource) { 1148bf215546Sopenharmony_ci struct nv04_resource *res = nv04_resource(view->resource); 1149bf215546Sopenharmony_ci unsigned rt = nvc0_format_table[view->format].rt; 1150bf215546Sopenharmony_ci 1151bf215546Sopenharmony_ci if (util_format_is_depth_or_stencil(view->format)) 1152bf215546Sopenharmony_ci rt = rt << 12; 1153bf215546Sopenharmony_ci else 1154bf215546Sopenharmony_ci rt = (rt << 4) | (0x14 << 12); 1155bf215546Sopenharmony_ci 1156bf215546Sopenharmony_ci /* get surface dimensions based on the target. */ 1157bf215546Sopenharmony_ci nvc0_get_surface_dims(view, &width, &height, &depth); 1158bf215546Sopenharmony_ci 1159bf215546Sopenharmony_ci address = res->address; 1160bf215546Sopenharmony_ci if (res->base.target == PIPE_BUFFER) { 1161bf215546Sopenharmony_ci unsigned blocksize = util_format_get_blocksize(view->format); 1162bf215546Sopenharmony_ci 1163bf215546Sopenharmony_ci address += view->u.buf.offset; 1164bf215546Sopenharmony_ci assert(!(address & 0xff)); 1165bf215546Sopenharmony_ci 1166bf215546Sopenharmony_ci if (view->access & PIPE_IMAGE_ACCESS_WRITE) 1167bf215546Sopenharmony_ci nvc0_mark_image_range_valid(view); 1168bf215546Sopenharmony_ci 1169bf215546Sopenharmony_ci PUSH_DATAh(push, address); 1170bf215546Sopenharmony_ci PUSH_DATA (push, address); 1171bf215546Sopenharmony_ci PUSH_DATA (push, align(width * blocksize, 0x100)); 1172bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_3D_IMAGE_HEIGHT_LINEAR | 1); 1173bf215546Sopenharmony_ci PUSH_DATA (push, rt); 1174bf215546Sopenharmony_ci PUSH_DATA (push, 0); 1175bf215546Sopenharmony_ci } else { 1176bf215546Sopenharmony_ci struct nv50_miptree *mt = nv50_miptree(view->resource); 1177bf215546Sopenharmony_ci struct nv50_miptree_level *lvl = &mt->level[view->u.tex.level]; 1178bf215546Sopenharmony_ci unsigned adjusted_width = width, adjusted_height = height; 1179bf215546Sopenharmony_ci 1180bf215546Sopenharmony_ci if (mt->layout_3d) { 1181bf215546Sopenharmony_ci // We have to adjust the size of the 3d surface to be 1182bf215546Sopenharmony_ci // accessible within 2d limits. The size of each z tile goes 1183bf215546Sopenharmony_ci // into the x direction, while the number of z tiles goes into 1184bf215546Sopenharmony_ci // the y direction. 1185bf215546Sopenharmony_ci const unsigned nbx = util_format_get_nblocksx(view->format, width); 1186bf215546Sopenharmony_ci const unsigned nby = util_format_get_nblocksy(view->format, height); 1187bf215546Sopenharmony_ci const unsigned tsx = NVC0_TILE_SIZE_X(lvl->tile_mode); 1188bf215546Sopenharmony_ci const unsigned tsy = NVC0_TILE_SIZE_Y(lvl->tile_mode); 1189bf215546Sopenharmony_ci const unsigned tsz = NVC0_TILE_SIZE_Z(lvl->tile_mode); 1190bf215546Sopenharmony_ci 1191bf215546Sopenharmony_ci adjusted_width = align(nbx, tsx / util_format_get_blocksize(view->format)) * tsz; 1192bf215546Sopenharmony_ci adjusted_height = align(nby, tsy) * align(depth, tsz) >> NVC0_TILE_SHIFT_Z(lvl->tile_mode); 1193bf215546Sopenharmony_ci } else { 1194bf215546Sopenharmony_ci const unsigned z = view->u.tex.first_layer; 1195bf215546Sopenharmony_ci address += mt->layer_stride * z; 1196bf215546Sopenharmony_ci } 1197bf215546Sopenharmony_ci address += lvl->offset; 1198bf215546Sopenharmony_ci 1199bf215546Sopenharmony_ci PUSH_DATAh(push, address); 1200bf215546Sopenharmony_ci PUSH_DATA (push, address); 1201bf215546Sopenharmony_ci PUSH_DATA (push, adjusted_width << mt->ms_x); 1202bf215546Sopenharmony_ci PUSH_DATA (push, adjusted_height << mt->ms_y); 1203bf215546Sopenharmony_ci PUSH_DATA (push, rt); 1204bf215546Sopenharmony_ci PUSH_DATA (push, lvl->tile_mode & 0xff); /* mask out z-tiling */ 1205bf215546Sopenharmony_ci } 1206bf215546Sopenharmony_ci 1207bf215546Sopenharmony_ci if (s == 5) 1208bf215546Sopenharmony_ci BCTX_REFN(nvc0->bufctx_cp, CP_SUF, res, RDWR); 1209bf215546Sopenharmony_ci else 1210bf215546Sopenharmony_ci BCTX_REFN(nvc0->bufctx_3d, 3D_SUF, res, RDWR); 1211bf215546Sopenharmony_ci } else { 1212bf215546Sopenharmony_ci PUSH_DATA(push, 0); 1213bf215546Sopenharmony_ci PUSH_DATA(push, 0); 1214bf215546Sopenharmony_ci PUSH_DATA(push, 0); 1215bf215546Sopenharmony_ci PUSH_DATA(push, 0); 1216bf215546Sopenharmony_ci PUSH_DATA(push, 0x14000); 1217bf215546Sopenharmony_ci PUSH_DATA(push, 0); 1218bf215546Sopenharmony_ci } 1219bf215546Sopenharmony_ci 1220bf215546Sopenharmony_ci /* stick surface information into the driver constant buffer */ 1221bf215546Sopenharmony_ci if (s == 5) 1222bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_CP(CB_SIZE), 3); 1223bf215546Sopenharmony_ci else 1224bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); 1225bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_CB_AUX_SIZE); 1226bf215546Sopenharmony_ci PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s)); 1227bf215546Sopenharmony_ci PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s)); 1228bf215546Sopenharmony_ci if (s == 5) 1229bf215546Sopenharmony_ci BEGIN_1IC0(push, NVC0_CP(CB_POS), 1 + 16); 1230bf215546Sopenharmony_ci else 1231bf215546Sopenharmony_ci BEGIN_1IC0(push, NVC0_3D(CB_POS), 1 + 16); 1232bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_CB_AUX_SU_INFO(i)); 1233bf215546Sopenharmony_ci 1234bf215546Sopenharmony_ci nvc0_set_surface_info(push, view, address, width, height, depth); 1235bf215546Sopenharmony_ci } 1236bf215546Sopenharmony_ci} 1237bf215546Sopenharmony_ci 1238bf215546Sopenharmony_cistatic inline void 1239bf215546Sopenharmony_cinvc0_update_surface_bindings(struct nvc0_context *nvc0) 1240bf215546Sopenharmony_ci{ 1241bf215546Sopenharmony_ci nvc0_validate_suf(nvc0, 4); 1242bf215546Sopenharmony_ci 1243bf215546Sopenharmony_ci /* Invalidate all COMPUTE images because they are aliased with FRAGMENT. */ 1244bf215546Sopenharmony_ci nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF); 1245bf215546Sopenharmony_ci nvc0->dirty_cp |= NVC0_NEW_CP_SURFACES; 1246bf215546Sopenharmony_ci nvc0->images_dirty[5] |= nvc0->images_valid[5]; 1247bf215546Sopenharmony_ci} 1248bf215546Sopenharmony_ci 1249bf215546Sopenharmony_cistatic void 1250bf215546Sopenharmony_cigm107_validate_surfaces(struct nvc0_context *nvc0, 1251bf215546Sopenharmony_ci struct pipe_image_view *view, int stage, int slot) 1252bf215546Sopenharmony_ci{ 1253bf215546Sopenharmony_ci struct nv04_resource *res = nv04_resource(view->resource); 1254bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 1255bf215546Sopenharmony_ci struct nvc0_screen *screen = nvc0->screen; 1256bf215546Sopenharmony_ci struct nv50_tic_entry *tic; 1257bf215546Sopenharmony_ci 1258bf215546Sopenharmony_ci tic = nv50_tic_entry(nvc0->images_tic[stage][slot]); 1259bf215546Sopenharmony_ci 1260bf215546Sopenharmony_ci res = nv04_resource(tic->pipe.texture); 1261bf215546Sopenharmony_ci nvc0_update_tic(nvc0, tic, res); 1262bf215546Sopenharmony_ci 1263bf215546Sopenharmony_ci if (tic->id < 0) { 1264bf215546Sopenharmony_ci tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic); 1265bf215546Sopenharmony_ci 1266bf215546Sopenharmony_ci /* upload the texture view */ 1267bf215546Sopenharmony_ci nve4_p2mf_push_linear(&nvc0->base, nvc0->screen->txc, tic->id * 32, 1268bf215546Sopenharmony_ci NV_VRAM_DOMAIN(&nvc0->screen->base), 32, tic->tic); 1269bf215546Sopenharmony_ci 1270bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(TIC_FLUSH), 1); 1271bf215546Sopenharmony_ci PUSH_DATA (push, 0); 1272bf215546Sopenharmony_ci } else 1273bf215546Sopenharmony_ci if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) { 1274bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1); 1275bf215546Sopenharmony_ci PUSH_DATA (push, (tic->id << 4) | 1); 1276bf215546Sopenharmony_ci } 1277bf215546Sopenharmony_ci nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32); 1278bf215546Sopenharmony_ci 1279bf215546Sopenharmony_ci res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; 1280bf215546Sopenharmony_ci res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; 1281bf215546Sopenharmony_ci 1282bf215546Sopenharmony_ci BCTX_REFN(nvc0->bufctx_3d, 3D_SUF, res, RD); 1283bf215546Sopenharmony_ci 1284bf215546Sopenharmony_ci /* upload the texture handle */ 1285bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); 1286bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_CB_AUX_SIZE); 1287bf215546Sopenharmony_ci PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(stage)); 1288bf215546Sopenharmony_ci PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(stage)); 1289bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CB_POS), 2); 1290bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_CB_AUX_TEX_INFO(slot + 32)); 1291bf215546Sopenharmony_ci PUSH_DATA (push, tic->id); 1292bf215546Sopenharmony_ci} 1293bf215546Sopenharmony_ci 1294bf215546Sopenharmony_cistatic inline void 1295bf215546Sopenharmony_cinve4_update_surface_bindings(struct nvc0_context *nvc0) 1296bf215546Sopenharmony_ci{ 1297bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 1298bf215546Sopenharmony_ci struct nvc0_screen *screen = nvc0->screen; 1299bf215546Sopenharmony_ci int i, j, s; 1300bf215546Sopenharmony_ci 1301bf215546Sopenharmony_ci for (s = 0; s < 5; s++) { 1302bf215546Sopenharmony_ci if (!nvc0->images_dirty[s]) 1303bf215546Sopenharmony_ci continue; 1304bf215546Sopenharmony_ci 1305bf215546Sopenharmony_ci for (i = 0; i < NVC0_MAX_IMAGES; ++i) { 1306bf215546Sopenharmony_ci struct pipe_image_view *view = &nvc0->images[s][i]; 1307bf215546Sopenharmony_ci 1308bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); 1309bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_CB_AUX_SIZE); 1310bf215546Sopenharmony_ci PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s)); 1311bf215546Sopenharmony_ci PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s)); 1312bf215546Sopenharmony_ci BEGIN_1IC0(push, NVC0_3D(CB_POS), 1 + 16); 1313bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_CB_AUX_SU_INFO(i)); 1314bf215546Sopenharmony_ci 1315bf215546Sopenharmony_ci if (view->resource) { 1316bf215546Sopenharmony_ci struct nv04_resource *res = nv04_resource(view->resource); 1317bf215546Sopenharmony_ci 1318bf215546Sopenharmony_ci if (res->base.target == PIPE_BUFFER) { 1319bf215546Sopenharmony_ci if (view->access & PIPE_IMAGE_ACCESS_WRITE) 1320bf215546Sopenharmony_ci nvc0_mark_image_range_valid(view); 1321bf215546Sopenharmony_ci } 1322bf215546Sopenharmony_ci 1323bf215546Sopenharmony_ci nve4_set_surface_info(push, view, nvc0); 1324bf215546Sopenharmony_ci BCTX_REFN(nvc0->bufctx_3d, 3D_SUF, res, RDWR); 1325bf215546Sopenharmony_ci 1326bf215546Sopenharmony_ci if (nvc0->screen->base.class_3d >= GM107_3D_CLASS) 1327bf215546Sopenharmony_ci gm107_validate_surfaces(nvc0, view, s, i); 1328bf215546Sopenharmony_ci } else { 1329bf215546Sopenharmony_ci for (j = 0; j < 16; j++) 1330bf215546Sopenharmony_ci PUSH_DATA(push, 0); 1331bf215546Sopenharmony_ci } 1332bf215546Sopenharmony_ci } 1333bf215546Sopenharmony_ci } 1334bf215546Sopenharmony_ci} 1335bf215546Sopenharmony_ci 1336bf215546Sopenharmony_civoid 1337bf215546Sopenharmony_cinvc0_validate_surfaces(struct nvc0_context *nvc0) 1338bf215546Sopenharmony_ci{ 1339bf215546Sopenharmony_ci if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) { 1340bf215546Sopenharmony_ci nve4_update_surface_bindings(nvc0); 1341bf215546Sopenharmony_ci } else { 1342bf215546Sopenharmony_ci nvc0_update_surface_bindings(nvc0); 1343bf215546Sopenharmony_ci } 1344bf215546Sopenharmony_ci} 1345bf215546Sopenharmony_ci 1346bf215546Sopenharmony_cistatic uint64_t 1347bf215546Sopenharmony_cinve4_create_image_handle(struct pipe_context *pipe, 1348bf215546Sopenharmony_ci const struct pipe_image_view *view) 1349bf215546Sopenharmony_ci{ 1350bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 1351bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 1352bf215546Sopenharmony_ci struct nvc0_screen *screen = nvc0->screen; 1353bf215546Sopenharmony_ci int i = screen->img.next, s; 1354bf215546Sopenharmony_ci 1355bf215546Sopenharmony_ci while (screen->img.entries[i]) { 1356bf215546Sopenharmony_ci i = (i + 1) & (NVE4_IMG_MAX_HANDLES - 1); 1357bf215546Sopenharmony_ci if (i == screen->img.next) 1358bf215546Sopenharmony_ci return 0; 1359bf215546Sopenharmony_ci } 1360bf215546Sopenharmony_ci 1361bf215546Sopenharmony_ci screen->img.next = (i + 1) & (NVE4_IMG_MAX_HANDLES - 1); 1362bf215546Sopenharmony_ci screen->img.entries[i] = calloc(1, sizeof(struct pipe_image_view)); 1363bf215546Sopenharmony_ci *screen->img.entries[i] = *view; 1364bf215546Sopenharmony_ci 1365bf215546Sopenharmony_ci for (s = 0; s < 6; s++) { 1366bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); 1367bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_CB_AUX_SIZE); 1368bf215546Sopenharmony_ci PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s)); 1369bf215546Sopenharmony_ci PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s)); 1370bf215546Sopenharmony_ci BEGIN_1IC0(push, NVC0_3D(CB_POS), 1 + 16); 1371bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_CB_AUX_BINDLESS_INFO(i)); 1372bf215546Sopenharmony_ci nve4_set_surface_info(push, view, nvc0); 1373bf215546Sopenharmony_ci } 1374bf215546Sopenharmony_ci 1375bf215546Sopenharmony_ci return 0x100000000ULL | i; 1376bf215546Sopenharmony_ci} 1377bf215546Sopenharmony_ci 1378bf215546Sopenharmony_cistatic void 1379bf215546Sopenharmony_cinve4_delete_image_handle(struct pipe_context *pipe, uint64_t handle) 1380bf215546Sopenharmony_ci{ 1381bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 1382bf215546Sopenharmony_ci struct nvc0_screen *screen = nvc0->screen; 1383bf215546Sopenharmony_ci int i = handle & (NVE4_IMG_MAX_HANDLES - 1); 1384bf215546Sopenharmony_ci 1385bf215546Sopenharmony_ci free(screen->img.entries[i]); 1386bf215546Sopenharmony_ci screen->img.entries[i] = NULL; 1387bf215546Sopenharmony_ci} 1388bf215546Sopenharmony_ci 1389bf215546Sopenharmony_cistatic void 1390bf215546Sopenharmony_cinve4_make_image_handle_resident(struct pipe_context *pipe, uint64_t handle, 1391bf215546Sopenharmony_ci unsigned access, bool resident) 1392bf215546Sopenharmony_ci{ 1393bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 1394bf215546Sopenharmony_ci struct nvc0_screen *screen = nvc0->screen; 1395bf215546Sopenharmony_ci 1396bf215546Sopenharmony_ci if (resident) { 1397bf215546Sopenharmony_ci struct nvc0_resident *res = calloc(1, sizeof(struct nvc0_resident)); 1398bf215546Sopenharmony_ci struct pipe_image_view *view = 1399bf215546Sopenharmony_ci screen->img.entries[handle & (NVE4_IMG_MAX_HANDLES - 1)]; 1400bf215546Sopenharmony_ci assert(view); 1401bf215546Sopenharmony_ci 1402bf215546Sopenharmony_ci if (view->resource->target == PIPE_BUFFER && 1403bf215546Sopenharmony_ci access & PIPE_IMAGE_ACCESS_WRITE) 1404bf215546Sopenharmony_ci nvc0_mark_image_range_valid(view); 1405bf215546Sopenharmony_ci res->handle = handle; 1406bf215546Sopenharmony_ci res->buf = nv04_resource(view->resource); 1407bf215546Sopenharmony_ci res->flags = (access & 3) << 8; 1408bf215546Sopenharmony_ci list_add(&res->list, &nvc0->img_head); 1409bf215546Sopenharmony_ci } else { 1410bf215546Sopenharmony_ci list_for_each_entry_safe(struct nvc0_resident, pos, &nvc0->img_head, list) { 1411bf215546Sopenharmony_ci if (pos->handle == handle) { 1412bf215546Sopenharmony_ci list_del(&pos->list); 1413bf215546Sopenharmony_ci free(pos); 1414bf215546Sopenharmony_ci break; 1415bf215546Sopenharmony_ci } 1416bf215546Sopenharmony_ci } 1417bf215546Sopenharmony_ci } 1418bf215546Sopenharmony_ci} 1419bf215546Sopenharmony_ci 1420bf215546Sopenharmony_cistatic uint64_t 1421bf215546Sopenharmony_cigm107_create_image_handle(struct pipe_context *pipe, 1422bf215546Sopenharmony_ci const struct pipe_image_view *view) 1423bf215546Sopenharmony_ci{ 1424bf215546Sopenharmony_ci /* GM107+ use TIC handles to reference images. As such, image handles are 1425bf215546Sopenharmony_ci * just the TIC id. 1426bf215546Sopenharmony_ci */ 1427bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 1428bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 1429bf215546Sopenharmony_ci struct pipe_sampler_view *sview = 1430bf215546Sopenharmony_ci gm107_create_texture_view_from_image(pipe, view); 1431bf215546Sopenharmony_ci struct nv50_tic_entry *tic = nv50_tic_entry(sview); 1432bf215546Sopenharmony_ci 1433bf215546Sopenharmony_ci if (tic == NULL) 1434bf215546Sopenharmony_ci goto fail; 1435bf215546Sopenharmony_ci 1436bf215546Sopenharmony_ci tic->bindless = 1; 1437bf215546Sopenharmony_ci tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic); 1438bf215546Sopenharmony_ci if (tic->id < 0) 1439bf215546Sopenharmony_ci goto fail; 1440bf215546Sopenharmony_ci 1441bf215546Sopenharmony_ci nve4_p2mf_push_linear(&nvc0->base, nvc0->screen->txc, tic->id * 32, 1442bf215546Sopenharmony_ci NV_VRAM_DOMAIN(&nvc0->screen->base), 32, 1443bf215546Sopenharmony_ci tic->tic); 1444bf215546Sopenharmony_ci 1445bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(TIC_FLUSH), 0); 1446bf215546Sopenharmony_ci 1447bf215546Sopenharmony_ci nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32); 1448bf215546Sopenharmony_ci 1449bf215546Sopenharmony_ci // Compute handle. This will include the TIC as well as some additional 1450bf215546Sopenharmony_ci // info regarding the bound 3d surface layer, if applicable. 1451bf215546Sopenharmony_ci uint64_t handle = 0x100000000ULL | tic->id; 1452bf215546Sopenharmony_ci struct nv04_resource *res = nv04_resource(view->resource); 1453bf215546Sopenharmony_ci if (res->base.target == PIPE_TEXTURE_3D) { 1454bf215546Sopenharmony_ci handle |= 1 << 11; 1455bf215546Sopenharmony_ci handle |= view->u.tex.first_layer << (11 + 16); 1456bf215546Sopenharmony_ci } 1457bf215546Sopenharmony_ci return handle; 1458bf215546Sopenharmony_ci 1459bf215546Sopenharmony_cifail: 1460bf215546Sopenharmony_ci FREE(tic); 1461bf215546Sopenharmony_ci return 0; 1462bf215546Sopenharmony_ci} 1463bf215546Sopenharmony_ci 1464bf215546Sopenharmony_cistatic void 1465bf215546Sopenharmony_cigm107_delete_image_handle(struct pipe_context *pipe, uint64_t handle) 1466bf215546Sopenharmony_ci{ 1467bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 1468bf215546Sopenharmony_ci int tic = handle & NVE4_TIC_ENTRY_INVALID; 1469bf215546Sopenharmony_ci struct nv50_tic_entry *entry = nvc0->screen->tic.entries[tic]; 1470bf215546Sopenharmony_ci struct pipe_sampler_view *view = &entry->pipe; 1471bf215546Sopenharmony_ci assert(entry->bindless == 1); 1472bf215546Sopenharmony_ci assert(!view_bound(nvc0, view)); 1473bf215546Sopenharmony_ci entry->bindless = 0; 1474bf215546Sopenharmony_ci nvc0_screen_tic_unlock(nvc0->screen, entry); 1475bf215546Sopenharmony_ci pipe_sampler_view_reference(&view, NULL); 1476bf215546Sopenharmony_ci} 1477bf215546Sopenharmony_ci 1478bf215546Sopenharmony_cistatic void 1479bf215546Sopenharmony_cigm107_make_image_handle_resident(struct pipe_context *pipe, uint64_t handle, 1480bf215546Sopenharmony_ci unsigned access, bool resident) 1481bf215546Sopenharmony_ci{ 1482bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 1483bf215546Sopenharmony_ci 1484bf215546Sopenharmony_ci if (resident) { 1485bf215546Sopenharmony_ci struct nvc0_resident *res = calloc(1, sizeof(struct nvc0_resident)); 1486bf215546Sopenharmony_ci struct nv50_tic_entry *tic = 1487bf215546Sopenharmony_ci nvc0->screen->tic.entries[handle & NVE4_TIC_ENTRY_INVALID]; 1488bf215546Sopenharmony_ci assert(tic); 1489bf215546Sopenharmony_ci assert(tic->bindless); 1490bf215546Sopenharmony_ci 1491bf215546Sopenharmony_ci res->handle = handle; 1492bf215546Sopenharmony_ci res->buf = nv04_resource(tic->pipe.texture); 1493bf215546Sopenharmony_ci res->flags = (access & 3) << 8; 1494bf215546Sopenharmony_ci if (res->buf->base.target == PIPE_BUFFER && 1495bf215546Sopenharmony_ci access & PIPE_IMAGE_ACCESS_WRITE) 1496bf215546Sopenharmony_ci util_range_add(&res->buf->base, &res->buf->valid_buffer_range, 1497bf215546Sopenharmony_ci tic->pipe.u.buf.offset, 1498bf215546Sopenharmony_ci tic->pipe.u.buf.offset + tic->pipe.u.buf.size); 1499bf215546Sopenharmony_ci list_add(&res->list, &nvc0->img_head); 1500bf215546Sopenharmony_ci } else { 1501bf215546Sopenharmony_ci list_for_each_entry_safe(struct nvc0_resident, pos, &nvc0->img_head, list) { 1502bf215546Sopenharmony_ci if (pos->handle == handle) { 1503bf215546Sopenharmony_ci list_del(&pos->list); 1504bf215546Sopenharmony_ci free(pos); 1505bf215546Sopenharmony_ci break; 1506bf215546Sopenharmony_ci } 1507bf215546Sopenharmony_ci } 1508bf215546Sopenharmony_ci } 1509bf215546Sopenharmony_ci} 1510bf215546Sopenharmony_ci 1511bf215546Sopenharmony_civoid 1512bf215546Sopenharmony_cinvc0_init_bindless_functions(struct pipe_context *pipe) { 1513bf215546Sopenharmony_ci pipe->create_texture_handle = nve4_create_texture_handle; 1514bf215546Sopenharmony_ci pipe->delete_texture_handle = nve4_delete_texture_handle; 1515bf215546Sopenharmony_ci pipe->make_texture_handle_resident = nve4_make_texture_handle_resident; 1516bf215546Sopenharmony_ci 1517bf215546Sopenharmony_ci if (nvc0_context(pipe)->screen->base.class_3d < GM107_3D_CLASS) { 1518bf215546Sopenharmony_ci pipe->create_image_handle = nve4_create_image_handle; 1519bf215546Sopenharmony_ci pipe->delete_image_handle = nve4_delete_image_handle; 1520bf215546Sopenharmony_ci pipe->make_image_handle_resident = nve4_make_image_handle_resident; 1521bf215546Sopenharmony_ci } else { 1522bf215546Sopenharmony_ci pipe->create_image_handle = gm107_create_image_handle; 1523bf215546Sopenharmony_ci pipe->delete_image_handle = gm107_delete_image_handle; 1524bf215546Sopenharmony_ci pipe->make_image_handle_resident = gm107_make_image_handle_resident; 1525bf215546Sopenharmony_ci } 1526bf215546Sopenharmony_ci} 1527bf215546Sopenharmony_ci 1528bf215546Sopenharmony_ci 1529bf215546Sopenharmony_cistatic const uint8_t nve4_su_format_map[PIPE_FORMAT_COUNT] = 1530bf215546Sopenharmony_ci{ 1531bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32B32A32_FLOAT] = GK104_IMAGE_FORMAT_RGBA32_FLOAT, 1532bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32B32A32_SINT] = GK104_IMAGE_FORMAT_RGBA32_SINT, 1533bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32B32A32_UINT] = GK104_IMAGE_FORMAT_RGBA32_UINT, 1534bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_FLOAT] = GK104_IMAGE_FORMAT_RGBA16_FLOAT, 1535bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_UNORM] = GK104_IMAGE_FORMAT_RGBA16_UNORM, 1536bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_SNORM] = GK104_IMAGE_FORMAT_RGBA16_SNORM, 1537bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_SINT] = GK104_IMAGE_FORMAT_RGBA16_SINT, 1538bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_UINT] = GK104_IMAGE_FORMAT_RGBA16_UINT, 1539bf215546Sopenharmony_ci [PIPE_FORMAT_B8G8R8A8_UNORM] = GK104_IMAGE_FORMAT_BGRA8_UNORM, 1540bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8B8A8_UNORM] = GK104_IMAGE_FORMAT_RGBA8_UNORM, 1541bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8B8A8_SNORM] = GK104_IMAGE_FORMAT_RGBA8_SNORM, 1542bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8B8A8_SINT] = GK104_IMAGE_FORMAT_RGBA8_SINT, 1543bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8B8A8_UINT] = GK104_IMAGE_FORMAT_RGBA8_UINT, 1544bf215546Sopenharmony_ci [PIPE_FORMAT_R11G11B10_FLOAT] = GK104_IMAGE_FORMAT_R11G11B10_FLOAT, 1545bf215546Sopenharmony_ci [PIPE_FORMAT_R10G10B10A2_UNORM] = GK104_IMAGE_FORMAT_RGB10_A2_UNORM, 1546bf215546Sopenharmony_ci [PIPE_FORMAT_R10G10B10A2_UINT] = GK104_IMAGE_FORMAT_RGB10_A2_UINT, 1547bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32_FLOAT] = GK104_IMAGE_FORMAT_RG32_FLOAT, 1548bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32_SINT] = GK104_IMAGE_FORMAT_RG32_SINT, 1549bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32_UINT] = GK104_IMAGE_FORMAT_RG32_UINT, 1550bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_FLOAT] = GK104_IMAGE_FORMAT_RG16_FLOAT, 1551bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_UNORM] = GK104_IMAGE_FORMAT_RG16_UNORM, 1552bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_SNORM] = GK104_IMAGE_FORMAT_RG16_SNORM, 1553bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_SINT] = GK104_IMAGE_FORMAT_RG16_SINT, 1554bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_UINT] = GK104_IMAGE_FORMAT_RG16_UINT, 1555bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8_UNORM] = GK104_IMAGE_FORMAT_RG8_UNORM, 1556bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8_SNORM] = GK104_IMAGE_FORMAT_RG8_SNORM, 1557bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8_SINT] = GK104_IMAGE_FORMAT_RG8_SINT, 1558bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8_UINT] = GK104_IMAGE_FORMAT_RG8_UINT, 1559bf215546Sopenharmony_ci [PIPE_FORMAT_R32_FLOAT] = GK104_IMAGE_FORMAT_R32_FLOAT, 1560bf215546Sopenharmony_ci [PIPE_FORMAT_R32_SINT] = GK104_IMAGE_FORMAT_R32_SINT, 1561bf215546Sopenharmony_ci [PIPE_FORMAT_R32_UINT] = GK104_IMAGE_FORMAT_R32_UINT, 1562bf215546Sopenharmony_ci [PIPE_FORMAT_R16_FLOAT] = GK104_IMAGE_FORMAT_R16_FLOAT, 1563bf215546Sopenharmony_ci [PIPE_FORMAT_R16_UNORM] = GK104_IMAGE_FORMAT_R16_UNORM, 1564bf215546Sopenharmony_ci [PIPE_FORMAT_R16_SNORM] = GK104_IMAGE_FORMAT_R16_SNORM, 1565bf215546Sopenharmony_ci [PIPE_FORMAT_R16_SINT] = GK104_IMAGE_FORMAT_R16_SINT, 1566bf215546Sopenharmony_ci [PIPE_FORMAT_R16_UINT] = GK104_IMAGE_FORMAT_R16_UINT, 1567bf215546Sopenharmony_ci [PIPE_FORMAT_R8_UNORM] = GK104_IMAGE_FORMAT_R8_UNORM, 1568bf215546Sopenharmony_ci [PIPE_FORMAT_R8_SNORM] = GK104_IMAGE_FORMAT_R8_SNORM, 1569bf215546Sopenharmony_ci [PIPE_FORMAT_R8_SINT] = GK104_IMAGE_FORMAT_R8_SINT, 1570bf215546Sopenharmony_ci [PIPE_FORMAT_R8_UINT] = GK104_IMAGE_FORMAT_R8_UINT, 1571bf215546Sopenharmony_ci}; 1572bf215546Sopenharmony_ci 1573bf215546Sopenharmony_ci/* Auxiliary format description values for surface instructions. 1574bf215546Sopenharmony_ci * (log2(bytes per pixel) << 12) | (unk8 << 8) | unk22 1575bf215546Sopenharmony_ci */ 1576bf215546Sopenharmony_cistatic const uint16_t nve4_su_format_aux_map[PIPE_FORMAT_COUNT] = 1577bf215546Sopenharmony_ci{ 1578bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32B32A32_FLOAT] = 0x4842, 1579bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32B32A32_SINT] = 0x4842, 1580bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32B32A32_UINT] = 0x4842, 1581bf215546Sopenharmony_ci 1582bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_UNORM] = 0x3933, 1583bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_SNORM] = 0x3933, 1584bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_SINT] = 0x3933, 1585bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_UINT] = 0x3933, 1586bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_FLOAT] = 0x3933, 1587bf215546Sopenharmony_ci 1588bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32_FLOAT] = 0x3433, 1589bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32_SINT] = 0x3433, 1590bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32_UINT] = 0x3433, 1591bf215546Sopenharmony_ci 1592bf215546Sopenharmony_ci [PIPE_FORMAT_R10G10B10A2_UNORM] = 0x2a24, 1593bf215546Sopenharmony_ci [PIPE_FORMAT_R10G10B10A2_UINT] = 0x2a24, 1594bf215546Sopenharmony_ci [PIPE_FORMAT_B8G8R8A8_UNORM] = 0x2a24, 1595bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8B8A8_UNORM] = 0x2a24, 1596bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8B8A8_SNORM] = 0x2a24, 1597bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8B8A8_SINT] = 0x2a24, 1598bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8B8A8_UINT] = 0x2a24, 1599bf215546Sopenharmony_ci [PIPE_FORMAT_R11G11B10_FLOAT] = 0x2a24, 1600bf215546Sopenharmony_ci 1601bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_UNORM] = 0x2524, 1602bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_SNORM] = 0x2524, 1603bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_SINT] = 0x2524, 1604bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_UINT] = 0x2524, 1605bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_FLOAT] = 0x2524, 1606bf215546Sopenharmony_ci 1607bf215546Sopenharmony_ci [PIPE_FORMAT_R32_SINT] = 0x2024, 1608bf215546Sopenharmony_ci [PIPE_FORMAT_R32_UINT] = 0x2024, 1609bf215546Sopenharmony_ci [PIPE_FORMAT_R32_FLOAT] = 0x2024, 1610bf215546Sopenharmony_ci 1611bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8_UNORM] = 0x1615, 1612bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8_SNORM] = 0x1615, 1613bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8_SINT] = 0x1615, 1614bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8_UINT] = 0x1615, 1615bf215546Sopenharmony_ci 1616bf215546Sopenharmony_ci [PIPE_FORMAT_R16_UNORM] = 0x1115, 1617bf215546Sopenharmony_ci [PIPE_FORMAT_R16_SNORM] = 0x1115, 1618bf215546Sopenharmony_ci [PIPE_FORMAT_R16_SINT] = 0x1115, 1619bf215546Sopenharmony_ci [PIPE_FORMAT_R16_UINT] = 0x1115, 1620bf215546Sopenharmony_ci [PIPE_FORMAT_R16_FLOAT] = 0x1115, 1621bf215546Sopenharmony_ci 1622bf215546Sopenharmony_ci [PIPE_FORMAT_R8_UNORM] = 0x0206, 1623bf215546Sopenharmony_ci [PIPE_FORMAT_R8_SNORM] = 0x0206, 1624bf215546Sopenharmony_ci [PIPE_FORMAT_R8_SINT] = 0x0206, 1625bf215546Sopenharmony_ci [PIPE_FORMAT_R8_UINT] = 0x0206 1626bf215546Sopenharmony_ci}; 1627bf215546Sopenharmony_ci 1628bf215546Sopenharmony_ci/* NOTE: These are hardcoded offsets for the shader library. 1629bf215546Sopenharmony_ci * TODO: Automate them. 1630bf215546Sopenharmony_ci */ 1631bf215546Sopenharmony_cistatic const uint16_t nve4_suldp_lib_offset[PIPE_FORMAT_COUNT] = 1632bf215546Sopenharmony_ci{ 1633bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32B32A32_FLOAT] = 0x218, 1634bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32B32A32_SINT] = 0x218, 1635bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32B32A32_UINT] = 0x218, 1636bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_UNORM] = 0x248, 1637bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_SNORM] = 0x2b8, 1638bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_SINT] = 0x330, 1639bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_UINT] = 0x388, 1640bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16B16A16_FLOAT] = 0x3d8, 1641bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32_FLOAT] = 0x428, 1642bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32_SINT] = 0x468, 1643bf215546Sopenharmony_ci [PIPE_FORMAT_R32G32_UINT] = 0x468, 1644bf215546Sopenharmony_ci [PIPE_FORMAT_R10G10B10A2_UNORM] = 0x4a8, 1645bf215546Sopenharmony_ci [PIPE_FORMAT_R10G10B10A2_UINT] = 0x530, 1646bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8B8A8_UNORM] = 0x588, 1647bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8B8A8_SNORM] = 0x5f8, 1648bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8B8A8_SINT] = 0x670, 1649bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8B8A8_UINT] = 0x6c8, 1650bf215546Sopenharmony_ci [PIPE_FORMAT_B5G6R5_UNORM] = 0x718, 1651bf215546Sopenharmony_ci [PIPE_FORMAT_B5G5R5X1_UNORM] = 0x7a0, 1652bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_UNORM] = 0x828, 1653bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_SNORM] = 0x890, 1654bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_SINT] = 0x8f0, 1655bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_UINT] = 0x948, 1656bf215546Sopenharmony_ci [PIPE_FORMAT_R16G16_FLOAT] = 0x998, 1657bf215546Sopenharmony_ci [PIPE_FORMAT_R32_FLOAT] = 0x9e8, 1658bf215546Sopenharmony_ci [PIPE_FORMAT_R32_SINT] = 0xa30, 1659bf215546Sopenharmony_ci [PIPE_FORMAT_R32_UINT] = 0xa30, 1660bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8_UNORM] = 0xa78, 1661bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8_SNORM] = 0xae0, 1662bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8_UINT] = 0xb48, 1663bf215546Sopenharmony_ci [PIPE_FORMAT_R8G8_SINT] = 0xb98, 1664bf215546Sopenharmony_ci [PIPE_FORMAT_R16_UNORM] = 0xbe8, 1665bf215546Sopenharmony_ci [PIPE_FORMAT_R16_SNORM] = 0xc48, 1666bf215546Sopenharmony_ci [PIPE_FORMAT_R16_SINT] = 0xca0, 1667bf215546Sopenharmony_ci [PIPE_FORMAT_R16_UINT] = 0xce8, 1668bf215546Sopenharmony_ci [PIPE_FORMAT_R16_FLOAT] = 0xd30, 1669bf215546Sopenharmony_ci [PIPE_FORMAT_R8_UNORM] = 0xd88, 1670bf215546Sopenharmony_ci [PIPE_FORMAT_R8_SNORM] = 0xde0, 1671bf215546Sopenharmony_ci [PIPE_FORMAT_R8_SINT] = 0xe38, 1672bf215546Sopenharmony_ci [PIPE_FORMAT_R8_UINT] = 0xe88, 1673bf215546Sopenharmony_ci [PIPE_FORMAT_R11G11B10_FLOAT] = 0xed0 1674bf215546Sopenharmony_ci}; 1675