r600g: add family retrival
[mesa.git] / src / gallium / drivers / r600 / r600_screen.c
1 /*
2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
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 * Authors:
24 * Jerome Glisse
25 * Corbin Simpson
26 */
27 #include <util/u_inlines.h>
28 #include <util/u_format.h>
29 #include <util/u_memory.h>
30 #include "r600_resource.h"
31 #include "r600_screen.h"
32 #include "r600_texture.h"
33 #include "r600_context.h"
34 #include "r600_public.h"
35 #include <stdio.h>
36
37 static const char* r600_get_vendor(struct pipe_screen* pscreen)
38 {
39 return "X.Org";
40 }
41
42 static const char* r600_get_name(struct pipe_screen* pscreen)
43 {
44 struct r600_screen *screen = r600_screen(pscreen);
45 enum radeon_family family = radeon_get_family(screen->rw);
46
47 if (family >= CHIP_R600 && family < CHIP_RV770)
48 return "R600 (HD2XXX,HD3XXX)";
49 else
50 return "R700 (HD4XXX)";
51 }
52
53 static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
54 {
55 switch (param) {
56 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
57 case PIPE_CAP_MAX_COMBINED_SAMPLERS:
58 return 16;
59 case PIPE_CAP_NPOT_TEXTURES:
60 return 1;
61 case PIPE_CAP_TWO_SIDED_STENCIL:
62 return 1;
63 case PIPE_CAP_GLSL:
64 return 1;
65 case PIPE_CAP_DUAL_SOURCE_BLEND:
66 return 1;
67 case PIPE_CAP_ANISOTROPIC_FILTER:
68 return 1;
69 case PIPE_CAP_POINT_SPRITE:
70 return 1;
71 case PIPE_CAP_MAX_RENDER_TARGETS:
72 /* FIXME some r6xx are buggy and can only do 4 */
73 return 8;
74 case PIPE_CAP_OCCLUSION_QUERY:
75 return 1;
76 case PIPE_CAP_TEXTURE_SHADOW_MAP:
77 return 1;
78 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
79 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
80 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
81 /* FIXME not sure here */
82 return 13;
83 case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
84 return 1;
85 case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
86 return 1;
87 case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
88 /* FIXME allow this once infrastructure is there */
89 return 0;
90 case PIPE_CAP_TGSI_CONT_SUPPORTED:
91 return 0;
92 case PIPE_CAP_BLEND_EQUATION_SEPARATE:
93 return 1;
94 case PIPE_CAP_SM3:
95 return 1;
96 case PIPE_CAP_INDEP_BLEND_ENABLE:
97 return 1;
98 case PIPE_CAP_INDEP_BLEND_FUNC:
99 /* FIXME allow this */
100 return 0;
101 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
102 return 1;
103 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
104 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
105 return 1;
106 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
107 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
108 return 0;
109 default:
110 debug_printf("r600: unknown param %d\n", param);
111 return 0;
112 }
113 }
114
115 static float r600_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param)
116 {
117 switch (param) {
118 case PIPE_CAP_MAX_LINE_WIDTH:
119 case PIPE_CAP_MAX_LINE_WIDTH_AA:
120 case PIPE_CAP_MAX_POINT_WIDTH:
121 case PIPE_CAP_MAX_POINT_WIDTH_AA:
122 return 8192.0f;
123 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
124 return 16.0f;
125 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
126 return 16.0f;
127 default:
128 debug_printf("r600: unsupported paramf %d\n", param);
129 return 0.0f;
130 }
131 }
132
133 static boolean r600_is_format_supported(struct pipe_screen* screen,
134 enum pipe_format format,
135 enum pipe_texture_target target,
136 unsigned sample_count,
137 unsigned bindings,
138 unsigned geom_flags)
139 {
140 if (target >= PIPE_MAX_TEXTURE_TYPES) {
141 debug_printf("r600: unsupported texture type %d\n", target);
142 return FALSE;
143 }
144 switch (format) {
145 case PIPE_FORMAT_B4G4R4A4_UNORM:
146 case PIPE_FORMAT_B5G6R5_UNORM:
147 case PIPE_FORMAT_B5G5R5A1_UNORM:
148 case PIPE_FORMAT_A8_UNORM:
149 case PIPE_FORMAT_L8_UNORM:
150 case PIPE_FORMAT_A8R8G8B8_SRGB:
151 case PIPE_FORMAT_R8G8B8A8_SRGB:
152 case PIPE_FORMAT_DXT1_RGB:
153 case PIPE_FORMAT_DXT1_RGBA:
154 case PIPE_FORMAT_DXT3_RGBA:
155 case PIPE_FORMAT_DXT5_RGBA:
156 case PIPE_FORMAT_UYVY:
157 case PIPE_FORMAT_L8_SRGB:
158 case PIPE_FORMAT_L8A8_SRGB:
159 case PIPE_FORMAT_L8A8_UNORM:
160 case PIPE_FORMAT_A8R8G8B8_UNORM:
161 case PIPE_FORMAT_X8R8G8B8_UNORM:
162 case PIPE_FORMAT_R8G8B8A8_UNORM:
163 case PIPE_FORMAT_R8G8B8X8_UNORM:
164 case PIPE_FORMAT_B8G8R8A8_UNORM:
165 case PIPE_FORMAT_B8G8R8X8_UNORM:
166 case PIPE_FORMAT_A8B8G8R8_SRGB:
167 case PIPE_FORMAT_B8G8R8A8_SRGB:
168 case PIPE_FORMAT_I8_UNORM:
169 case PIPE_FORMAT_Z16_UNORM:
170 case PIPE_FORMAT_X8Z24_UNORM:
171 case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
172 case PIPE_FORMAT_Z32_UNORM:
173 case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
174 case PIPE_FORMAT_Z24X8_UNORM:
175 return TRUE;
176 default:
177 /* Unknown format... */
178 break;
179 }
180 return FALSE;
181 }
182
183 struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
184 struct pipe_resource *texture,
185 struct pipe_subresource sr,
186 unsigned usage,
187 const struct pipe_box *box)
188 {
189 struct r600_texture *rtex = (struct r600_texture*)texture;
190 struct r600_transfer *trans;
191
192 trans = CALLOC_STRUCT(r600_transfer);
193 if (trans == NULL)
194 return NULL;
195 pipe_resource_reference(&trans->transfer.resource, texture);
196 trans->transfer.sr = sr;
197 trans->transfer.usage = usage;
198 trans->transfer.box = *box;
199 trans->transfer.stride = rtex->stride[sr.level];
200 trans->offset = r600_texture_get_offset(rtex, sr.level, box->z, sr.face);
201 return &trans->transfer;
202 }
203
204 void r600_texture_transfer_destroy(struct pipe_context *ctx,
205 struct pipe_transfer *trans)
206 {
207 pipe_resource_reference(&trans->resource, NULL);
208 FREE(trans);
209 }
210
211 void* r600_texture_transfer_map(struct pipe_context *ctx,
212 struct pipe_transfer* transfer)
213 {
214 struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
215 struct r600_texture *rtex = (struct r600_texture*)transfer->resource;
216 char *map;
217 enum pipe_format format = rtex->b.b.format;
218
219 map = pipe_buffer_map(ctx, rtex->buffer,
220 transfer->usage,
221 &rtransfer->buffer_transfer);
222
223 if (!map) {
224 return NULL;
225 }
226
227 return map + rtransfer->offset +
228 transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
229 transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
230 }
231
232 void r600_texture_transfer_unmap(struct pipe_context *ctx,
233 struct pipe_transfer* transfer)
234 {
235 struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
236 struct r600_texture *rtex = (struct r600_texture*)transfer->resource;
237
238 pipe_buffer_unmap(ctx, rtex->buffer, rtransfer->buffer_transfer);
239 }
240
241 static void r600_destroy_screen(struct pipe_screen* pscreen)
242 {
243 struct r600_screen* rscreen = r600_screen(pscreen);
244
245 if (rscreen == NULL)
246 return;
247 FREE(rscreen);
248 }
249
250 struct pipe_screen *r600_screen_create(struct radeon *rw)
251 {
252 struct r600_screen* rscreen;
253
254 rscreen = CALLOC_STRUCT(r600_screen);
255 if (rscreen == NULL) {
256 return NULL;
257 }
258 rscreen->rw = rw;
259 rscreen->screen.winsys = (struct pipe_winsys*)rw;
260 rscreen->screen.destroy = r600_destroy_screen;
261 rscreen->screen.get_name = r600_get_name;
262 rscreen->screen.get_vendor = r600_get_vendor;
263 rscreen->screen.get_param = r600_get_param;
264 rscreen->screen.get_paramf = r600_get_paramf;
265 rscreen->screen.is_format_supported = r600_is_format_supported;
266 rscreen->screen.context_create = r600_create_context;
267 r600_init_screen_texture_functions(&rscreen->screen);
268 r600_init_screen_resource_functions(rscreen);
269 return &rscreen->screen;
270 }