Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5564 | serge | 1 | /* |
2 | * Copyright 2008 Corbin Simpson |
||
3 | * Copyright 2010 Marek Olšák |
||
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 | #include "os/os_time.h" |
||
28 | #include "vl/vl_decoder.h" |
||
29 | #include "vl/vl_video_buffer.h" |
||
30 | |||
31 | #include "r300_context.h" |
||
32 | #include "r300_texture.h" |
||
33 | #include "r300_screen_buffer.h" |
||
34 | #include "r300_state_inlines.h" |
||
35 | #include "r300_public.h" |
||
36 | |||
37 | #include "draw/draw_context.h" |
||
38 | |||
39 | /* Return the identifier behind whom the brave coders responsible for this |
||
40 | * amalgamation of code, sweat, and duct tape, routinely obscure their names. |
||
41 | * |
||
42 | * ...I should have just put "Corbin Simpson", but I'm not that cool. |
||
43 | * |
||
44 | * (Or egotistical. Yet.) */ |
||
45 | static const char* r300_get_vendor(struct pipe_screen* pscreen) |
||
46 | { |
||
47 | return "X.Org R300 Project"; |
||
48 | } |
||
49 | |||
50 | static const char* r300_get_device_vendor(struct pipe_screen* pscreen) |
||
51 | { |
||
52 | return "ATI"; |
||
53 | } |
||
54 | |||
55 | static const char* chip_families[] = { |
||
56 | "unknown", |
||
57 | "ATI R300", |
||
58 | "ATI R350", |
||
59 | "ATI RV350", |
||
60 | "ATI RV370", |
||
61 | "ATI RV380", |
||
62 | "ATI RS400", |
||
63 | "ATI RC410", |
||
64 | "ATI RS480", |
||
65 | "ATI R420", |
||
66 | "ATI R423", |
||
67 | "ATI R430", |
||
68 | "ATI R480", |
||
69 | "ATI R481", |
||
70 | "ATI RV410", |
||
71 | "ATI RS600", |
||
72 | "ATI RS690", |
||
73 | "ATI RS740", |
||
74 | "ATI RV515", |
||
75 | "ATI R520", |
||
76 | "ATI RV530", |
||
77 | "ATI R580", |
||
78 | "ATI RV560", |
||
79 | "ATI RV570" |
||
80 | }; |
||
81 | |||
82 | static const char* r300_get_name(struct pipe_screen* pscreen) |
||
83 | { |
||
84 | struct r300_screen* r300screen = r300_screen(pscreen); |
||
85 | |||
86 | return chip_families[r300screen->caps.family]; |
||
87 | } |
||
88 | |||
89 | static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) |
||
90 | { |
||
91 | struct r300_screen* r300screen = r300_screen(pscreen); |
||
92 | boolean is_r500 = r300screen->caps.is_r500; |
||
93 | |||
94 | switch (param) { |
||
95 | /* Supported features (boolean caps). */ |
||
96 | case PIPE_CAP_NPOT_TEXTURES: |
||
97 | case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: |
||
98 | case PIPE_CAP_TWO_SIDED_STENCIL: |
||
99 | case PIPE_CAP_ANISOTROPIC_FILTER: |
||
100 | case PIPE_CAP_POINT_SPRITE: |
||
101 | case PIPE_CAP_OCCLUSION_QUERY: |
||
102 | case PIPE_CAP_TEXTURE_SHADOW_MAP: |
||
103 | case PIPE_CAP_TEXTURE_MIRROR_CLAMP: |
||
104 | case PIPE_CAP_BLEND_EQUATION_SEPARATE: |
||
105 | case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: |
||
106 | case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: |
||
107 | case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: |
||
108 | case PIPE_CAP_CONDITIONAL_RENDER: |
||
109 | case PIPE_CAP_TEXTURE_BARRIER: |
||
110 | case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: |
||
111 | case PIPE_CAP_USER_INDEX_BUFFERS: |
||
112 | case PIPE_CAP_USER_CONSTANT_BUFFERS: |
||
113 | case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: |
||
114 | case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: |
||
115 | case PIPE_CAP_CLIP_HALFZ: |
||
116 | return 1; |
||
117 | |||
118 | case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: |
||
119 | return R300_BUFFER_ALIGNMENT; |
||
120 | |||
121 | case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: |
||
122 | return 16; |
||
123 | |||
124 | case PIPE_CAP_GLSL_FEATURE_LEVEL: |
||
125 | return 120; |
||
126 | |||
127 | /* r300 cannot do swizzling of compressed textures. Supported otherwise. */ |
||
128 | case PIPE_CAP_TEXTURE_SWIZZLE: |
||
129 | return util_format_s3tc_enabled ? r300screen->caps.dxtc_swizzle : 1; |
||
130 | |||
131 | /* We don't support color clamping on r500, so that we can use color |
||
132 | * intepolators for generic varyings. */ |
||
133 | case PIPE_CAP_VERTEX_COLOR_CLAMPED: |
||
134 | return !is_r500; |
||
135 | |||
136 | /* Supported on r500 only. */ |
||
137 | case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: |
||
138 | case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: |
||
139 | case PIPE_CAP_SM3: |
||
140 | return is_r500 ? 1 : 0; |
||
141 | |||
142 | /* Unsupported features. */ |
||
143 | case PIPE_CAP_QUERY_TIME_ELAPSED: |
||
144 | case PIPE_CAP_QUERY_PIPELINE_STATISTICS: |
||
145 | case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: |
||
146 | case PIPE_CAP_INDEP_BLEND_ENABLE: |
||
147 | case PIPE_CAP_INDEP_BLEND_FUNC: |
||
148 | case PIPE_CAP_DEPTH_CLIP_DISABLE: |
||
149 | case PIPE_CAP_SHADER_STENCIL_EXPORT: |
||
150 | case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: |
||
151 | case PIPE_CAP_TGSI_INSTANCEID: |
||
152 | case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: |
||
153 | case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: |
||
154 | case PIPE_CAP_SEAMLESS_CUBE_MAP: |
||
155 | case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: |
||
156 | case PIPE_CAP_MIN_TEXEL_OFFSET: |
||
157 | case PIPE_CAP_MAX_TEXEL_OFFSET: |
||
158 | case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET: |
||
159 | case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: |
||
160 | case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: |
||
161 | case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: |
||
162 | case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: |
||
163 | case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES: |
||
164 | case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: |
||
165 | case PIPE_CAP_MAX_VERTEX_STREAMS: |
||
166 | case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: |
||
167 | case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: |
||
168 | case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: |
||
169 | case PIPE_CAP_COMPUTE: |
||
170 | case PIPE_CAP_START_INSTANCE: |
||
171 | case PIPE_CAP_QUERY_TIMESTAMP: |
||
172 | case PIPE_CAP_TEXTURE_MULTISAMPLE: |
||
173 | case PIPE_CAP_CUBE_MAP_ARRAY: |
||
174 | case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: |
||
175 | case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: |
||
176 | case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: |
||
177 | case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE: |
||
178 | case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT: |
||
179 | case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: |
||
180 | case PIPE_CAP_TEXTURE_GATHER_SM5: |
||
181 | case PIPE_CAP_TEXTURE_QUERY_LOD: |
||
182 | case PIPE_CAP_FAKE_SW_MSAA: |
||
183 | case PIPE_CAP_SAMPLE_SHADING: |
||
184 | case PIPE_CAP_TEXTURE_GATHER_OFFSETS: |
||
185 | case PIPE_CAP_DRAW_INDIRECT: |
||
186 | case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE: |
||
187 | case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: |
||
188 | case PIPE_CAP_SAMPLER_VIEW_TARGET: |
||
189 | case PIPE_CAP_VERTEXID_NOBASE: |
||
190 | case PIPE_CAP_POLYGON_OFFSET_CLAMP: |
||
191 | case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: |
||
192 | case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: |
||
193 | case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: |
||
194 | return 0; |
||
195 | |||
196 | /* SWTCL-only features. */ |
||
197 | case PIPE_CAP_PRIMITIVE_RESTART: |
||
198 | case PIPE_CAP_USER_VERTEX_BUFFERS: |
||
199 | case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION: |
||
200 | return !r300screen->caps.has_tcl; |
||
201 | |||
202 | /* HWTCL-only features / limitations. */ |
||
203 | case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: |
||
204 | case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: |
||
205 | case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: |
||
206 | return r300screen->caps.has_tcl; |
||
207 | case PIPE_CAP_TGSI_TEXCOORD: |
||
208 | return 0; |
||
209 | |||
210 | /* Texturing. */ |
||
211 | case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: |
||
212 | case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: |
||
213 | case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: |
||
214 | /* 13 == 4096, 12 == 2048 */ |
||
215 | return is_r500 ? 13 : 12; |
||
216 | |||
217 | /* Render targets. */ |
||
218 | case PIPE_CAP_MAX_RENDER_TARGETS: |
||
219 | return 4; |
||
220 | case PIPE_CAP_ENDIANNESS: |
||
221 | return PIPE_ENDIAN_LITTLE; |
||
222 | |||
223 | case PIPE_CAP_MAX_VIEWPORTS: |
||
224 | return 1; |
||
225 | |||
226 | case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE: |
||
227 | return 2048; |
||
228 | |||
229 | case PIPE_CAP_VENDOR_ID: |
||
230 | return 0x1002; |
||
231 | case PIPE_CAP_DEVICE_ID: |
||
232 | return r300screen->info.pci_id; |
||
233 | case PIPE_CAP_ACCELERATED: |
||
234 | return 1; |
||
235 | case PIPE_CAP_VIDEO_MEMORY: |
||
236 | return r300screen->info.vram_size >> 20; |
||
237 | case PIPE_CAP_UMA: |
||
238 | return 0; |
||
239 | } |
||
240 | return 0; |
||
241 | } |
||
242 | |||
243 | static int r300_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum pipe_shader_cap param) |
||
244 | { |
||
245 | struct r300_screen* r300screen = r300_screen(pscreen); |
||
246 | boolean is_r400 = r300screen->caps.is_r400; |
||
247 | boolean is_r500 = r300screen->caps.is_r500; |
||
248 | |||
249 | switch (shader) { |
||
250 | case PIPE_SHADER_FRAGMENT: |
||
251 | switch (param) |
||
252 | { |
||
253 | case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: |
||
254 | return is_r500 || is_r400 ? 512 : 96; |
||
255 | case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: |
||
256 | return is_r500 || is_r400 ? 512 : 64; |
||
257 | case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: |
||
258 | return is_r500 || is_r400 ? 512 : 32; |
||
259 | case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: |
||
260 | return is_r500 ? 511 : 4; |
||
261 | case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: |
||
262 | return is_r500 ? 64 : 0; /* Actually unlimited on r500. */ |
||
263 | /* Fragment shader limits. */ |
||
264 | case PIPE_SHADER_CAP_MAX_INPUTS: |
||
265 | /* 2 colors + 8 texcoords are always supported |
||
266 | * (minus fog and wpos). |
||
267 | * |
||
268 | * R500 has the ability to turn 3rd and 4th color into |
||
269 | * additional texcoords but there is no two-sided color |
||
270 | * selection then. However the facing bit can be used instead. */ |
||
271 | return 10; |
||
272 | case PIPE_SHADER_CAP_MAX_OUTPUTS: |
||
273 | return 4; |
||
274 | case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE: |
||
275 | return (is_r500 ? 256 : 32) * sizeof(float[4]); |
||
276 | case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: |
||
277 | return 1; |
||
278 | case PIPE_SHADER_CAP_MAX_TEMPS: |
||
279 | return is_r500 ? 128 : is_r400 ? 64 : 32; |
||
280 | case PIPE_SHADER_CAP_MAX_PREDS: |
||
281 | return 0; /* unused */ |
||
282 | case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: |
||
283 | case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: |
||
284 | return r300screen->caps.num_tex_units; |
||
285 | case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: |
||
286 | case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: |
||
287 | case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: |
||
288 | case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: |
||
289 | case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: |
||
290 | case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: |
||
291 | case PIPE_SHADER_CAP_SUBROUTINES: |
||
292 | case PIPE_SHADER_CAP_INTEGERS: |
||
293 | case PIPE_SHADER_CAP_DOUBLES: |
||
294 | case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED: |
||
295 | case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED: |
||
296 | case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED: |
||
297 | return 0; |
||
298 | case PIPE_SHADER_CAP_PREFERRED_IR: |
||
299 | return PIPE_SHADER_IR_TGSI; |
||
300 | } |
||
301 | break; |
||
302 | case PIPE_SHADER_VERTEX: |
||
303 | switch (param) |
||
304 | { |
||
305 | case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: |
||
306 | case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: |
||
307 | case PIPE_SHADER_CAP_SUBROUTINES: |
||
308 | return 0; |
||
309 | default:; |
||
310 | } |
||
311 | |||
312 | if (!r300screen->caps.has_tcl) { |
||
313 | return draw_get_shader_param(shader, param); |
||
314 | } |
||
315 | |||
316 | switch (param) |
||
317 | { |
||
318 | case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: |
||
319 | case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: |
||
320 | return is_r500 ? 1024 : 256; |
||
321 | case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: |
||
322 | return is_r500 ? 4 : 0; /* For loops; not sure about conditionals. */ |
||
323 | case PIPE_SHADER_CAP_MAX_INPUTS: |
||
324 | return 16; |
||
325 | case PIPE_SHADER_CAP_MAX_OUTPUTS: |
||
326 | return 10; |
||
327 | case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE: |
||
328 | return 256 * sizeof(float[4]); |
||
329 | case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: |
||
330 | return 1; |
||
331 | case PIPE_SHADER_CAP_MAX_TEMPS: |
||
332 | return 32; |
||
333 | case PIPE_SHADER_CAP_MAX_PREDS: |
||
334 | return 0; /* unused */ |
||
335 | case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: |
||
336 | return 1; |
||
337 | case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: |
||
338 | case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: |
||
339 | case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: |
||
340 | case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: |
||
341 | case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: |
||
342 | case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: |
||
343 | case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: |
||
344 | case PIPE_SHADER_CAP_SUBROUTINES: |
||
345 | case PIPE_SHADER_CAP_INTEGERS: |
||
346 | case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: |
||
347 | case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: |
||
348 | case PIPE_SHADER_CAP_DOUBLES: |
||
349 | case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED: |
||
350 | case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED: |
||
351 | case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED: |
||
352 | return 0; |
||
353 | case PIPE_SHADER_CAP_PREFERRED_IR: |
||
354 | return PIPE_SHADER_IR_TGSI; |
||
355 | } |
||
356 | break; |
||
357 | } |
||
358 | return 0; |
||
359 | } |
||
360 | |||
361 | static float r300_get_paramf(struct pipe_screen* pscreen, |
||
362 | enum pipe_capf param) |
||
363 | { |
||
364 | struct r300_screen* r300screen = r300_screen(pscreen); |
||
365 | |||
366 | switch (param) { |
||
367 | case PIPE_CAPF_MAX_LINE_WIDTH: |
||
368 | case PIPE_CAPF_MAX_LINE_WIDTH_AA: |
||
369 | case PIPE_CAPF_MAX_POINT_WIDTH: |
||
370 | case PIPE_CAPF_MAX_POINT_WIDTH_AA: |
||
371 | /* The maximum dimensions of the colorbuffer are our practical |
||
372 | * rendering limits. 2048 pixels should be enough for anybody. */ |
||
373 | if (r300screen->caps.is_r500) { |
||
374 | return 4096.0f; |
||
375 | } else if (r300screen->caps.is_r400) { |
||
376 | return 4021.0f; |
||
377 | } else { |
||
378 | return 2560.0f; |
||
379 | } |
||
380 | case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: |
||
381 | return 16.0f; |
||
382 | case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: |
||
383 | return 16.0f; |
||
384 | case PIPE_CAPF_GUARD_BAND_LEFT: |
||
385 | case PIPE_CAPF_GUARD_BAND_TOP: |
||
386 | case PIPE_CAPF_GUARD_BAND_RIGHT: |
||
387 | case PIPE_CAPF_GUARD_BAND_BOTTOM: |
||
388 | return 0.0f; |
||
389 | default: |
||
390 | debug_printf("r300: Warning: Unknown CAP %d in get_paramf.\n", |
||
391 | param); |
||
392 | return 0.0f; |
||
393 | } |
||
394 | } |
||
395 | |||
396 | static int r300_get_video_param(struct pipe_screen *screen, |
||
397 | enum pipe_video_profile profile, |
||
398 | enum pipe_video_entrypoint entrypoint, |
||
399 | enum pipe_video_cap param) |
||
400 | { |
||
401 | switch (param) { |
||
402 | case PIPE_VIDEO_CAP_SUPPORTED: |
||
403 | return vl_profile_supported(screen, profile, entrypoint); |
||
404 | case PIPE_VIDEO_CAP_NPOT_TEXTURES: |
||
405 | return 0; |
||
406 | case PIPE_VIDEO_CAP_MAX_WIDTH: |
||
407 | case PIPE_VIDEO_CAP_MAX_HEIGHT: |
||
408 | return vl_video_buffer_max_size(screen); |
||
409 | case PIPE_VIDEO_CAP_PREFERED_FORMAT: |
||
410 | return PIPE_FORMAT_NV12; |
||
411 | case PIPE_VIDEO_CAP_PREFERS_INTERLACED: |
||
412 | return false; |
||
413 | case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED: |
||
414 | return false; |
||
415 | case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE: |
||
416 | return true; |
||
417 | case PIPE_VIDEO_CAP_MAX_LEVEL: |
||
418 | return vl_level_supported(screen, profile); |
||
419 | default: |
||
420 | return 0; |
||
421 | } |
||
422 | } |
||
423 | |||
424 | /** |
||
425 | * Whether the format matches: |
||
426 | * PIPE_FORMAT_?10?10?10?2_UNORM |
||
427 | */ |
||
428 | static INLINE boolean |
||
429 | util_format_is_rgba1010102_variant(const struct util_format_description *desc) |
||
430 | { |
||
431 | static const unsigned size[4] = {10, 10, 10, 2}; |
||
432 | unsigned chan; |
||
433 | |||
434 | if (desc->block.width != 1 || |
||
435 | desc->block.height != 1 || |
||
436 | desc->block.bits != 32) |
||
437 | return FALSE; |
||
438 | |||
439 | for (chan = 0; chan < 4; ++chan) { |
||
440 | if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED && |
||
441 | desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID) |
||
442 | return FALSE; |
||
443 | if (desc->channel[chan].size != size[chan]) |
||
444 | return FALSE; |
||
445 | } |
||
446 | |||
447 | return TRUE; |
||
448 | } |
||
449 | |||
450 | static bool r300_is_blending_supported(struct r300_screen *rscreen, |
||
451 | enum pipe_format format) |
||
452 | { |
||
453 | int c; |
||
454 | const struct util_format_description *desc = |
||
455 | util_format_description(format); |
||
456 | |||
457 | if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) |
||
458 | return false; |
||
459 | |||
460 | c = util_format_get_first_non_void_channel(format); |
||
461 | |||
462 | /* RGBA16F */ |
||
463 | if (rscreen->caps.is_r500 && |
||
464 | desc->nr_channels == 4 && |
||
465 | desc->channel[c].size == 16 && |
||
466 | desc->channel[c].type == UTIL_FORMAT_TYPE_FLOAT) |
||
467 | return true; |
||
468 | |||
469 | if (desc->channel[c].normalized && |
||
470 | desc->channel[c].type == UTIL_FORMAT_TYPE_UNSIGNED && |
||
471 | desc->channel[c].size >= 4 && |
||
472 | desc->channel[c].size <= 10) { |
||
473 | /* RGB10_A2, RGBA8, RGB5_A1, RGBA4, RGB565 */ |
||
474 | if (desc->nr_channels >= 3) |
||
475 | return true; |
||
476 | |||
477 | if (format == PIPE_FORMAT_R8G8_UNORM) |
||
478 | return true; |
||
479 | |||
480 | /* R8, I8, L8, A8 */ |
||
481 | if (desc->nr_channels == 1) |
||
482 | return true; |
||
483 | } |
||
484 | |||
485 | return false; |
||
486 | } |
||
487 | |||
488 | static boolean r300_is_format_supported(struct pipe_screen* screen, |
||
489 | enum pipe_format format, |
||
490 | enum pipe_texture_target target, |
||
491 | unsigned sample_count, |
||
492 | unsigned usage) |
||
493 | { |
||
494 | uint32_t retval = 0; |
||
495 | boolean drm_2_8_0 = r300_screen(screen)->info.drm_minor >= 8; |
||
496 | boolean is_r500 = r300_screen(screen)->caps.is_r500; |
||
497 | boolean is_r400 = r300_screen(screen)->caps.is_r400; |
||
498 | boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM || |
||
499 | format == PIPE_FORMAT_R10G10B10X2_SNORM || |
||
500 | format == PIPE_FORMAT_B10G10R10A2_UNORM || |
||
501 | format == PIPE_FORMAT_B10G10R10X2_UNORM || |
||
502 | format == PIPE_FORMAT_R10SG10SB10SA2U_NORM; |
||
503 | boolean is_ati1n = format == PIPE_FORMAT_RGTC1_UNORM || |
||
504 | format == PIPE_FORMAT_RGTC1_SNORM || |
||
505 | format == PIPE_FORMAT_LATC1_UNORM || |
||
506 | format == PIPE_FORMAT_LATC1_SNORM; |
||
507 | boolean is_ati2n = format == PIPE_FORMAT_RGTC2_UNORM || |
||
508 | format == PIPE_FORMAT_RGTC2_SNORM || |
||
509 | format == PIPE_FORMAT_LATC2_UNORM || |
||
510 | format == PIPE_FORMAT_LATC2_SNORM; |
||
511 | boolean is_x16f_xy16f = format == PIPE_FORMAT_R16_FLOAT || |
||
512 | format == PIPE_FORMAT_R16G16_FLOAT || |
||
513 | format == PIPE_FORMAT_A16_FLOAT || |
||
514 | format == PIPE_FORMAT_L16_FLOAT || |
||
515 | format == PIPE_FORMAT_L16A16_FLOAT || |
||
516 | format == PIPE_FORMAT_R16A16_FLOAT || |
||
517 | format == PIPE_FORMAT_I16_FLOAT; |
||
518 | boolean is_half_float = format == PIPE_FORMAT_R16_FLOAT || |
||
519 | format == PIPE_FORMAT_R16G16_FLOAT || |
||
520 | format == PIPE_FORMAT_R16G16B16_FLOAT || |
||
521 | format == PIPE_FORMAT_R16G16B16A16_FLOAT || |
||
522 | format == PIPE_FORMAT_R16G16B16X16_FLOAT; |
||
523 | const struct util_format_description *desc; |
||
524 | |||
525 | if (!util_format_is_supported(format, usage)) |
||
526 | return FALSE; |
||
527 | |||
528 | /* Check multisampling support. */ |
||
529 | switch (sample_count) { |
||
530 | case 0: |
||
531 | case 1: |
||
532 | break; |
||
533 | case 2: |
||
534 | case 4: |
||
535 | case 6: |
||
536 | /* We need DRM 2.8.0. */ |
||
537 | if (!drm_2_8_0) { |
||
538 | return FALSE; |
||
539 | } |
||
540 | /* No texturing and scanout. */ |
||
541 | if (usage & (PIPE_BIND_SAMPLER_VIEW | |
||
542 | PIPE_BIND_DISPLAY_TARGET | |
||
543 | PIPE_BIND_SCANOUT)) { |
||
544 | return FALSE; |
||
545 | } |
||
546 | |||
547 | desc = util_format_description(format); |
||
548 | |||
549 | if (is_r500) { |
||
550 | /* Only allow depth/stencil, RGBA8, RGBA1010102, RGBA16F. */ |
||
551 | if (!util_format_is_depth_or_stencil(format) && |
||
552 | !util_format_is_rgba8_variant(desc) && |
||
553 | !util_format_is_rgba1010102_variant(desc) && |
||
554 | format != PIPE_FORMAT_R16G16B16A16_FLOAT && |
||
555 | format != PIPE_FORMAT_R16G16B16X16_FLOAT) { |
||
556 | return FALSE; |
||
557 | } |
||
558 | } else { |
||
559 | /* Only allow depth/stencil, RGBA8. */ |
||
560 | if (!util_format_is_depth_or_stencil(format) && |
||
561 | !util_format_is_rgba8_variant(desc)) { |
||
562 | return FALSE; |
||
563 | } |
||
564 | } |
||
565 | break; |
||
566 | default: |
||
567 | return FALSE; |
||
568 | } |
||
569 | |||
570 | /* Check sampler format support. */ |
||
571 | if ((usage & PIPE_BIND_SAMPLER_VIEW) && |
||
572 | /* these two are broken for an unknown reason */ |
||
573 | format != PIPE_FORMAT_R8G8B8X8_SNORM && |
||
574 | format != PIPE_FORMAT_R16G16B16X16_SNORM && |
||
575 | /* ATI1N is r5xx-only. */ |
||
576 | (is_r500 || !is_ati1n) && |
||
577 | /* ATI2N is supported on r4xx-r5xx. */ |
||
578 | (is_r400 || is_r500 || !is_ati2n) && |
||
579 | /* R16F and RG16F texture support was added in as late as DRM 2.8.0 */ |
||
580 | (drm_2_8_0 || !is_x16f_xy16f) && |
||
581 | r300_is_sampler_format_supported(format)) { |
||
582 | retval |= PIPE_BIND_SAMPLER_VIEW; |
||
583 | } |
||
584 | |||
585 | /* Check colorbuffer format support. */ |
||
586 | if ((usage & (PIPE_BIND_RENDER_TARGET | |
||
587 | PIPE_BIND_DISPLAY_TARGET | |
||
588 | PIPE_BIND_SCANOUT | |
||
589 | PIPE_BIND_SHARED | |
||
590 | PIPE_BIND_BLENDABLE)) && |
||
591 | /* 2101010 cannot be rendered to on non-r5xx. */ |
||
592 | (!is_color2101010 || (is_r500 && drm_2_8_0)) && |
||
593 | r300_is_colorbuffer_format_supported(format)) { |
||
594 | retval |= usage & |
||
595 | (PIPE_BIND_RENDER_TARGET | |
||
596 | PIPE_BIND_DISPLAY_TARGET | |
||
597 | PIPE_BIND_SCANOUT | |
||
598 | PIPE_BIND_SHARED); |
||
599 | |||
600 | if (r300_is_blending_supported(r300_screen(screen), format)) { |
||
601 | retval |= usage & PIPE_BIND_BLENDABLE; |
||
602 | } |
||
603 | } |
||
604 | |||
605 | /* Check depth-stencil format support. */ |
||
606 | if (usage & PIPE_BIND_DEPTH_STENCIL && |
||
607 | r300_is_zs_format_supported(format)) { |
||
608 | retval |= PIPE_BIND_DEPTH_STENCIL; |
||
609 | } |
||
610 | |||
611 | /* Check vertex buffer format support. */ |
||
612 | if (usage & PIPE_BIND_VERTEX_BUFFER) { |
||
613 | if (r300_screen(screen)->caps.has_tcl) { |
||
614 | /* Half float is supported on >= R400. */ |
||
615 | if ((is_r400 || is_r500 || !is_half_float) && |
||
616 | r300_translate_vertex_data_type(format) != R300_INVALID_FORMAT) { |
||
617 | retval |= PIPE_BIND_VERTEX_BUFFER; |
||
618 | } |
||
619 | } else { |
||
620 | /* SW TCL */ |
||
621 | if (!util_format_is_pure_integer(format)) { |
||
622 | retval |= PIPE_BIND_VERTEX_BUFFER; |
||
623 | } |
||
624 | } |
||
625 | } |
||
626 | |||
627 | /* Transfers are always supported. */ |
||
628 | if (usage & PIPE_BIND_TRANSFER_READ) |
||
629 | retval |= PIPE_BIND_TRANSFER_READ; |
||
630 | if (usage & PIPE_BIND_TRANSFER_WRITE) |
||
631 | retval |= PIPE_BIND_TRANSFER_WRITE; |
||
632 | |||
633 | return retval == usage; |
||
634 | } |
||
635 | |||
636 | static void r300_destroy_screen(struct pipe_screen* pscreen) |
||
637 | { |
||
638 | struct r300_screen* r300screen = r300_screen(pscreen); |
||
639 | struct radeon_winsys *rws = radeon_winsys(pscreen); |
||
640 | |||
641 | if (rws && !rws->unref(rws)) |
||
642 | return; |
||
643 | |||
644 | pipe_mutex_destroy(r300screen->cmask_mutex); |
||
645 | |||
646 | if (rws) |
||
647 | rws->destroy(rws); |
||
648 | |||
649 | FREE(r300screen); |
||
650 | } |
||
651 | |||
652 | static void r300_fence_reference(struct pipe_screen *screen, |
||
653 | struct pipe_fence_handle **ptr, |
||
654 | struct pipe_fence_handle *fence) |
||
655 | { |
||
656 | struct radeon_winsys *rws = r300_screen(screen)->rws; |
||
657 | |||
658 | rws->fence_reference(ptr, fence); |
||
659 | } |
||
660 | |||
661 | static boolean r300_fence_signalled(struct pipe_screen *screen, |
||
662 | struct pipe_fence_handle *fence) |
||
663 | { |
||
664 | struct radeon_winsys *rws = r300_screen(screen)->rws; |
||
665 | |||
666 | return rws->fence_wait(rws, fence, 0); |
||
667 | } |
||
668 | |||
669 | static boolean r300_fence_finish(struct pipe_screen *screen, |
||
670 | struct pipe_fence_handle *fence, |
||
671 | uint64_t timeout) |
||
672 | { |
||
673 | struct radeon_winsys *rws = r300_screen(screen)->rws; |
||
674 | |||
675 | return rws->fence_wait(rws, fence, timeout); |
||
676 | } |
||
677 | |||
678 | struct pipe_screen* r300_screen_create(struct radeon_winsys *rws) |
||
679 | { |
||
680 | struct r300_screen *r300screen = CALLOC_STRUCT(r300_screen); |
||
681 | |||
682 | if (!r300screen) { |
||
683 | FREE(r300screen); |
||
684 | return NULL; |
||
685 | } |
||
686 | |||
687 | rws->query_info(rws, &r300screen->info); |
||
688 | |||
689 | r300_init_debug(r300screen); |
||
690 | r300_parse_chipset(r300screen->info.pci_id, &r300screen->caps); |
||
691 | |||
692 | if (SCREEN_DBG_ON(r300screen, DBG_NO_ZMASK)) |
||
693 | r300screen->caps.zmask_ram = 0; |
||
694 | if (SCREEN_DBG_ON(r300screen, DBG_NO_HIZ)) |
||
695 | r300screen->caps.hiz_ram = 0; |
||
696 | |||
697 | if (r300screen->info.drm_minor < 8) |
||
698 | r300screen->caps.has_us_format = FALSE; |
||
699 | |||
700 | r300screen->rws = rws; |
||
701 | r300screen->screen.destroy = r300_destroy_screen; |
||
702 | r300screen->screen.get_name = r300_get_name; |
||
703 | r300screen->screen.get_vendor = r300_get_vendor; |
||
704 | r300screen->screen.get_device_vendor = r300_get_device_vendor; |
||
705 | r300screen->screen.get_param = r300_get_param; |
||
706 | r300screen->screen.get_shader_param = r300_get_shader_param; |
||
707 | r300screen->screen.get_paramf = r300_get_paramf; |
||
708 | r300screen->screen.get_video_param = r300_get_video_param; |
||
709 | r300screen->screen.is_format_supported = r300_is_format_supported; |
||
710 | r300screen->screen.is_video_format_supported = vl_video_buffer_is_format_supported; |
||
711 | r300screen->screen.context_create = r300_create_context; |
||
712 | r300screen->screen.fence_reference = r300_fence_reference; |
||
713 | r300screen->screen.fence_signalled = r300_fence_signalled; |
||
714 | r300screen->screen.fence_finish = r300_fence_finish; |
||
715 | |||
716 | r300_init_screen_resource_functions(r300screen); |
||
717 | |||
718 | util_format_s3tc_init(); |
||
719 | pipe_mutex_init(r300screen->cmask_mutex); |
||
720 | |||
721 | return &r300screen->screen; |
||
722 | }>=>> |