1 #include "util/u_format.h"
3 #include "nvfx_context.h"
5 #include "nvfx_resource.h"
8 nv30_sampler_state_init(struct pipe_context
*pipe
,
9 struct nvfx_sampler_state
*ps
,
10 const struct pipe_sampler_state
*cso
)
14 if (cso
->max_anisotropy
>= 2)
16 if (cso
->max_anisotropy
>= 8)
17 ps
->en
|= NV30_3D_TEX_ENABLE_ANISO_8X
;
18 else if (cso
->max_anisotropy
>= 4)
19 ps
->en
|= NV30_3D_TEX_ENABLE_ANISO_4X
;
20 else if (cso
->max_anisotropy
>= 2)
21 ps
->en
|= NV30_3D_TEX_ENABLE_ANISO_2X
;
24 limit
= CLAMP(cso
->lod_bias
, -16.0, 15.0 + (255.0 / 256.0));
25 ps
->filt
|= (int)(cso
->lod_bias
* 256.0) & 0x1fff;
27 ps
->max_lod
= (int)CLAMP(cso
->max_lod
, 0.0, 15.0);
28 ps
->min_lod
= (int)CLAMP(cso
->min_lod
, 0.0, 15.0);
30 ps
->en
|= NV30_3D_TEX_ENABLE_ENABLE
;
34 nv30_sampler_view_init(struct pipe_context
*pipe
,
35 struct nvfx_sampler_view
*sv
)
37 struct pipe_resource
* pt
= sv
->base
.texture
;
38 struct nvfx_texture_format
*tf
= &nvfx_texture_formats
[sv
->base
.format
];
40 unsigned level
= pt
->target
== PIPE_TEXTURE_CUBE
? 0 : sv
->base
.u
.tex
.first_level
;
42 assert(tf
->fmt
[0] >= 0);
45 txf
|= (level
!= sv
->base
.u
.tex
.last_level
? NV30_3D_TEX_FORMAT_MIPMAP
: 0);
46 txf
|= util_logbase2(u_minify(pt
->width0
, level
)) << NV30_3D_TEX_FORMAT_BASE_SIZE_U__SHIFT
;
47 txf
|= util_logbase2(u_minify(pt
->height0
, level
)) << NV30_3D_TEX_FORMAT_BASE_SIZE_V__SHIFT
;
48 txf
|= util_logbase2(u_minify(pt
->depth0
, level
)) << NV30_3D_TEX_FORMAT_BASE_SIZE_W__SHIFT
;
51 sv
->u
.nv30
.fmt
[0] = tf
->fmt
[0] | txf
;
52 sv
->u
.nv30
.fmt
[1] = tf
->fmt
[1] | txf
;
53 sv
->u
.nv30
.fmt
[2] = tf
->fmt
[2] | txf
;
54 sv
->u
.nv30
.fmt
[3] = tf
->fmt
[3] | txf
;
56 sv
->swizzle
|= (nvfx_subresource_pitch(pt
, 0) << NV30_3D_TEX_SWIZZLE_RECT_PITCH__SHIFT
);
58 if(pt
->height0
<= 1 || util_format_is_compressed(sv
->base
.format
))
61 sv
->u
.nv30
.rect
= !!(pt
->flags
& NVFX_RESOURCE_FLAG_LINEAR
);
63 sv
->lod_offset
= sv
->base
.u
.tex
.first_level
- level
;
64 sv
->max_lod_limit
= sv
->base
.u
.tex
.last_level
- level
;
68 nv30_fragtex_set(struct nvfx_context
*nvfx
, int unit
)
70 struct nvfx_sampler_state
*ps
= nvfx
->tex_sampler
[unit
];
71 struct nvfx_sampler_view
* sv
= (struct nvfx_sampler_view
*)nvfx
->fragment_sampler_views
[unit
];
72 struct nouveau_bo
*bo
= ((struct nvfx_miptree
*)sv
->base
.texture
)->base
.bo
;
73 struct nouveau_channel
* chan
= nvfx
->screen
->base
.channel
;
74 struct nouveau_grobj
*eng3d
= nvfx
->screen
->eng3d
;
76 unsigned tex_flags
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
;
78 unsigned max_lod
= MIN2(ps
->max_lod
+ sv
->lod_offset
, sv
->max_lod_limit
);
79 unsigned min_lod
= MIN2(ps
->min_lod
+ sv
->lod_offset
, max_lod
) ;
81 if(sv
->u
.nv30
.rect
< 0)
83 /* in the case of compressed or 1D textures, we can get away with this,
84 * since the layout is the same
90 static boolean warned
= FALSE
;
91 if( !!ps
->fmt
!= sv
->u
.nv30
.rect
&& !warned
) {
94 "Unimplemented: coordinate normalization mismatch. Possible reasons:\n"
95 "1. ARB_texture_non_power_of_two is being used despite the fact it isn't supported\n"
96 "2. The state tracker is not using the appropriate coordinate normalization\n"
97 "3. The state tracker is not supported\n");
100 use_rect
= sv
->u
.nv30
.rect
;
103 txf
= sv
->u
.nv30
.fmt
[ps
->compare
+ (use_rect
? 2 : 0)];
105 MARK_RING(chan
, 9, 2);
106 BEGIN_RING(chan
, eng3d
, NV30_3D_TEX_OFFSET(unit
), 8);
107 OUT_RELOC(chan
, bo
, sv
->offset
, tex_flags
| NOUVEAU_BO_LOW
, 0, 0);
108 OUT_RELOC(chan
, bo
, txf
,
109 tex_flags
| NOUVEAU_BO_OR
,
110 NV30_3D_TEX_FORMAT_DMA0
, NV30_3D_TEX_FORMAT_DMA1
);
111 OUT_RING(chan
, (ps
->wrap
& sv
->wrap_mask
) | sv
->wrap
);
112 OUT_RING(chan
, ps
->en
| (min_lod
<< NV30_3D_TEX_ENABLE_MIPMAP_MIN_LOD__SHIFT
) | (max_lod
<< NV30_3D_TEX_ENABLE_MIPMAP_MAX_LOD__SHIFT
));
113 OUT_RING(chan
, sv
->swizzle
);
114 OUT_RING(chan
, ps
->filt
| sv
->filt
);
115 OUT_RING(chan
, sv
->npot_size
);
116 OUT_RING(chan
, ps
->bcol
);
118 nvfx
->hw_txf
[unit
] = txf
;
119 nvfx
->hw_samplers
|= (1 << unit
);