r300_screen.c revision 10baf7ec1d31552a268c38422619abc131a37e2b
1/*
2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
3 * Copyright 2010 Marek Olšák <maraeo@gmail.com>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23
24#include "util/u_format.h"
25#include "util/u_format_s3tc.h"
26#include "util/u_memory.h"
27
28#include "r300_context.h"
29#include "r300_texture.h"
30#include "r300_screen_buffer.h"
31#include "r300_winsys.h"
32
33/* Return the identifier behind whom the brave coders responsible for this
34 * amalgamation of code, sweat, and duct tape, routinely obscure their names.
35 *
36 * ...I should have just put "Corbin Simpson", but I'm not that cool.
37 *
38 * (Or egotistical. Yet.) */
39static const char* r300_get_vendor(struct pipe_screen* pscreen)
40{
41    return "X.Org R300 Project";
42}
43
44static const char* chip_families[] = {
45    "R300",
46    "R350",
47    "R360",
48    "RV350",
49    "RV370",
50    "RV380",
51    "R420",
52    "R423",
53    "R430",
54    "R480",
55    "R481",
56    "RV410",
57    "RS400",
58    "RC410",
59    "RS480",
60    "RS482",
61    "RS600",
62    "RS690",
63    "RS740",
64    "RV515",
65    "R520",
66    "RV530",
67    "R580",
68    "RV560",
69    "RV570"
70};
71
72static const char* r300_get_name(struct pipe_screen* pscreen)
73{
74    struct r300_screen* r300screen = r300_screen(pscreen);
75
76    return chip_families[r300screen->caps.family];
77}
78
79static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
80{
81    struct r300_screen* r300screen = r300_screen(pscreen);
82    boolean is_r400 = r300screen->caps.is_r400;
83    boolean is_r500 = r300screen->caps.is_r500;
84
85    /* XXX extended shader capabilities of r400 unimplemented */
86    is_r400 = FALSE;
87
88    switch (param) {
89        /* Supported features (boolean caps). */
90        case PIPE_CAP_NPOT_TEXTURES:
91        case PIPE_CAP_TWO_SIDED_STENCIL:
92        case PIPE_CAP_GLSL:
93            /* I'll be frank. This is a lie.
94             *
95             * We don't truly support GLSL on any of this driver's chipsets.
96             * To be fair, no chipset supports the full GLSL specification
97             * to the best of our knowledge, but some of the less esoteric
98             * features are still missing here.
99             *
100             * Rather than cripple ourselves intentionally, I'm going to set
101             * this flag, and as Gallium's interface continues to change, I
102             * hope that this single monolithic GLSL enable can slowly get
103             * split down into many different pieces and the state tracker
104             * will handle fallbacks transparently, like it should.
105             *
106             * ~ C.
107             */
108        case PIPE_CAP_ANISOTROPIC_FILTER:
109        case PIPE_CAP_POINT_SPRITE:
110        case PIPE_CAP_OCCLUSION_QUERY:
111        case PIPE_CAP_TEXTURE_SHADOW_MAP:
112        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
113        case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
114        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
115            return 1;
116
117        /* Unsupported features (boolean caps). */
118        case PIPE_CAP_TIMER_QUERY:
119        case PIPE_CAP_DUAL_SOURCE_BLEND:
120        case PIPE_CAP_TGSI_CONT_SUPPORTED:
121        case PIPE_CAP_INDEP_BLEND_ENABLE:
122        case PIPE_CAP_INDEP_BLEND_FUNC:
123            return 0;
124
125        /* Texturing. */
126        case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
127        case PIPE_CAP_MAX_COMBINED_SAMPLERS:
128            return r300screen->caps.num_tex_units;
129        case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
130            return 0;
131        case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
132        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
133        case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
134            /* 13 == 4096, 12 == 2048 */
135            return is_r500 ? 13 : 12;
136
137        /* Render targets. */
138        case PIPE_CAP_MAX_RENDER_TARGETS:
139            return 4;
140
141        /* General shader limits and features. */
142        case PIPE_CAP_SM3:
143            return is_r500 ? 1 : 0;
144        case PIPE_CAP_MAX_CONST_BUFFERS:
145            return 1;
146        case PIPE_CAP_MAX_CONST_BUFFER_SIZE:
147            return 256;
148
149        case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
150            return 1;
151
152        /* Fragment coordinate conventions. */
153        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
154        case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
155	    return 1;
156        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
157        case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
158            return 0;
159
160        /* Fragment shader limits. */
161        case PIPE_CAP_MAX_FS_INSTRUCTIONS:
162            return is_r500 || is_r400 ? 512 : 96;
163        case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS:
164            return is_r500 || is_r400 ? 512 : 64;
165        case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS:
166            return is_r500 || is_r400 ? 512 : 32;
167        case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS:
168            return is_r500 ? 511 : 4;
169        case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH:
170            return is_r500 ? 64 : 0; /* Actually unlimited on r500. */
171        case PIPE_CAP_MAX_FS_INPUTS:
172            /* 2 colors + 8 texcoords are always supported
173             * (minus fog and wpos).
174             *
175             * R500 has the ability to turn 3rd and 4th color into
176             * additional texcoords but there is no two-sided color
177             * selection then. However the facing bit can be used instead. */
178            return 10;
179        case PIPE_CAP_MAX_FS_CONSTS:
180            return is_r500 ? 256 : 32;
181        case PIPE_CAP_MAX_FS_TEMPS:
182            return is_r500 ? 128 : is_r400 ? 64 : 32;
183        case PIPE_CAP_MAX_FS_ADDRS:
184            return 0;
185        case PIPE_CAP_MAX_FS_PREDS:
186            return is_r500 ? 1 : 0;
187
188        /* Vertex shader limits. */
189        case PIPE_CAP_MAX_VS_INSTRUCTIONS:
190        case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS:
191            return is_r500 ? 1024 : 256;
192        case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS:
193        case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS:
194            return 0;
195        case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH:
196            return is_r500 ? 4 : 0; /* For loops; not sure about conditionals. */
197        case PIPE_CAP_MAX_VS_INPUTS:
198            return 16;
199        case PIPE_CAP_MAX_VS_CONSTS:
200            return 256;
201        case PIPE_CAP_MAX_VS_TEMPS:
202            return 32;
203        case PIPE_CAP_MAX_VS_ADDRS:
204            return 1; /* XXX guessed */
205        case PIPE_CAP_MAX_VS_PREDS:
206            return is_r500 ? 4 : 0; /* XXX guessed. */
207
208        default:
209            fprintf(stderr, "r300: Implementation error: Bad param %d\n",
210                param);
211            return 0;
212    }
213}
214
215static float r300_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param)
216{
217    struct r300_screen* r300screen = r300_screen(pscreen);
218
219    switch (param) {
220        case PIPE_CAP_MAX_LINE_WIDTH:
221        case PIPE_CAP_MAX_LINE_WIDTH_AA:
222        case PIPE_CAP_MAX_POINT_WIDTH:
223        case PIPE_CAP_MAX_POINT_WIDTH_AA:
224            /* The maximum dimensions of the colorbuffer are our practical
225             * rendering limits. 2048 pixels should be enough for anybody. */
226            if (r300screen->caps.is_r500) {
227                return 4096.0f;
228            } else if (r300screen->caps.is_r400) {
229                return 4021.0f;
230            } else {
231                return 2560.0f;
232            }
233        case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
234            return 16.0f;
235        case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
236            return 16.0f;
237        default:
238            fprintf(stderr, "r300: Implementation error: Bad paramf %d\n",
239                param);
240            return 0.0f;
241    }
242}
243
244static boolean r300_is_format_supported(struct pipe_screen* screen,
245                                        enum pipe_format format,
246                                        enum pipe_texture_target target,
247                                        unsigned sample_count,
248                                        unsigned usage,
249                                        unsigned geom_flags)
250{
251    uint32_t retval = 0;
252    boolean is_r500 = r300_screen(screen)->caps.is_r500;
253    boolean is_r400 = r300_screen(screen)->caps.is_r400;
254    boolean is_z24 = format == PIPE_FORMAT_X8Z24_UNORM ||
255                     format == PIPE_FORMAT_S8_USCALED_Z24_UNORM;
256    boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM ||
257                              format == PIPE_FORMAT_R10G10B10X2_SNORM ||
258                              format == PIPE_FORMAT_B10G10R10A2_UNORM ||
259                              format == PIPE_FORMAT_R10SG10SB10SA2U_NORM;
260    boolean is_ati1n = format == PIPE_FORMAT_RGTC1_UNORM ||
261                       format == PIPE_FORMAT_RGTC1_SNORM;
262    boolean is_ati2n = format == PIPE_FORMAT_RGTC2_UNORM ||
263                       format == PIPE_FORMAT_RGTC2_SNORM;
264
265    if (target >= PIPE_MAX_TEXTURE_TYPES) {
266        fprintf(stderr, "r300: Implementation error: Received bogus texture "
267            "target %d in %s\n", target, __FUNCTION__);
268        return FALSE;
269    }
270
271   if (sample_count > 1)
272      return FALSE;
273
274    /* Check sampler format support. */
275    if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
276        /* Z24 cannot be sampled from on non-r5xx. */
277        (is_r500 || !is_z24) &&
278        /* ATI1N is r5xx-only. */
279        (is_r500 || !is_ati1n) &&
280        /* ATI2N is supported on r4xx-r5xx. */
281        (is_r400 || is_r500 || !is_ati2n) &&
282        r300_is_sampler_format_supported(format)) {
283        retval |= PIPE_BIND_SAMPLER_VIEW;
284    }
285
286    /* Check colorbuffer format support. */
287    if ((usage & (PIPE_BIND_RENDER_TARGET |
288                  PIPE_BIND_DISPLAY_TARGET |
289                  PIPE_BIND_SCANOUT |
290                  PIPE_BIND_SHARED)) &&
291        /* 2101010 cannot be rendered to on non-r5xx. */
292        (is_r500 || !is_color2101010) &&
293        r300_is_colorbuffer_format_supported(format)) {
294        retval |= usage &
295            (PIPE_BIND_RENDER_TARGET |
296             PIPE_BIND_DISPLAY_TARGET |
297             PIPE_BIND_SCANOUT |
298             PIPE_BIND_SHARED);
299    }
300
301    /* Check depth-stencil format support. */
302    if (usage & PIPE_BIND_DEPTH_STENCIL &&
303        r300_is_zs_format_supported(format)) {
304        retval |= PIPE_BIND_DEPTH_STENCIL;
305    }
306
307    return retval == usage;
308}
309
310static void r300_destroy_screen(struct pipe_screen* pscreen)
311{
312    struct r300_screen* r300screen = r300_screen(pscreen);
313    struct r300_winsys_screen *rws = r300_winsys_screen(pscreen);
314
315    if (rws)
316      rws->destroy(rws);
317
318    FREE(r300screen);
319}
320
321static void r300_fence_reference(struct pipe_screen *screen,
322                                 struct pipe_fence_handle **ptr,
323                                 struct pipe_fence_handle *fence)
324{
325    struct r300_fence **oldf = (struct r300_fence**)ptr;
326    struct r300_fence *newf = (struct r300_fence*)fence;
327
328    if (pipe_reference(&(*oldf)->reference, &newf->reference))
329        FREE(*oldf);
330
331    *ptr = fence;
332}
333
334static int r300_fence_signalled(struct pipe_screen *screen,
335                                struct pipe_fence_handle *fence,
336                                unsigned flags)
337{
338    struct r300_fence *rfence = (struct r300_fence*)fence;
339
340    return rfence->signalled ? 0 : 1; /* 0 == success */
341}
342
343static int r300_fence_finish(struct pipe_screen *screen,
344                             struct pipe_fence_handle *fence,
345                             unsigned flags)
346{
347    struct r300_fence *rfence = (struct r300_fence*)fence;
348
349    r300_finish(rfence->ctx);
350    rfence->signalled = TRUE;
351    return 0; /* 0 == success */
352}
353
354struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws)
355{
356    struct r300_screen *r300screen = CALLOC_STRUCT(r300_screen);
357
358    if (!r300screen) {
359        FREE(r300screen);
360        return NULL;
361    }
362
363    r300screen->caps.pci_id = rws->get_value(rws, R300_VID_PCI_ID);
364    r300screen->caps.num_frag_pipes = rws->get_value(rws, R300_VID_GB_PIPES);
365    r300screen->caps.num_z_pipes = rws->get_value(rws, R300_VID_Z_PIPES);
366
367    r300_init_debug(r300screen);
368    r300_parse_chipset(&r300screen->caps);
369
370    r300screen->rws = rws;
371    r300screen->screen.winsys = (struct pipe_winsys*)rws;
372    r300screen->screen.destroy = r300_destroy_screen;
373    r300screen->screen.get_name = r300_get_name;
374    r300screen->screen.get_vendor = r300_get_vendor;
375    r300screen->screen.get_param = r300_get_param;
376    r300screen->screen.get_paramf = r300_get_paramf;
377    r300screen->screen.is_format_supported = r300_is_format_supported;
378    r300screen->screen.context_create = r300_create_context;
379
380    r300screen->screen.fence_reference = r300_fence_reference;
381    r300screen->screen.fence_signalled = r300_fence_signalled;
382    r300screen->screen.fence_finish = r300_fence_finish;
383
384    r300_init_screen_resource_functions(r300screen);
385
386    util_format_s3tc_init();
387
388    return &r300screen->screen;
389}
390
391struct r300_winsys_screen *
392r300_winsys_screen(struct pipe_screen *screen)
393{
394    return r300_screen(screen)->rws;
395}
396