1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2008 Ben Skeggs
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included in
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * all copies or substantial portions of the Software.
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "nvc0_context.h"
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "nvc0_resource.h"
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "nv50/nv50_texture.xml.h"
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h"
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define NVE4_TIC_ENTRY_INVALID 0x000fffff
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define NVE4_TSC_ENTRY_INVALID 0xfff00000
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define NV50_TIC_0_SWIZZLE__MASK                      \
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (NV50_TIC_0_MAPA__MASK | NV50_TIC_0_MAPB__MASK |   \
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    NV50_TIC_0_MAPG__MASK | NV50_TIC_0_MAPR__MASK)
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE uint32_t
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_tic_swizzle(uint32_t tc, unsigned swz, boolean tex_int)
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (swz) {
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_SWIZZLE_RED:
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (tc & NV50_TIC_0_MAPR__MASK) >> NV50_TIC_0_MAPR__SHIFT;
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_SWIZZLE_GREEN:
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (tc & NV50_TIC_0_MAPG__MASK) >> NV50_TIC_0_MAPG__SHIFT;
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_SWIZZLE_BLUE:
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (tc & NV50_TIC_0_MAPB__MASK) >> NV50_TIC_0_MAPB__SHIFT;
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_SWIZZLE_ALPHA:
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (tc & NV50_TIC_0_MAPA__MASK) >> NV50_TIC_0_MAPA__SHIFT;
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_SWIZZLE_ONE:
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return tex_int ? NV50_TIC_MAP_ONE_INT : NV50_TIC_MAP_ONE_FLOAT;
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_SWIZZLE_ZERO:
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NV50_TIC_MAP_ZERO;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pipe_sampler_view *
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnvc0_create_sampler_view(struct pipe_context *pipe,
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         struct pipe_resource *texture,
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         const struct pipe_sampler_view *templ)
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct util_format_description *desc;
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint64_t address;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t *tic;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t swz[4];
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t depth;
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nv50_tic_entry *view;
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nv50_miptree *mt;
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean tex_int;
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   view = MALLOC_STRUCT(nv50_tic_entry);
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!view)
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mt = nv50_miptree(texture);
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   view->pipe = *templ;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   view->pipe.reference.count = 1;
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   view->pipe.texture = NULL;
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   view->pipe.context = pipe;
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   view->id = -1;
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_resource_reference(&view->pipe.texture, texture);
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tic = &view->tic[0];
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   desc = util_format_description(view->pipe.format);
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tic[0] = nvc0_format_table[view->pipe.format].tic;
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tex_int = util_format_is_pure_integer(view->pipe.format);
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   swz[0] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_r, tex_int);
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   swz[1] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_g, tex_int);
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   swz[2] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_b, tex_int);
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   swz[3] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_a, tex_int);
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tic[0] = (tic[0] & ~NV50_TIC_0_SWIZZLE__MASK) |
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (swz[0] << NV50_TIC_0_MAPR__SHIFT) |
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (swz[1] << NV50_TIC_0_MAPG__SHIFT) |
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (swz[2] << NV50_TIC_0_MAPB__SHIFT) |
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (swz[3] << NV50_TIC_0_MAPA__SHIFT);
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   address = mt->base.address;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tic[2] = 0x10001000 | NV50_TIC_2_NO_BORDER;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[2] |= NV50_TIC_2_COLORSPACE_SRGB;
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* check for linear storage type */
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (texture->target == PIPE_BUFFER) {
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         address +=
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            view->pipe.u.buf.first_element * desc->block.bits / 8;
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER;
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tic[3] = 0;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tic[4] = /* width */
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            view->pipe.u.buf.last_element - view->pipe.u.buf.first_element + 1;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tic[5] = 0;
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* must be 2D texture without mip maps */
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_RECT;
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (texture->target != PIPE_TEXTURE_RECT)
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tic[2] |= NV50_TIC_2_NORMALIZED_COORDS;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tic[3] = mt->level[0].pitch;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tic[4] = mt->base.base.width0;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tic[5] = (1 << 16) | mt->base.base.height0;
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[6] =
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[7] = 0;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[1] = address;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[2] |= address >> 32;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return &view->pipe;
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mt->base.base.target != PIPE_TEXTURE_RECT)
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[2] |= NV50_TIC_2_NORMALIZED_COORDS;
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tic[2] |=
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) |
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ((mt->level[0].tile_mode & 0xf00) << (25 - 8));
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   depth = MAX2(mt->base.base.array_size, mt->base.base.depth0);
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mt->base.base.array_size > 1) {
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* there doesn't seem to be a base layer field in TIC */
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      address += view->pipe.u.tex.first_layer * mt->layer_stride;
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tic[1] = address;
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tic[2] |= address >> 32;
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (mt->base.base.target) {
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEXTURE_1D:
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[2] |= NV50_TIC_2_TARGET_1D;
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* case PIPE_TEXTURE_2D_MS: */
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEXTURE_2D:
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[2] |= NV50_TIC_2_TARGET_2D;
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEXTURE_RECT:
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[2] |= NV50_TIC_2_TARGET_RECT;
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEXTURE_3D:
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[2] |= NV50_TIC_2_TARGET_3D;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEXTURE_CUBE:
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      depth /= 6;
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (depth > 1)
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tic[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY;
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tic[2] |= NV50_TIC_2_TARGET_CUBE;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEXTURE_1D_ARRAY:
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[2] |= NV50_TIC_2_TARGET_1D_ARRAY;
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* case PIPE_TEXTURE_2D_ARRAY_MS: */
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEXTURE_2D_ARRAY:
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[2] |= NV50_TIC_2_TARGET_2D_ARRAY;
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      NOUVEAU_ERR("invalid texture target: %d\n", mt->base.base.target);
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mt->base.base.target == PIPE_BUFFER)
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[3] = mt->base.base.width0;
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[3] = 0x00300000;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tic[4] = (1 << 31) | (mt->base.base.width0 << mt->ms_x);
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tic[5] = (mt->base.base.height0 << mt->ms_y) & 0xffff;
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tic[5] |= depth << 16;
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tic[5] |= mt->base.base.last_level << 28;
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tic[6] = (mt->ms_x > 1) ? 0x88000000 : 0x03000000; /* sampling points */
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level;
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mt->base.base.target == PIPE_TEXTURE_2D_MS ||
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       mt->base.base.target == PIPE_TEXTURE_2D_ARRAY_MS)
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tic[7] |= mt->ms_mode << 12;
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   */
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &view->pipe;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnvc0_validate_tic(struct nvc0_context *nvc0, int s)
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t commands[32];
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_bo *txc = nvc0->screen->txc;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned n = 0;
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean need_flush = FALSE;
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < nvc0->num_textures[s]; ++i) {
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]);
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct nv04_resource *res;
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const boolean dirty = !!(nvc0->textures_dirty[s] & (1 << i));
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!tic) {
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (dirty)
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            commands[n++] = (i << 1) | 0;
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      res = nv04_resource(tic->pipe.texture);
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (tic->id < 0) {
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_SPACE(push, 17);
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATAh(push, txc->offset + (tic->id * 32));
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, txc->offset + (tic->id * 32));
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, 32);
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, 1);
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, 0x100111);
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NIC0(push, NVC0_M2MF(DATA), 8);
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATAp(push, &tic->tic[0], 8);
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         need_flush = TRUE;
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, (tic->id << 4) | 1);
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      res->status |=  NOUVEAU_BUFFER_STATUS_GPU_READING;
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!dirty)
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      commands[n++] = (tic->id << 9) | (i << 1) | 1;
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BCTX_REFN(nvc0->bufctx_3d, TEX(s, i), res, RD);
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (; i < nvc0->state.num_textures[s]; ++i)
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      commands[n++] = (i << 1) | 0;
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nvc0->state.num_textures[s] = nvc0->num_textures[s];
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (n) {
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NIC0(push, NVC0_3D(BIND_TIC(s)), n);
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAp(push, commands, n);
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nvc0->textures_dirty[s] = 0;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return need_flush;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnve4_validate_tic(struct nvc0_context *nvc0, unsigned s)
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_bo *txc = nvc0->screen->txc;
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean need_flush = FALSE;
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < nvc0->num_textures[s]; ++i) {
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]);
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct nv04_resource *res;
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const boolean dirty = !!(nvc0->textures_dirty[s] & (1 << i));
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!tic) {
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         nvc0->tex_handles[s][i] |= NVE4_TIC_ENTRY_INVALID;
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      res = nv04_resource(tic->pipe.texture);
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (tic->id < 0) {
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_SPACE(push, 16);
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NVC0(push, NVE4_P2MF(DST_ADDRESS_HIGH), 2);
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATAh(push, txc->offset + (tic->id * 32));
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, txc->offset + (tic->id * 32));
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NVC0(push, NVE4_P2MF(LINE_LENGTH_IN), 2);
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, 32);
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, 1);
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_1IC0(push, NVE4_P2MF(EXEC), 9);
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, 0x1001);
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATAp(push, &tic->tic[0], 8);
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         need_flush = TRUE;
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, (tic->id << 4) | 1);
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      res->status |=  NOUVEAU_BUFFER_STATUS_GPU_READING;
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->tex_handles[s][i] &= ~NVE4_TIC_ENTRY_INVALID;
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->tex_handles[s][i] |= tic->id;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dirty)
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BCTX_REFN(nvc0->bufctx_3d, TEX(s, i), res, RD);
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (; i < nvc0->state.num_textures[s]; ++i)
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->tex_handles[s][i] |= NVE4_TIC_ENTRY_INVALID;
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nvc0->state.num_textures[s] = nvc0->num_textures[s];
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return need_flush;
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid nvc0_validate_textures(struct nvc0_context *nvc0)
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean need_flush;
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) {
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_flush  = nve4_validate_tic(nvc0, 0);
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_flush |= nve4_validate_tic(nvc0, 3);
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_flush |= nve4_validate_tic(nvc0, 4);
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_flush  = nvc0_validate_tic(nvc0, 0);
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_flush |= nvc0_validate_tic(nvc0, 3);
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_flush |= nvc0_validate_tic(nvc0, 4);
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_flush) {
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TIC_FLUSH), 1);
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (nvc0->base.pushbuf, 0);
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnvc0_validate_tsc(struct nvc0_context *nvc0, int s)
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t commands[16];
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned n = 0;
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean need_flush = FALSE;
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < nvc0->num_samplers[s]; ++i) {
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]);
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!(nvc0->samplers_dirty[s] & (1 << i)))
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!tsc) {
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         commands[n++] = (i << 4) | 0;
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (tsc->id < 0) {
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc);
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->txc,
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               65536 + tsc->id * 32, NOUVEAU_BO_VRAM,
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               32, tsc->tsc);
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         need_flush = TRUE;
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      commands[n++] = (tsc->id << 12) | (i << 4) | 1;
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (; i < nvc0->state.num_samplers[s]; ++i)
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      commands[n++] = (i << 4) | 0;
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nvc0->state.num_samplers[s] = nvc0->num_samplers[s];
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (n) {
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NIC0(push, NVC0_3D(BIND_TSC(s)), n);
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAp(push, commands, n);
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nvc0->samplers_dirty[s] = 0;
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return need_flush;
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnve4_validate_tsc(struct nvc0_context *nvc0, int s)
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_bo *txc = nvc0->screen->txc;
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean need_flush = FALSE;
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < nvc0->num_samplers[s]; ++i) {
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]);
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!tsc) {
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         nvc0->tex_handles[s][i] |= NVE4_TSC_ENTRY_INVALID;
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (tsc->id < 0) {
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc);
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_SPACE(push, 16);
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NVC0(push, NVE4_P2MF(DST_ADDRESS_HIGH), 2);
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATAh(push, txc->offset + 65536 + (tsc->id * 32));
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, txc->offset + 65536 + (tsc->id * 32));
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NVC0(push, NVE4_P2MF(LINE_LENGTH_IN), 2);
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, 32);
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, 1);
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_1IC0(push, NVE4_P2MF(EXEC), 9);
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, 0x1001);
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATAp(push, &tsc->tsc[0], 8);
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         need_flush = TRUE;
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->tex_handles[s][i] &= ~NVE4_TSC_ENTRY_INVALID;
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->tex_handles[s][i] |= tsc->id << 20;
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (; i < nvc0->state.num_samplers[s]; ++i)
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->tex_handles[s][i] |= NVE4_TSC_ENTRY_INVALID;
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nvc0->state.num_samplers[s] = nvc0->num_samplers[s];
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return need_flush;
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid nvc0_validate_samplers(struct nvc0_context *nvc0)
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean need_flush;
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) {
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_flush  = nve4_validate_tsc(nvc0, 0);
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_flush |= nve4_validate_tsc(nvc0, 3);
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_flush |= nve4_validate_tsc(nvc0, 4);
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_flush  = nvc0_validate_tsc(nvc0, 0);
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_flush |= nvc0_validate_tsc(nvc0, 3);
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_flush |= nvc0_validate_tsc(nvc0, 4);
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_flush) {
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TSC_FLUSH), 1);
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (nvc0->base.pushbuf, 0);
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Upload the "diagonal" entries for the possible texture sources ($t == $s).
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * At some point we might want to get a list of the combinations used by a
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * shader and fill in those entries instead of having it extract the handles.
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnve4_set_tex_handles(struct nvc0_context *nvc0)
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint64_t address;
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned s;
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (nvc0->screen->base.class_3d < NVE4_3D_CLASS)
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   address = nvc0->screen->uniform_bo->offset + (5 << 16);
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (s = 0; s < 5; ++s, address += (1 << 9)) {
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      uint32_t dirty = nvc0->textures_dirty[s] | nvc0->samplers_dirty[s];
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!dirty)
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, 512);
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAh(push, address);
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, address);
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      do {
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         int i = ffs(dirty) - 1;
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dirty &= ~(1 << i);
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NVC0(push, NVC0_3D(CB_POS), 2);
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, (8 + i) * 4);
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, nvc0->tex_handles[s][i]);
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } while (dirty);
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->textures_dirty[s] = 0;
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->samplers_dirty[s] = 0;
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
498