r300_screen.c revision 9a20ef0a52f8c4efd7431ccd59e32efecdc33893
1/*
2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
3 *
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 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
22
23#include "r300_screen.h"
24
25/* Return the identifier behind whom the brave coders responsible for this
26 * amalgamation of code, sweat, and duct tape, routinely obscure their names.
27 *
28 * ...I should have just put "Corbin Simpson", but I'm not that cool.
29 *
30 * (Or egotistical. Yet.) */
31static const char* r300_get_vendor(struct pipe_screen* pscreen)
32{
33    return "X.Org R300 Project";
34}
35
36static const char* chip_families[] = {
37    "R300",
38    "R350",
39    "R360",
40    "RV350",
41    "RV370",
42    "RV380",
43    "R420",
44    "R423",
45    "R430",
46    "R480",
47    "R481",
48    "RV410",
49    "RS400",
50    "RC410",
51    "RS480",
52    "RS482",
53    "RS690",
54    "RS740",
55    "RV515",
56    "R520",
57    "RV530",
58    "R580",
59    "RV560",
60    "RV570"
61};
62
63static const char* r300_get_name(struct pipe_screen* pscreen)
64{
65    struct r300_screen* r300screen = r300_screen(pscreen);
66
67    return chip_families[r300screen->caps->family];
68}
69
70static int r300_get_param(struct pipe_screen* pscreen, int param)
71{
72    struct r300_screen* r300screen = r300_screen(pscreen);
73
74    switch (param) {
75        /* XXX cases marked "IN THEORY" are possible on the hardware,
76         * but haven't been implemented yet. */
77        case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
78            /* XXX I'm told this goes up to 16 */
79            return 8;
80        case PIPE_CAP_NPOT_TEXTURES:
81            /* IN THEORY */
82            return 0;
83        case PIPE_CAP_TWO_SIDED_STENCIL:
84            if (r300screen->caps->is_r500) {
85                return 1;
86            } else {
87                return 0;
88            }
89            return 0;
90        case PIPE_CAP_GLSL:
91            /* IN THEORY */
92            return 0;
93        case PIPE_CAP_S3TC:
94            /* IN THEORY */
95            return 0;
96        case PIPE_CAP_ANISOTROPIC_FILTER:
97            /* IN THEORY */
98            return 0;
99        case PIPE_CAP_POINT_SPRITE:
100            /* IN THEORY */
101            return 0;
102        case PIPE_CAP_MAX_RENDER_TARGETS:
103            return 4;
104        case PIPE_CAP_OCCLUSION_QUERY:
105            /* IN THEORY */
106            return 0;
107        case PIPE_CAP_TEXTURE_SHADOW_MAP:
108            /* IN THEORY */
109            return 0;
110        case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
111            if (r300screen->caps->is_r500) {
112                /* 13 == 4096x4096 */
113                return 13;
114            } else {
115                /* 12 == 2048x2048 */
116                return 12;
117            }
118        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
119            /* So, technically, the limit is the same as above, but some math
120             * shows why this is silly. Assuming RGBA, 4cpp, we can see that
121             * 4096*4096*4096 = 64.0 GiB exactly, so it's not exactly
122             * practical. However, if at some point a game really wants this,
123             * then we can remove this limit. */
124            if (r300screen->caps->is_r500) {
125                /* 9 == 256x256x256 */
126                return 9;
127            } else {
128                /* 8 == 128*128*128 */
129                return 8;
130            }
131        case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
132            if (r300screen->caps->is_r500) {
133                /* 13 == 4096x4096 */
134                return 13;
135            } else {
136                /* 12 == 2048x2048 */
137                return 12;
138            }
139        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
140            return 1;
141        case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
142            return 1;
143        case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
144            /* XXX guessing */
145            return 2;
146        default:
147            debug_printf("r300: Implementation error: Bad param %d\n",
148                param);
149            return 0;
150    }
151}
152
153static float r300_get_paramf(struct pipe_screen* pscreen, int param)
154{
155    switch (param) {
156        case PIPE_CAP_MAX_LINE_WIDTH:
157        case PIPE_CAP_MAX_LINE_WIDTH_AA:
158            /* XXX this is the biggest thing that will fit in that register.
159            * Perhaps the actual rendering limits are less? */
160            return 10922.0f;
161        case PIPE_CAP_MAX_POINT_WIDTH:
162        case PIPE_CAP_MAX_POINT_WIDTH_AA:
163            /* XXX this is the biggest thing that will fit in that register.
164             * Perhaps the actual rendering limits are less? */
165            return 10922.0f;
166        case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
167            return 16.0f;
168        case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
169            return 16.0f;
170        default:
171            debug_printf("r300: Implementation error: Bad paramf %d\n",
172                param);
173            return 0.0f;
174    }
175}
176
177/* XXX moar formats */
178static boolean check_tex_2d_format(enum pipe_format format)
179{
180    switch (format) {
181        case PIPE_FORMAT_A8R8G8B8_UNORM:
182        case PIPE_FORMAT_I8_UNORM:
183            return TRUE;
184        default:
185            debug_printf("r300: Warning: Got unknown format: %s, in %s\n",
186                pf_name(format), __FUNCTION__);
187            break;
188    }
189
190    return FALSE;
191}
192
193/* XXX moar targets */
194static boolean r300_is_format_supported(struct pipe_screen* pscreen,
195                                        enum pipe_format format,
196                                        enum pipe_texture_target target,
197                                        unsigned tex_usage,
198                                        unsigned geom_flags)
199{
200    switch (target) {
201        case PIPE_TEXTURE_2D:
202            return check_tex_2d_format(format);
203        default:
204            debug_printf("r300: Warning: Got unknown format target: %d\n",
205                format);
206            break;
207    }
208
209    return FALSE;
210}
211
212static void* r300_surface_map(struct pipe_screen* screen,
213                              struct pipe_surface* surface,
214                              unsigned flags)
215{
216    struct r300_texture* tex = (struct r300_texture*)surface->texture;
217    char* map = pipe_buffer_map(screen, tex->buffer, flags);
218
219    if (!map) {
220        return NULL;
221    }
222
223    return map + surface->offset;
224}
225
226static void r300_surface_unmap(struct pipe_screen* screen,
227                               struct pipe_surface* surface)
228{
229    struct r300_texture* tex = (struct r300_texture*)surface->texture;
230    pipe_buffer_unmap(screen, tex->buffer);
231}
232
233static void r300_destroy_screen(struct pipe_screen* pscreen)
234{
235    struct r300_screen* r300screen = r300_screen(pscreen);
236
237    FREE(r300screen->caps);
238    FREE(r300screen);
239}
240
241struct pipe_screen* r300_create_screen(struct pipe_winsys* winsys,
242                                       struct r300_winsys* r300_winsys)
243{
244    struct r300_screen* r300screen = CALLOC_STRUCT(r300_screen);
245    struct r300_capabilities* caps = CALLOC_STRUCT(r300_capabilities);
246
247    if (!r300screen || !caps)
248        return NULL;
249
250    caps->pci_id = r300_winsys->pci_id;
251    caps->num_frag_pipes = r300_winsys->gb_pipes;
252
253    r300_parse_chipset(caps);
254
255    r300screen->caps = caps;
256    r300screen->screen.winsys = winsys;
257    r300screen->screen.destroy = r300_destroy_screen;
258    r300screen->screen.get_name = r300_get_name;
259    r300screen->screen.get_vendor = r300_get_vendor;
260    r300screen->screen.get_param = r300_get_param;
261    r300screen->screen.get_paramf = r300_get_paramf;
262    r300screen->screen.is_format_supported = r300_is_format_supported;
263    r300screen->screen.surface_map = r300_surface_map;
264    r300screen->screen.surface_unmap = r300_surface_unmap;
265
266    r300_init_screen_texture_functions(&r300screen->screen);
267    u_simple_screen_init(&r300screen->screen);
268
269    return &r300screen->screen;
270}
271