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