struct pipe_sampler_view * nvc0_create_texture_view(struct pipe_context *pipe, struct pipe_resource *texture, const struct pipe_sampler_view *templ, uint32_t flags, enum pipe_texture_target target) { const struct util_format_description *desc; uint64_t address; uint32_t *tic; uint32_t swz[4]; uint32_t depth; struct nv50_tic_entry *view; struct nv50_miptree *mt; boolean tex_int; view = MALLOC_STRUCT(nv50_tic_entry); if (!view) return NULL; mt = nv50_miptree(texture); view->pipe = *templ; view->pipe.reference.count = 1; view->pipe.texture = NULL; view->pipe.context = pipe; view->id = -1; pipe_resource_reference(&view->pipe.texture, texture); tic = &view->tic[0]; desc = util_format_description(view->pipe.format); tic[0] = nvc0_format_table[view->pipe.format].tic; tex_int = util_format_is_pure_integer(view->pipe.format); swz[0] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_r, tex_int); swz[1] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_g, tex_int); swz[2] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_b, tex_int); swz[3] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_a, tex_int); tic[0] = (tic[0] & ~NV50_TIC_0_SWIZZLE__MASK) | (swz[0] << NV50_TIC_0_MAPR__SHIFT) | (swz[1] << NV50_TIC_0_MAPG__SHIFT) | (swz[2] << NV50_TIC_0_MAPB__SHIFT) | (swz[3] << NV50_TIC_0_MAPA__SHIFT); address = mt->base.address; tic[2] = 0x10001000 | NV50_TIC_2_NO_BORDER; if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) tic[2] |= NV50_TIC_2_COLORSPACE_SRGB; /* check for linear storage type */ if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) { if (texture->target == PIPE_BUFFER) { address += view->pipe.u.buf.first_element * desc->block.bits / 8; tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER; tic[3] = 0; tic[4] = /* width */ view->pipe.u.buf.last_element - view->pipe.u.buf.first_element + 1; tic[5] = 0; } else { /* must be 2D texture without mip maps */ tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_RECT; if (texture->target != PIPE_TEXTURE_RECT) tic[2] |= NV50_TIC_2_NORMALIZED_COORDS; tic[3] = mt->level[0].pitch; tic[4] = mt->base.base.width0; tic[5] = (1 << 16) | mt->base.base.height0; } tic[6] = tic[7] = 0; tic[1] = address; tic[2] |= address >> 32; return &view->pipe; } if (!(flags & NV50_TEXVIEW_SCALED_COORDS)) tic[2] |= NV50_TIC_2_NORMALIZED_COORDS; tic[2] |= ((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) | ((mt->level[0].tile_mode & 0xf00) << (25 - 8)); depth = MAX2(mt->base.base.array_size, mt->base.base.depth0); if (mt->base.base.array_size > 1) { /* there doesn't seem to be a base layer field in TIC */ address += view->pipe.u.tex.first_layer * mt->layer_stride; depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1; } tic[1] = address; tic[2] |= address >> 32; switch (target) { case PIPE_TEXTURE_1D: tic[2] |= NV50_TIC_2_TARGET_1D; break; /* case PIPE_TEXTURE_2D_MS: */ case PIPE_TEXTURE_2D: tic[2] |= NV50_TIC_2_TARGET_2D; break; case PIPE_TEXTURE_RECT: tic[2] |= NV50_TIC_2_TARGET_RECT; break; case PIPE_TEXTURE_3D: tic[2] |= NV50_TIC_2_TARGET_3D; break; case PIPE_TEXTURE_CUBE: depth /= 6; tic[2] |= NV50_TIC_2_TARGET_CUBE; break; case PIPE_TEXTURE_1D_ARRAY: tic[2] |= NV50_TIC_2_TARGET_1D_ARRAY; break; /* case PIPE_TEXTURE_2D_ARRAY_MS: */ case PIPE_TEXTURE_2D_ARRAY: tic[2] |= NV50_TIC_2_TARGET_2D_ARRAY; break; case PIPE_TEXTURE_CUBE_ARRAY: depth /= 6; tic[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY; break; default: NOUVEAU_ERR("invalid texture target: %d\n", mt->base.base.target); return FALSE; } if (mt->base.base.target == PIPE_BUFFER) tic[3] = mt->base.base.width0; else tic[3] = (flags & NV50_TEXVIEW_FILTER_MSAA8) ? 0x20000000 : 0x00300000; tic[4] = (1 << 31) | (mt->base.base.width0 << mt->ms_x); tic[5] = (mt->base.base.height0 << mt->ms_y) & 0xffff; tic[5] |= depth << 16; tic[5] |= mt->base.base.last_level << 28; tic[6] = (mt->ms_x > 1) ? 0x88000000 : 0x03000000; /* sampling points */ tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level; /* if (mt->base.base.target == PIPE_TEXTURE_2D_MS || mt->base.base.target == PIPE_TEXTURE_2D_ARRAY_MS) tic[7] |= mt->ms_mode << 12; */ return &view->pipe; }
static struct pipe_sampler_view * gm107_create_texture_view(struct pipe_context *pipe, struct pipe_resource *texture, const struct pipe_sampler_view *templ, uint32_t flags, enum pipe_texture_target target) { const struct util_format_description *desc; const struct nvc0_format *fmt; uint64_t address; uint32_t *tic; uint32_t swz[4]; uint32_t width, height; uint32_t depth; struct nv50_tic_entry *view; struct nv50_miptree *mt; bool tex_int; view = MALLOC_STRUCT(nv50_tic_entry); if (!view) return NULL; mt = nv50_miptree(texture); view->pipe = *templ; view->pipe.reference.count = 1; view->pipe.texture = NULL; view->pipe.context = pipe; view->id = -1; pipe_resource_reference(&view->pipe.texture, texture); tic = &view->tic[0]; desc = util_format_description(view->pipe.format); tex_int = util_format_is_pure_integer(view->pipe.format); fmt = &nvc0_format_table[view->pipe.format]; swz[0] = nv50_tic_swizzle(fmt, view->pipe.swizzle_r, tex_int); swz[1] = nv50_tic_swizzle(fmt, view->pipe.swizzle_g, tex_int); swz[2] = nv50_tic_swizzle(fmt, view->pipe.swizzle_b, tex_int); swz[3] = nv50_tic_swizzle(fmt, view->pipe.swizzle_a, tex_int); tic[0] = fmt->tic.format << GM107_TIC2_0_COMPONENTS_SIZES__SHIFT; tic[0] |= fmt->tic.type_r << GM107_TIC2_0_R_DATA_TYPE__SHIFT; tic[0] |= fmt->tic.type_g << GM107_TIC2_0_G_DATA_TYPE__SHIFT; tic[0] |= fmt->tic.type_b << GM107_TIC2_0_B_DATA_TYPE__SHIFT; tic[0] |= fmt->tic.type_a << GM107_TIC2_0_A_DATA_TYPE__SHIFT; tic[0] |= swz[0] << GM107_TIC2_0_X_SOURCE__SHIFT; tic[0] |= swz[1] << GM107_TIC2_0_Y_SOURCE__SHIFT; tic[0] |= swz[2] << GM107_TIC2_0_Z_SOURCE__SHIFT; tic[0] |= swz[3] << GM107_TIC2_0_W_SOURCE__SHIFT; address = mt->base.address; tic[3] = GM107_TIC2_3_LOD_ANISO_QUALITY_2; tic[4] = GM107_TIC2_4_SECTOR_PROMOTION_PROMOTE_TO_2_V; tic[4] |= GM107_TIC2_4_BORDER_SIZE_SAMPLER_COLOR; if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) tic[4] |= GM107_TIC2_4_SRGB_CONVERSION; if (!(flags & NV50_TEXVIEW_SCALED_COORDS)) tic[5] = GM107_TIC2_5_NORMALIZED_COORDS; else tic[5] = 0; /* check for linear storage type */ if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) { if (texture->target == PIPE_BUFFER) { assert(!(tic[5] & GM107_TIC2_5_NORMALIZED_COORDS)); width = view->pipe.u.buf.last_element - view->pipe.u.buf.first_element; address += view->pipe.u.buf.first_element * desc->block.bits / 8; tic[2] = GM107_TIC2_2_HEADER_VERSION_ONE_D_BUFFER; tic[3] |= width >> 16; tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_ONE_D_BUFFER; tic[4] |= width & 0xffff; } else {
boolean nv50_tex_construct(struct nv50_sampler_view *view) { const struct util_format_description *desc; struct nv50_miptree *mt = nv50_miptree(view->pipe.texture); uint32_t swz[4], *tic = view->tic; tic[0] = nv50_format_table[view->pipe.format].tic; swz[0] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_r); swz[1] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_g); swz[2] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_b); swz[3] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_a); view->tic[0] = (tic[0] & ~NV50TIC_0_0_SWIZZLE_MASK) | (swz[0] << NV50TIC_0_0_MAPR_SHIFT) | (swz[1] << NV50TIC_0_0_MAPG_SHIFT) | (swz[2] << NV50TIC_0_0_MAPB_SHIFT) | (swz[3] << NV50TIC_0_0_MAPA_SHIFT); tic[2] = 0x50001000; tic[2] |= ((mt->base.bo->tile_mode & 0x0f) << 22) | ((mt->base.bo->tile_mode & 0xf0) << 21); desc = util_format_description(mt->base.base.format); if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) tic[2] |= NV50TIC_0_2_COLORSPACE_SRGB; switch (mt->base.base.target) { case PIPE_TEXTURE_1D: tic[2] |= NV50TIC_0_2_TARGET_1D; break; case PIPE_TEXTURE_2D: tic[2] |= NV50TIC_0_2_TARGET_2D; break; case PIPE_TEXTURE_RECT: tic[2] |= NV50TIC_0_2_TARGET_RECT; break; case PIPE_TEXTURE_3D: tic[2] |= NV50TIC_0_2_TARGET_3D; break; case PIPE_TEXTURE_CUBE: tic[2] |= NV50TIC_0_2_TARGET_CUBE; break; default: NOUVEAU_ERR("invalid texture target: %d\n", mt->base.base.target); return FALSE; } tic[3] = 0x00300000; tic[4] = (1 << 31) | mt->base.base.width0; tic[5] = (mt->base.base.last_level << 28) | (mt->base.base.depth0 << 16) | mt->base.base.height0; tic[6] = 0x03000000; tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level; return TRUE; }
struct pipe_sampler_view * nv50_create_texture_view(struct pipe_context *pipe, struct pipe_resource *texture, const struct pipe_sampler_view *templ, uint32_t flags, enum pipe_texture_target target) { const struct util_format_description *desc; uint64_t addr; uint32_t *tic; uint32_t swz[4]; uint32_t depth; struct nv50_tic_entry *view; struct nv50_miptree *mt = nv50_miptree(texture); boolean tex_int; view = MALLOC_STRUCT(nv50_tic_entry); if (!view) return NULL; view->pipe = *templ; view->pipe.reference.count = 1; view->pipe.texture = NULL; view->pipe.context = pipe; view->id = -1; pipe_resource_reference(&view->pipe.texture, texture); tic = &view->tic[0]; desc = util_format_description(view->pipe.format); /* TIC[0] */ tic[0] = nv50_format_table[view->pipe.format].tic; tex_int = util_format_is_pure_integer(view->pipe.format); swz[0] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_r, tex_int); swz[1] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_g, tex_int); swz[2] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_b, tex_int); swz[3] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_a, tex_int); tic[0] = (tic[0] & ~NV50_TIC_0_SWIZZLE__MASK) | (swz[0] << NV50_TIC_0_MAPR__SHIFT) | (swz[1] << NV50_TIC_0_MAPG__SHIFT) | (swz[2] << NV50_TIC_0_MAPB__SHIFT) | (swz[3] << NV50_TIC_0_MAPA__SHIFT); addr = mt->base.address; if (mt->base.base.target == PIPE_TEXTURE_1D_ARRAY || mt->base.base.target == PIPE_TEXTURE_2D_ARRAY) { addr += view->pipe.u.tex.first_layer * mt->layer_stride; depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1; } else { depth = mt->base.base.depth0; } tic[2] = 0x10001000 | NV50_TIC_2_NO_BORDER; if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) tic[2] |= NV50_TIC_2_COLORSPACE_SRGB; if (!(flags & NV50_TEXVIEW_SCALED_COORDS)) tic[2] |= NV50_TIC_2_NORMALIZED_COORDS; if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) { if (target == PIPE_BUFFER) { addr += view->pipe.u.buf.first_element * desc->block.bits / 8; tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER; tic[3] = 0; tic[4] = /* width */ view->pipe.u.buf.last_element - view->pipe.u.buf.first_element + 1; tic[5] = 0; } else { tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_RECT; tic[3] = mt->level[0].pitch; tic[4] = mt->base.base.width0; tic[5] = (1 << 16) | (mt->base.base.height0); } tic[6] = tic[7] = 0; tic[1] = addr; tic[2] |= addr >> 32; return &view->pipe; } tic[1] = addr; tic[2] |= (addr >> 32) & 0xff; tic[2] |= ((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) | ((mt->level[0].tile_mode & 0xf00) << (25 - 8)); switch (target) { case PIPE_TEXTURE_1D: tic[2] |= NV50_TIC_2_TARGET_1D; break; case PIPE_TEXTURE_2D: tic[2] |= NV50_TIC_2_TARGET_2D; break; case PIPE_TEXTURE_RECT: tic[2] |= NV50_TIC_2_TARGET_RECT; break; case PIPE_TEXTURE_3D: tic[2] |= NV50_TIC_2_TARGET_3D; break; case PIPE_TEXTURE_CUBE: depth /= 6; tic[2] |= NV50_TIC_2_TARGET_CUBE; break; case PIPE_TEXTURE_1D_ARRAY: tic[2] |= NV50_TIC_2_TARGET_1D_ARRAY; break; case PIPE_TEXTURE_2D_ARRAY: tic[2] |= NV50_TIC_2_TARGET_2D_ARRAY; break; case PIPE_TEXTURE_CUBE_ARRAY: depth /= 6; tic[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY; break; case PIPE_BUFFER: assert(0); /* should be linear and handled above ! */ tic[2] |= NV50_TIC_2_TARGET_BUFFER | NV50_TIC_2_LINEAR; break; default: NOUVEAU_ERR("invalid texture target: %d\n", mt->base.base.target); return FALSE; } tic[3] = (flags & NV50_TEXVIEW_FILTER_MSAA8) ? 0x20000000 : 0x00300000; tic[4] = (1 << 31) | (mt->base.base.width0 << mt->ms_x); tic[5] = (mt->base.base.height0 << mt->ms_y) & 0xffff; tic[5] |= depth << 16; tic[5] |= mt->base.base.last_level << NV50_TIC_5_LAST_LEVEL__SHIFT; tic[6] = (mt->ms_x > 1) ? 0x88000000 : 0x03000000; /* sampling points */ tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level; if (unlikely(!(tic[2] & NV50_TIC_2_NORMALIZED_COORDS))) if (mt->base.base.last_level) tic[5] &= ~NV50_TIC_5_LAST_LEVEL__MASK; return &view->pipe; }