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 "nvc0_context.h"
24 #include "nvc0_resource.h"
25 #include "nv50_texture.xml.h"
27 #include "util/u_format.h"
29 static INLINE
uint32_t
30 nv50_tic_swizzle(uint32_t tc
, unsigned swz
)
33 case PIPE_SWIZZLE_RED
:
34 return (tc
& NV50_TIC_0_MAPR__MASK
) >> NV50_TIC_0_MAPR__SHIFT
;
35 case PIPE_SWIZZLE_GREEN
:
36 return (tc
& NV50_TIC_0_MAPG__MASK
) >> NV50_TIC_0_MAPG__SHIFT
;
37 case PIPE_SWIZZLE_BLUE
:
38 return (tc
& NV50_TIC_0_MAPB__MASK
) >> NV50_TIC_0_MAPB__SHIFT
;
39 case PIPE_SWIZZLE_ALPHA
:
40 return (tc
& NV50_TIC_0_MAPA__MASK
) >> NV50_TIC_0_MAPA__SHIFT
;
41 case PIPE_SWIZZLE_ONE
:
42 return NV50_TIC_MAP_ONE
;
43 case PIPE_SWIZZLE_ZERO
:
45 return NV50_TIC_MAP_ZERO
;
49 struct pipe_sampler_view
*
50 nvc0_create_sampler_view(struct pipe_context
*pipe
,
51 struct pipe_resource
*texture
,
52 const struct pipe_sampler_view
*templ
)
54 const struct util_format_description
*desc
;
57 struct nvc0_tic_entry
*view
;
58 struct nvc0_miptree
*mt
= nvc0_miptree(texture
);
60 view
= MALLOC_STRUCT(nvc0_tic_entry
);
65 view
->pipe
.reference
.count
= 1;
66 view
->pipe
.texture
= NULL
;
67 view
->pipe
.context
= pipe
;
71 pipe_resource_reference(&view
->pipe
.texture
, texture
);
75 desc
= util_format_description(mt
->base
.base
.format
);
79 tic
[0] = nvc0_format_table
[view
->pipe
.format
].tic
;
81 swz
[0] = nv50_tic_swizzle(tic
[0], view
->pipe
.swizzle_r
);
82 swz
[1] = nv50_tic_swizzle(tic
[0], view
->pipe
.swizzle_g
);
83 swz
[2] = nv50_tic_swizzle(tic
[0], view
->pipe
.swizzle_b
);
84 swz
[3] = nv50_tic_swizzle(tic
[0], view
->pipe
.swizzle_a
);
85 tic
[0] = (tic
[0] & ~NV50_TIC_0_SWIZZLE__MASK
) |
86 (swz
[0] << NV50_TIC_0_MAPR__SHIFT
) |
87 (swz
[1] << NV50_TIC_0_MAPG__SHIFT
) |
88 (swz
[2] << NV50_TIC_0_MAPB__SHIFT
) |
89 (swz
[3] << NV50_TIC_0_MAPA__SHIFT
);
91 tic
[1] = nouveau_bo_gpu_address(mt
->base
.bo
);
92 tic
[2] = nouveau_bo_gpu_address(mt
->base
.bo
) >> 32;
94 tic
[2] |= 0x10001000 | /* NV50_TIC_2_NO_BORDER */ 0x40000000;
96 if (desc
->colorspace
== UTIL_FORMAT_COLORSPACE_SRGB
)
97 tic
[2] |= NV50_TIC_2_COLORSPACE_SRGB
;
99 if (mt
->base
.base
.target
!= PIPE_TEXTURE_RECT
)
100 tic
[2] |= NV50_TIC_2_NORMALIZED_COORDS
;
103 ((mt
->base
.bo
->tile_mode
& 0x0f0) << (22 - 4)) |
104 ((mt
->base
.bo
->tile_mode
& 0xf00) << (21 - 4));
106 switch (mt
->base
.base
.target
) {
107 case PIPE_TEXTURE_1D
:
108 tic
[2] |= NV50_TIC_2_TARGET_1D
;
110 case PIPE_TEXTURE_2D
:
111 tic
[2] |= NV50_TIC_2_TARGET_2D
;
113 case PIPE_TEXTURE_RECT
:
114 tic
[2] |= NV50_TIC_2_TARGET_RECT
;
116 case PIPE_TEXTURE_3D
:
117 tic
[2] |= NV50_TIC_2_TARGET_3D
;
119 case PIPE_TEXTURE_CUBE
:
120 tic
[2] |= NV50_TIC_2_TARGET_CUBE
;
123 tic
[2] |= NV50_TIC_2_TARGET_BUFFER
| /* NV50_TIC_2_LINEAR */ (1 << 18);
125 NOUVEAU_ERR("invalid texture target: %d\n", mt
->base
.base
.target
);
129 if (mt
->base
.base
.target
== PIPE_BUFFER
)
130 tic
[3] = mt
->base
.base
.width0
;
134 tic
[4] = (1 << 31) | mt
->base
.base
.width0
;
136 tic
[5] = mt
->base
.base
.height0
& 0xffff;
137 tic
[5] |= mt
->base
.base
.depth0
<< 16;
138 tic
[5] |= mt
->base
.base
.last_level
<< 28;
142 tic
[7] = (view
->pipe
.last_level
<< 4) | view
->pipe
.first_level
;
148 nvc0_validate_tic(struct nvc0_context
*nvc0
, int s
)
150 struct nouveau_channel
*chan
= nvc0
->screen
->base
.channel
;
152 boolean need_flush
= FALSE
;
154 for (i
= 0; i
< nvc0
->num_textures
[s
]; ++i
) {
155 struct nvc0_tic_entry
*tic
= nvc0_tic_entry(nvc0
->textures
[s
][i
]);
156 struct nvc0_resource
*res
;
159 BEGIN_RING(chan
, RING_3D(BIND_TIC(s
)), 1);
160 OUT_RING (chan
, (i
<< 1) | 0);
163 res
= &nvc0_miptree(tic
->pipe
.texture
)->base
;
166 tic
->id
= nvc0_screen_tic_alloc(nvc0
->screen
, tic
);
168 nvc0_m2mf_push_linear(nvc0
, nvc0
->screen
->txc
, NOUVEAU_BO_VRAM
,
169 tic
->id
* 32, 32, tic
->tic
);
172 nvc0
->screen
->tic
.lock
[tic
->id
/ 32] |= 1 << (tic
->id
% 32);
174 nvc0_bufctx_add_resident(nvc0
, NVC0_BUFCTX_TEXTURES
, res
,
175 NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
177 BEGIN_RING(chan
, RING_3D(BIND_TIC(s
)), 1);
178 OUT_RING (chan
, (tic
->id
<< 9) | (i
<< 1) | 1);
180 for (; i
< nvc0
->state
.num_textures
[s
]; ++i
) {
181 BEGIN_RING(chan
, RING_3D(BIND_TIC(s
)), 1);
182 OUT_RING (chan
, (i
<< 1) | 0);
184 nvc0
->state
.num_textures
[s
] = nvc0
->num_textures
[s
];
189 void nvc0_validate_textures(struct nvc0_context
*nvc0
)
193 nvc0_bufctx_reset(nvc0
, NVC0_BUFCTX_TEXTURES
);
195 need_flush
= nvc0_validate_tic(nvc0
, 0);
196 need_flush
|= nvc0_validate_tic(nvc0
, 4);
199 BEGIN_RING(nvc0
->screen
->base
.channel
, RING_3D(TIC_FLUSH
), 1);
200 OUT_RING (nvc0
->screen
->base
.channel
, 0);
205 nvc0_validate_tsc(struct nvc0_context
*nvc0
, int s
)
207 struct nouveau_channel
*chan
= nvc0
->screen
->base
.channel
;
209 boolean need_flush
= FALSE
;
211 for (i
= 0; i
< nvc0
->num_samplers
[s
]; ++i
) {
212 struct nvc0_tsc_entry
*tsc
= nvc0_tsc_entry(nvc0
->samplers
[s
][i
]);
215 BEGIN_RING(chan
, RING_3D(BIND_TSC(s
)), 1);
216 OUT_RING (chan
, (i
<< 4) | 0);
220 tsc
->id
= nvc0_screen_tsc_alloc(nvc0
->screen
, tsc
);
222 nvc0_m2mf_push_linear(nvc0
, nvc0
->screen
->txc
, NOUVEAU_BO_VRAM
,
223 65536 + tsc
->id
* 32, 32, tsc
->tsc
);
226 nvc0
->screen
->tsc
.lock
[tsc
->id
/ 32] |= 1 << (tsc
->id
% 32);
228 BEGIN_RING(chan
, RING_3D(BIND_TSC(s
)), 1);
229 OUT_RING (chan
, (tsc
->id
<< 12) | (i
<< 4) | 1);
231 for (; i
< nvc0
->state
.num_samplers
[s
]; ++i
) {
232 BEGIN_RING(chan
, RING_3D(BIND_TSC(s
)), 1);
233 OUT_RING (chan
, (i
<< 4) | 0);
235 nvc0
->state
.num_samplers
[s
] = nvc0
->num_samplers
[s
];
240 void nvc0_validate_samplers(struct nvc0_context
*nvc0
)
244 need_flush
= nvc0_validate_tsc(nvc0
, 0);
245 need_flush
|= nvc0_validate_tsc(nvc0
, 4);
248 BEGIN_RING(nvc0
->screen
->base
.channel
, RING_3D(TSC_FLUSH
), 1);
249 OUT_RING (nvc0
->screen
->base
.channel
, 0);