1 #include "util/u_format.h"
2 #include "nvfx_context.h"
4 #include "nvfx_resource.h"
7 nv40_sampler_state_init(struct pipe_context
*pipe
,
8 struct nvfx_sampler_state
*ps
,
9 const struct pipe_sampler_state
*cso
)
14 if (cso
->max_anisotropy
>= 2) {
15 /* no idea, binary driver sets it, works without it.. meh.. */
18 if (cso
->max_anisotropy
>= 16)
19 ps
->en
|= NV40_3D_TEX_ENABLE_ANISO_16X
;
20 else if (cso
->max_anisotropy
>= 12)
21 ps
->en
|= NV40_3D_TEX_ENABLE_ANISO_12X
;
22 else if (cso
->max_anisotropy
>= 10)
23 ps
->en
|= NV40_3D_TEX_ENABLE_ANISO_10X
;
24 else if (cso
->max_anisotropy
>= 8)
25 ps
->en
|= NV40_3D_TEX_ENABLE_ANISO_8X
;
26 else if (cso
->max_anisotropy
>= 6)
27 ps
->en
|= NV40_3D_TEX_ENABLE_ANISO_6X
;
28 else if (cso
->max_anisotropy
>= 4)
29 ps
->en
|= NV40_3D_TEX_ENABLE_ANISO_4X
;
31 ps
->en
|= NV40_3D_TEX_ENABLE_ANISO_2X
;
35 limit
= CLAMP(cso
->lod_bias
, -16.0, 15.0 + (255.0 / 256.0));
37 ps
->filt
|= (int)(cso
->lod_bias
* 256.0) & 0x1fff;
39 ps
->max_lod
= (int)(CLAMP(cso
->max_lod
, 0.0, 15.0 + (255.0 / 256.0)) * 256.0);
40 ps
->min_lod
= (int)(CLAMP(cso
->min_lod
, 0.0, 15.0 + (255.0 / 256.0)) * 256.0);
42 ps
->en
|= NV40_3D_TEX_ENABLE_ENABLE
;
46 nv40_sampler_view_init(struct pipe_context
*pipe
,
47 struct nvfx_sampler_view
*sv
)
49 struct pipe_resource
* pt
= sv
->base
.texture
;
50 struct nvfx_miptree
* mt
= (struct nvfx_miptree
*)pt
;
51 struct nvfx_texture_format
*tf
= &nvfx_texture_formats
[sv
->base
.format
];
53 unsigned level
= pt
->target
== PIPE_TEXTURE_CUBE
? 0 : sv
->base
.u
.tex
.first_level
;
54 assert(tf
->fmt
[4] >= 0);
58 if(pt
->target
== PIPE_TEXTURE_CUBE
)
59 txf
|= ((pt
->last_level
+ 1) << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT
);
61 txf
|= (((sv
->base
.u
.tex
.last_level
- sv
->base
.u
.tex
.first_level
) + 1) << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT
);
63 if (!mt
->linear_pitch
)
64 sv
->u
.nv40
.npot_size2
= 0;
66 sv
->u
.nv40
.npot_size2
= mt
->linear_pitch
;
67 txf
|= NV40_3D_TEX_FORMAT_LINEAR
;
70 sv
->u
.nv40
.fmt
[0] = tf
->fmt
[4] | txf
;
71 sv
->u
.nv40
.fmt
[1] = tf
->fmt
[5] | txf
;
73 sv
->u
.nv40
.npot_size2
|= (u_minify(pt
->depth0
, level
) << NV40_3D_TEX_SIZE1_DEPTH__SHIFT
);
75 sv
->lod_offset
= (sv
->base
.u
.tex
.first_level
- level
) * 256;
76 sv
->max_lod_limit
= (sv
->base
.u
.tex
.last_level
- level
) * 256;
80 nv40_fragtex_set(struct nvfx_context
*nvfx
, int unit
)
82 struct nouveau_channel
* chan
= nvfx
->screen
->base
.channel
;
83 struct nouveau_grobj
*eng3d
= nvfx
->screen
->eng3d
;
84 struct nvfx_sampler_state
*ps
= nvfx
->tex_sampler
[unit
];
85 struct nvfx_sampler_view
* sv
= (struct nvfx_sampler_view
*)nvfx
->fragment_sampler_views
[unit
];
86 struct nouveau_bo
*bo
= ((struct nvfx_miptree
*)sv
->base
.texture
)->base
.bo
;
87 unsigned tex_flags
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
;
89 unsigned max_lod
= MIN2(ps
->max_lod
+ sv
->lod_offset
, sv
->max_lod_limit
);
90 unsigned min_lod
= MIN2(ps
->min_lod
+ sv
->lod_offset
, max_lod
);
92 txf
= sv
->u
.nv40
.fmt
[ps
->compare
] | ps
->fmt
;
94 MARK_RING(chan
, 11, 2);
95 BEGIN_RING(chan
, eng3d
, NV30_3D_TEX_OFFSET(unit
), 8);
96 OUT_RELOC(chan
, bo
, sv
->offset
, tex_flags
| NOUVEAU_BO_LOW
, 0, 0);
97 OUT_RELOC(chan
, bo
, txf
, tex_flags
| NOUVEAU_BO_OR
,
98 NV30_3D_TEX_FORMAT_DMA0
, NV30_3D_TEX_FORMAT_DMA1
);
99 OUT_RING(chan
, (ps
->wrap
& sv
->wrap_mask
) | sv
->wrap
);
100 OUT_RING(chan
, ps
->en
| (min_lod
<< 19) | (max_lod
<< 7));
101 OUT_RING(chan
, sv
->swizzle
);
102 OUT_RING(chan
, ps
->filt
| sv
->filt
);
103 OUT_RING(chan
, sv
->npot_size
);
104 OUT_RING(chan
, ps
->bcol
);
105 BEGIN_RING(chan
, eng3d
, NV40_3D_TEX_SIZE1(unit
), 1);
106 OUT_RING(chan
, sv
->u
.nv40
.npot_size2
);
108 nvfx
->hw_txf
[unit
] = txf
;
109 nvfx
->hw_samplers
|= (1 << unit
);