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