2 * Copyright 2008 Ben Skeggs
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 #include "nv50_context.h"
24 #include "nv50_resource.h"
25 #include "nv50_texture.xml.h"
26 #include "nv50_defs.xml.h"
28 #include "util/u_format.h"
30 static INLINE
uint32_t
31 nv50_tic_swizzle(uint32_t tc
, unsigned swz
)
34 case PIPE_SWIZZLE_RED
:
35 return (tc
& NV50_TIC_0_MAPR__MASK
) >> NV50_TIC_0_MAPR__SHIFT
;
36 case PIPE_SWIZZLE_GREEN
:
37 return (tc
& NV50_TIC_0_MAPG__MASK
) >> NV50_TIC_0_MAPG__SHIFT
;
38 case PIPE_SWIZZLE_BLUE
:
39 return (tc
& NV50_TIC_0_MAPB__MASK
) >> NV50_TIC_0_MAPB__SHIFT
;
40 case PIPE_SWIZZLE_ALPHA
:
41 return (tc
& NV50_TIC_0_MAPA__MASK
) >> NV50_TIC_0_MAPA__SHIFT
;
42 case PIPE_SWIZZLE_ONE
:
43 return NV50_TIC_MAP_ONE
;
44 case PIPE_SWIZZLE_ZERO
:
46 return NV50_TIC_MAP_ZERO
;
50 struct pipe_sampler_view
*
51 nv50_create_sampler_view(struct pipe_context
*pipe
,
52 struct pipe_resource
*texture
,
53 const struct pipe_sampler_view
*templ
)
55 const struct util_format_description
*desc
;
59 struct nv50_tic_entry
*view
;
60 struct nv50_miptree
*mt
= nv50_miptree(texture
);
62 view
= MALLOC_STRUCT(nv50_tic_entry
);
67 view
->pipe
.reference
.count
= 1;
68 view
->pipe
.texture
= NULL
;
69 view
->pipe
.context
= pipe
;
73 pipe_resource_reference(&view
->pipe
.texture
, texture
);
77 desc
= util_format_description(mt
->base
.base
.format
);
81 tic
[0] = nv50_format_table
[view
->pipe
.format
].tic
;
83 swz
[0] = nv50_tic_swizzle(tic
[0], view
->pipe
.swizzle_r
);
84 swz
[1] = nv50_tic_swizzle(tic
[0], view
->pipe
.swizzle_g
);
85 swz
[2] = nv50_tic_swizzle(tic
[0], view
->pipe
.swizzle_b
);
86 swz
[3] = nv50_tic_swizzle(tic
[0], view
->pipe
.swizzle_a
);
87 tic
[0] = (tic
[0] & ~NV50_TIC_0_SWIZZLE__MASK
) |
88 (swz
[0] << NV50_TIC_0_MAPR__SHIFT
) |
89 (swz
[1] << NV50_TIC_0_MAPG__SHIFT
) |
90 (swz
[2] << NV50_TIC_0_MAPB__SHIFT
) |
91 (swz
[3] << NV50_TIC_0_MAPA__SHIFT
);
93 /* tic[1] = mt->base.bo->offset; */
94 tic
[2] = /* mt->base.bo->offset >> 32 */ 0;
96 tic
[2] |= 0x10001000 | /* NV50_TIC_2_NO_BORDER */ 0x40000000;
98 if (desc
->colorspace
== UTIL_FORMAT_COLORSPACE_SRGB
)
99 tic
[2] |= NV50_TIC_2_COLORSPACE_SRGB
;
101 if (mt
->base
.base
.target
!= PIPE_TEXTURE_RECT
)
102 tic
[2] |= NV50_TIC_2_NORMALIZED_COORDS
;
105 ((mt
->base
.bo
->tile_mode
& 0x0f) << (22 - 0)) |
106 ((mt
->base
.bo
->tile_mode
& 0xf0) << (25 - 4));
108 depth
= MAX2(mt
->base
.base
.array_size
, mt
->base
.base
.depth0
);
110 switch (mt
->base
.base
.target
) {
111 case PIPE_TEXTURE_1D
:
112 tic
[2] |= NV50_TIC_2_TARGET_1D
;
114 case PIPE_TEXTURE_2D
:
115 tic
[2] |= NV50_TIC_2_TARGET_2D
;
117 case PIPE_TEXTURE_RECT
:
118 tic
[2] |= NV50_TIC_2_TARGET_RECT
;
120 case PIPE_TEXTURE_3D
:
121 tic
[2] |= NV50_TIC_2_TARGET_3D
;
123 case PIPE_TEXTURE_CUBE
:
126 tic
[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY
;
128 tic
[2] |= NV50_TIC_2_TARGET_CUBE
;
130 case PIPE_TEXTURE_1D_ARRAY
:
131 tic
[2] |= NV50_TIC_2_TARGET_1D_ARRAY
;
133 case PIPE_TEXTURE_2D_ARRAY
:
134 tic
[2] |= NV50_TIC_2_TARGET_2D_ARRAY
;
137 tic
[2] |= NV50_TIC_2_TARGET_BUFFER
| /* NV50_TIC_2_LINEAR */ (1 << 18);
139 NOUVEAU_ERR("invalid texture target: %d\n", mt
->base
.base
.target
);
143 if (mt
->base
.base
.target
== PIPE_BUFFER
)
144 tic
[3] = mt
->base
.base
.width0
;
148 tic
[4] = (1 << 31) | mt
->base
.base
.width0
;
150 tic
[5] = mt
->base
.base
.height0
& 0xffff;
151 tic
[5] |= depth
<< 16;
152 tic
[5] |= mt
->base
.base
.last_level
<< 28;
156 tic
[7] = (view
->pipe
.u
.tex
.last_level
<< 4) | view
->pipe
.u
.tex
.first_level
;
162 nv50_validate_tic(struct nv50_context
*nv50
, int s
)
164 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
165 struct nouveau_bo
*txc
= nv50
->screen
->txc
;
167 boolean need_flush
= FALSE
;
169 for (i
= 0; i
< nv50
->num_textures
[s
]; ++i
) {
170 struct nv50_tic_entry
*tic
= nv50_tic_entry(nv50
->textures
[s
][i
]);
171 struct nv50_resource
*res
;
174 BEGIN_RING(chan
, RING_3D(BIND_TIC(s
)), 1);
175 OUT_RING (chan
, (i
<< 1) | 0);
178 res
= &nv50_miptree(tic
->pipe
.texture
)->base
;
181 tic
->id
= nv50_screen_tic_alloc(nv50
->screen
, tic
);
183 MARK_RING (chan
, 24 + 8, 4);
184 BEGIN_RING(chan
, RING_2D(DST_FORMAT
), 2);
185 OUT_RING (chan
, NV50_SURFACE_FORMAT_R8_UNORM
);
187 BEGIN_RING(chan
, RING_2D(DST_PITCH
), 5);
188 OUT_RING (chan
, 262144);
189 OUT_RING (chan
, 65536);
191 OUT_RELOCh(chan
, txc
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
192 OUT_RELOCl(chan
, txc
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
193 BEGIN_RING(chan
, RING_2D(SIFC_BITMAP_ENABLE
), 2);
195 OUT_RING (chan
, NV50_SURFACE_FORMAT_R8_UNORM
);
196 BEGIN_RING(chan
, RING_2D(SIFC_WIDTH
), 10);
204 OUT_RING (chan
, tic
->id
* 32);
207 BEGIN_RING_NI(chan
, RING_2D(SIFC_DATA
), 8);
208 OUT_RING (chan
, tic
->tic
[0]);
209 OUT_RELOCl(chan
, res
->bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
210 OUT_RELOC (chan
, res
->bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
|
211 NOUVEAU_BO_HIGH
| NOUVEAU_BO_OR
, tic
->tic
[2], tic
->tic
[2]);
212 OUT_RINGp (chan
, &tic
->tic
[3], 5);
216 nv50
->screen
->tic
.lock
[tic
->id
/ 32] |= 1 << (tic
->id
% 32);
218 nv50_bufctx_add_resident(nv50
, NV50_BUFCTX_TEXTURES
, res
,
219 NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
221 BEGIN_RING(chan
, RING_3D(BIND_TIC(s
)), 1);
222 OUT_RING (chan
, (tic
->id
<< 9) | (i
<< 1) | 1);
224 for (; i
< nv50
->state
.num_textures
[s
]; ++i
) {
225 BEGIN_RING(chan
, RING_3D(BIND_TIC(s
)), 1);
226 OUT_RING (chan
, (i
<< 1) | 0);
228 nv50
->state
.num_textures
[s
] = nv50
->num_textures
[s
];
233 void nv50_validate_textures(struct nv50_context
*nv50
)
237 need_flush
= nv50_validate_tic(nv50
, 0);
238 need_flush
|= nv50_validate_tic(nv50
, 2);
241 BEGIN_RING(nv50
->screen
->base
.channel
, RING_3D(TIC_FLUSH
), 1);
242 OUT_RING (nv50
->screen
->base
.channel
, 0);
247 nv50_validate_tsc(struct nv50_context
*nv50
, int s
)
249 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
251 boolean need_flush
= FALSE
;
253 for (i
= 0; i
< nv50
->num_samplers
[s
]; ++i
) {
254 struct nv50_tsc_entry
*tsc
= nv50_tsc_entry(nv50
->samplers
[s
][i
]);
257 BEGIN_RING(chan
, RING_3D(BIND_TSC(s
)), 1);
258 OUT_RING (chan
, (i
<< 4) | 0);
262 tsc
->id
= nv50_screen_tsc_alloc(nv50
->screen
, tsc
);
264 nv50_sifc_linear_u8(nv50
, nv50
->screen
->txc
, NOUVEAU_BO_VRAM
,
265 65536 + tsc
->id
* 32, 32, tsc
->tsc
);
268 nv50
->screen
->tsc
.lock
[tsc
->id
/ 32] |= 1 << (tsc
->id
% 32);
270 BEGIN_RING(chan
, RING_3D(BIND_TSC(s
)), 1);
271 OUT_RING (chan
, (tsc
->id
<< 12) | (i
<< 4) | 1);
273 for (; i
< nv50
->state
.num_samplers
[s
]; ++i
) {
274 BEGIN_RING(chan
, RING_3D(BIND_TSC(s
)), 1);
275 OUT_RING (chan
, (i
<< 4) | 0);
277 nv50
->state
.num_samplers
[s
] = nv50
->num_samplers
[s
];
282 void nv50_validate_samplers(struct nv50_context
*nv50
)
286 need_flush
= nv50_validate_tsc(nv50
, 0);
287 need_flush
|= nv50_validate_tsc(nv50
, 2);
290 BEGIN_RING(nv50
->screen
->base
.channel
, RING_3D(TSC_FLUSH
), 1);
291 OUT_RING (nv50
->screen
->base
.channel
, 0);