r300: Zero-initialize register for NV_vertex_program
[mesa.git] / src / gallium / drivers / nv20 / nv20_screen.c
1 #include "pipe/p_screen.h"
2
3 #include "nv20_context.h"
4 #include "nv20_screen.h"
5
6 static int
7 nv20_screen_get_param(struct pipe_screen *screen, int param)
8 {
9 switch (param) {
10 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
11 return 2;
12 case PIPE_CAP_NPOT_TEXTURES:
13 return 0;
14 case PIPE_CAP_TWO_SIDED_STENCIL:
15 return 0;
16 case PIPE_CAP_GLSL:
17 return 0;
18 case PIPE_CAP_S3TC:
19 return 0;
20 case PIPE_CAP_ANISOTROPIC_FILTER:
21 return 1;
22 case PIPE_CAP_POINT_SPRITE:
23 return 0;
24 case PIPE_CAP_MAX_RENDER_TARGETS:
25 return 1;
26 case PIPE_CAP_OCCLUSION_QUERY:
27 return 0;
28 case PIPE_CAP_TEXTURE_SHADOW_MAP:
29 return 0;
30 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
31 return 12;
32 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
33 return 0;
34 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
35 return 12;
36 case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
37 return 0;
38 case PIPE_CAP_TGSI_CONT_SUPPORTED:
39 return 0;
40 case PIPE_CAP_BLEND_EQUATION_SEPARATE:
41 return 0;
42 case NOUVEAU_CAP_HW_VTXBUF:
43 case NOUVEAU_CAP_HW_IDXBUF:
44 return 0;
45 default:
46 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
47 return 0;
48 }
49 }
50
51 static float
52 nv20_screen_get_paramf(struct pipe_screen *screen, int param)
53 {
54 switch (param) {
55 case PIPE_CAP_MAX_LINE_WIDTH:
56 case PIPE_CAP_MAX_LINE_WIDTH_AA:
57 return 10.0;
58 case PIPE_CAP_MAX_POINT_WIDTH:
59 case PIPE_CAP_MAX_POINT_WIDTH_AA:
60 return 64.0;
61 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
62 return 2.0;
63 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
64 return 4.0;
65 default:
66 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
67 return 0.0;
68 }
69 }
70
71 static boolean
72 nv20_screen_is_format_supported(struct pipe_screen *screen,
73 enum pipe_format format,
74 enum pipe_texture_target target,
75 unsigned tex_usage, unsigned geom_flags)
76 {
77 if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
78 switch (format) {
79 case PIPE_FORMAT_A8R8G8B8_UNORM:
80 case PIPE_FORMAT_R5G6B5_UNORM:
81 return TRUE;
82 default:
83 break;
84 }
85 } else
86 if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
87 switch (format) {
88 case PIPE_FORMAT_Z24S8_UNORM:
89 case PIPE_FORMAT_Z24X8_UNORM:
90 case PIPE_FORMAT_Z16_UNORM:
91 return TRUE;
92 default:
93 break;
94 }
95 } else {
96 switch (format) {
97 case PIPE_FORMAT_A8R8G8B8_UNORM:
98 case PIPE_FORMAT_A1R5G5B5_UNORM:
99 case PIPE_FORMAT_A4R4G4B4_UNORM:
100 case PIPE_FORMAT_R5G6B5_UNORM:
101 case PIPE_FORMAT_L8_UNORM:
102 case PIPE_FORMAT_A8_UNORM:
103 case PIPE_FORMAT_I8_UNORM:
104 return TRUE;
105 default:
106 break;
107 }
108 }
109
110 return FALSE;
111 }
112
113 static void
114 nv20_screen_destroy(struct pipe_screen *pscreen)
115 {
116 struct nv20_screen *screen = nv20_screen(pscreen);
117
118 nouveau_notifier_free(&screen->sync);
119 nouveau_grobj_free(&screen->kelvin);
120
121 FREE(pscreen);
122 }
123
124 static struct pipe_buffer *
125 nv20_surface_buffer(struct pipe_surface *surf)
126 {
127 struct nv20_miptree *mt = (struct nv20_miptree *)surf->texture;
128
129 return mt->buffer;
130 }
131
132 struct pipe_screen *
133 nv20_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
134 {
135 struct nv20_screen *screen = CALLOC_STRUCT(nv20_screen);
136 struct nouveau_channel *chan;
137 struct pipe_screen *pscreen;
138 unsigned kelvin_class = 0;
139 int ret;
140
141 if (!screen)
142 return NULL;
143 pscreen = &screen->base.base;
144
145 ret = nouveau_screen_init(&screen->base, dev);
146 if (ret) {
147 nv20_screen_destroy(pscreen);
148 return NULL;
149 }
150 chan = screen->base.channel;
151
152 pscreen->winsys = ws;
153 pscreen->destroy = nv20_screen_destroy;
154 pscreen->get_param = nv20_screen_get_param;
155 pscreen->get_paramf = nv20_screen_get_paramf;
156 pscreen->is_format_supported = nv20_screen_is_format_supported;
157
158 nv20_screen_init_miptree_functions(pscreen);
159 nv20_screen_init_transfer_functions(pscreen);
160
161 /* 3D object */
162 if (dev->chipset >= 0x25)
163 kelvin_class = NV25TCL;
164 else if (dev->chipset >= 0x20)
165 kelvin_class = NV20TCL;
166
167 if (!kelvin_class || dev->chipset >= 0x30) {
168 NOUVEAU_ERR("Unknown nv2x chipset: nv%02x\n", dev->chipset);
169 return NULL;
170 }
171
172 ret = nouveau_grobj_alloc(chan, 0xbeef0097, kelvin_class,
173 &screen->kelvin);
174 if (ret) {
175 NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
176 return FALSE;
177 }
178 BIND_RING(chan, screen->kelvin, 7);
179
180 /* 2D engine setup */
181 screen->eng2d = nv04_surface_2d_init(&screen->base);
182 screen->eng2d->buf = nv20_surface_buffer;
183
184 /* Notifier for sync purposes */
185 ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
186 if (ret) {
187 NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
188 nv20_screen_destroy(pscreen);
189 return NULL;
190 }
191
192 return pscreen;
193 }
194