• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2008 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 
29 #include "compiler/nir/nir.h"
30 #include "util/u_helpers.h"
31 #include "util/u_memory.h"
32 #include "util/format/u_format.h"
33 #include "util/format/u_format_s3tc.h"
34 #include "util/u_screen.h"
35 #include "util/u_video.h"
36 #include "util/os_misc.h"
37 #include "util/os_time.h"
38 #include "pipe/p_defines.h"
39 #include "pipe/p_screen.h"
40 #include "draw/draw_context.h"
41 
42 #include "frontend/sw_winsys.h"
43 #include "tgsi/tgsi_exec.h"
44 
45 #include "sp_texture.h"
46 #include "sp_screen.h"
47 #include "sp_context.h"
48 #include "sp_fence.h"
49 #include "sp_public.h"
50 
51 static const struct debug_named_value sp_debug_options[] = {
52    {"vs",        SP_DBG_VS,         "dump vertex shader assembly to stderr"},
53    {"gs",        SP_DBG_GS,         "dump geometry shader assembly to stderr"},
54    {"fs",        SP_DBG_FS,         "dump fragment shader assembly to stderr"},
55    {"cs",        SP_DBG_CS,         "dump compute shader assembly to stderr"},
56    {"no_rast",   SP_DBG_NO_RAST,    "no-ops rasterization, for profiling purposes"},
57    {"use_llvm",  SP_DBG_USE_LLVM,   "Use LLVM if available for shaders"},
58    DEBUG_NAMED_VALUE_END
59 };
60 
61 int sp_debug;
62 DEBUG_GET_ONCE_FLAGS_OPTION(sp_debug, "SOFTPIPE_DEBUG", sp_debug_options, 0)
63 
64 static const char *
softpipe_get_vendor(struct pipe_screen * screen)65 softpipe_get_vendor(struct pipe_screen *screen)
66 {
67    return "Mesa";
68 }
69 
70 
71 static const char *
softpipe_get_name(struct pipe_screen * screen)72 softpipe_get_name(struct pipe_screen *screen)
73 {
74    return "softpipe";
75 }
76 
77 static const nir_shader_compiler_options sp_compiler_options = {
78    .fdot_replicates = true,
79    .fuse_ffma32 = true,
80    .fuse_ffma64 = true,
81    .lower_extract_byte = true,
82    .lower_extract_word = true,
83    .lower_insert_byte = true,
84    .lower_insert_word = true,
85    .lower_fdph = true,
86    .lower_flrp64 = true,
87    .lower_fmod = true,
88    .lower_uniforms_to_ubo = true,
89    .lower_vector_cmp = true,
90    .lower_int64_options = nir_lower_imul_2x32_64,
91    .max_unroll_iterations = 32,
92 
93    /* TGSI doesn't have a semantic for local or global index, just local and
94     * workgroup id.
95     */
96    .lower_cs_local_index_to_id = true,
97    .support_indirect_inputs = (uint8_t)BITFIELD_MASK(PIPE_SHADER_TYPES),
98    .support_indirect_outputs = (uint8_t)BITFIELD_MASK(PIPE_SHADER_TYPES),
99 };
100 
101 static const void *
softpipe_get_compiler_options(struct pipe_screen * pscreen,enum pipe_shader_ir ir,enum pipe_shader_type shader)102 softpipe_get_compiler_options(struct pipe_screen *pscreen,
103                               enum pipe_shader_ir ir,
104                               enum pipe_shader_type shader)
105 {
106    assert(ir == PIPE_SHADER_IR_NIR);
107    return &sp_compiler_options;
108 }
109 
110 static int
softpipe_get_shader_param(struct pipe_screen * screen,enum pipe_shader_type shader,enum pipe_shader_cap param)111 softpipe_get_shader_param(struct pipe_screen *screen,
112                           enum pipe_shader_type shader,
113                           enum pipe_shader_cap param)
114 {
115    struct softpipe_screen *sp_screen = softpipe_screen(screen);
116 
117    switch (param) {
118    case PIPE_SHADER_CAP_SUPPORTED_IRS:
119       return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI);
120    default:
121       break;
122    }
123 
124    switch(shader)
125    {
126    case PIPE_SHADER_FRAGMENT:
127       return tgsi_exec_get_shader_param(param);
128    case PIPE_SHADER_COMPUTE:
129       return tgsi_exec_get_shader_param(param);
130    case PIPE_SHADER_VERTEX:
131    case PIPE_SHADER_GEOMETRY:
132       if (sp_screen->use_llvm)
133          return draw_get_shader_param(shader, param);
134       else
135          return draw_get_shader_param_no_llvm(shader, param);
136    default:
137       return 0;
138    }
139 }
140 
141 /**
142  * Query format support for creating a texture, drawing surface, etc.
143  * \param format  the format to test
144  * \param type  one of PIPE_TEXTURE, PIPE_SURFACE
145  */
146 static bool
softpipe_is_format_supported(struct pipe_screen * screen,enum pipe_format format,enum pipe_texture_target target,unsigned sample_count,unsigned storage_sample_count,unsigned bind)147 softpipe_is_format_supported( struct pipe_screen *screen,
148                               enum pipe_format format,
149                               enum pipe_texture_target target,
150                               unsigned sample_count,
151                               unsigned storage_sample_count,
152                               unsigned bind)
153 {
154    struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
155    const struct util_format_description *format_desc;
156 
157    assert(target == PIPE_BUFFER ||
158           target == PIPE_TEXTURE_1D ||
159           target == PIPE_TEXTURE_1D_ARRAY ||
160           target == PIPE_TEXTURE_2D ||
161           target == PIPE_TEXTURE_2D_ARRAY ||
162           target == PIPE_TEXTURE_RECT ||
163           target == PIPE_TEXTURE_3D ||
164           target == PIPE_TEXTURE_CUBE ||
165           target == PIPE_TEXTURE_CUBE_ARRAY);
166 
167    if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
168       return false;
169 
170    format_desc = util_format_description(format);
171 
172    if (sample_count > 1)
173       return false;
174 
175    if (bind & (PIPE_BIND_DISPLAY_TARGET |
176                PIPE_BIND_SCANOUT |
177                PIPE_BIND_SHARED)) {
178       if(!winsys->is_displaytarget_format_supported(winsys, bind, format))
179          return false;
180    }
181 
182    if (bind & PIPE_BIND_RENDER_TARGET) {
183       if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
184          return false;
185 
186       /*
187        * Although possible, it is unnatural to render into compressed or YUV
188        * surfaces. So disable these here to avoid going into weird paths
189        * inside gallium frontends.
190        */
191       if (format_desc->block.width != 1 ||
192           format_desc->block.height != 1)
193          return false;
194    }
195 
196    if (bind & PIPE_BIND_DEPTH_STENCIL) {
197       if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
198          return false;
199    }
200 
201    if (format_desc->layout == UTIL_FORMAT_LAYOUT_ASTC ||
202        format_desc->layout == UTIL_FORMAT_LAYOUT_ATC) {
203       /* Software decoding is not hooked up. */
204       return false;
205    }
206 
207    if ((bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW)) &&
208        ((bind & PIPE_BIND_DISPLAY_TARGET) == 0) &&
209        target != PIPE_BUFFER) {
210       const struct util_format_description *desc =
211          util_format_description(format);
212       if (desc->nr_channels == 3 && desc->is_array) {
213          /* Don't support any 3-component formats for rendering/texturing
214           * since we don't support the corresponding 8-bit 3 channel UNORM
215           * formats.  This allows us to support GL_ARB_copy_image between
216           * GL_RGB8 and GL_RGB8UI, for example.  Otherwise, we may be asked to
217           * do a resource copy between PIPE_FORMAT_R8G8B8_UINT and
218           * PIPE_FORMAT_R8G8B8X8_UNORM, for example, which will not work
219           * (different bpp).
220           */
221          return false;
222       }
223    }
224 
225    if (format_desc->layout == UTIL_FORMAT_LAYOUT_ETC &&
226        format != PIPE_FORMAT_ETC1_RGB8)
227       return false;
228 
229    /*
230     * All other operations (sampling, transfer, etc).
231     */
232 
233    /*
234     * Everything else should be supported by u_format.
235     */
236    return true;
237 }
238 
239 
240 static void
softpipe_init_screen_caps(struct softpipe_screen * sp_screen)241 softpipe_init_screen_caps(struct softpipe_screen *sp_screen)
242 {
243    struct pipe_caps *caps = (struct pipe_caps *)&sp_screen->base.caps;
244 
245    u_init_pipe_screen_caps(&sp_screen->base, 0);
246 
247    caps->npot_textures = true;
248    caps->mixed_framebuffer_sizes = true;
249    caps->mixed_color_depth_bits = true;
250    caps->fragment_shader_texture_lod = true;
251    caps->fragment_shader_derivatives = true;
252    caps->anisotropic_filter = true;
253    caps->max_render_targets = PIPE_MAX_COLOR_BUFS;
254    caps->max_dual_source_render_targets = 1;
255    caps->occlusion_query = true;
256    caps->query_time_elapsed = true;
257    caps->query_pipeline_statistics = true;
258    caps->texture_mirror_clamp = true;
259    caps->texture_mirror_clamp_to_edge = true;
260    caps->texture_swizzle = true;
261    caps->max_texture_2d_size = 1 << (SP_MAX_TEXTURE_2D_LEVELS - 1);
262    caps->max_texture_3d_levels = SP_MAX_TEXTURE_3D_LEVELS;
263    caps->max_texture_cube_levels = SP_MAX_TEXTURE_CUBE_LEVELS;
264    caps->blend_equation_separate = true;
265    caps->indep_blend_enable = true;
266    caps->indep_blend_func = true;
267    caps->fs_coord_origin_upper_left = true;
268    caps->fs_coord_origin_lower_left = true;
269    caps->fs_coord_pixel_center_half_integer = true;
270    caps->fs_coord_pixel_center_integer = true;
271    caps->depth_clip_disable = true;
272    caps->depth_bounds_test = true;
273    caps->max_stream_output_buffers = PIPE_MAX_SO_BUFFERS;
274    caps->max_stream_output_separate_components =
275    caps->max_stream_output_interleaved_components = 16*4;
276    caps->max_geometry_output_vertices =
277    caps->max_geometry_total_output_components = 1024;
278    caps->max_vertex_streams = sp_screen->use_llvm ? 1 : PIPE_MAX_VERTEX_STREAMS;
279    caps->max_vertex_attrib_stride = 2048;
280    caps->primitive_restart = true;
281    caps->primitive_restart_fixed_index = true;
282    caps->shader_stencil_export = true;
283    caps->image_atomic_float_add = true;
284    caps->vs_instanceid = true;
285    caps->vertex_element_instance_divisor = true;
286    caps->start_instance = true;
287    caps->seamless_cube_map = true;
288    caps->seamless_cube_map_per_texture = true;
289    caps->max_texture_array_layers = 256; /* for GL3 */
290    caps->min_texel_offset = -8;
291    caps->max_texel_offset = 7;
292    caps->conditional_render = true;
293    caps->fragment_color_clamped = true;
294    caps->vertex_color_unclamped = true; /* draw module */
295    caps->vertex_color_clamped = true; /* draw module */
296    caps->glsl_feature_level =
297    caps->glsl_feature_level_compatibility = 400;
298    caps->compute = true;
299    caps->user_vertex_buffers = true;
300    caps->stream_output_pause_resume = true;
301    caps->stream_output_interleave_buffers = true;
302    caps->vs_layer_viewport = true;
303    caps->doubles = true;
304    caps->int64 = true;
305    caps->tgsi_div = true;
306    caps->constant_buffer_offset_alignment = 16;
307    caps->min_map_buffer_alignment = 64;
308    caps->query_timestamp = true;
309    caps->timer_resolution = true;
310    caps->cube_map_array = true;
311    caps->texture_buffer_objects = true;
312    caps->max_texel_buffer_elements = 65536;
313    caps->texture_buffer_offset_alignment = 16;
314    caps->texture_transfer_modes = 0;
315    caps->max_viewports = PIPE_MAX_VIEWPORTS;
316    caps->endianness = PIPE_ENDIAN_NATIVE;
317    caps->max_texture_gather_components = 4;
318    caps->texture_gather_sm5 = true;
319    caps->texture_query_lod = true;
320    caps->vs_window_space_position = true;
321    caps->fs_fine_derivative = true;
322    caps->sampler_view_target = true;
323    caps->fake_sw_msaa = true;
324    caps->min_texture_gather_offset = -32;
325    caps->max_texture_gather_offset = 31;
326    caps->draw_indirect = true;
327    caps->query_so_overflow = true;
328    caps->nir_images_as_deref = false;
329 
330    /* Can't expose shareable shaders because the draw shaders reference the
331     * draw module's state, which is per-context.
332     */
333    caps->shareable_shaders = false;
334 
335    caps->vendor_id = 0xFFFFFFFF;
336    caps->device_id = 0xFFFFFFFF;
337 
338    /* XXX: Do we want to return the full amount fo system memory ? */
339    uint64_t system_memory;
340    if (os_get_total_physical_memory(&system_memory)) {
341       if (sizeof(void *) == 4)
342          /* Cap to 2 GB on 32 bits system. We do this because llvmpipe does
343           * eat application memory, which is quite limited on 32 bits. App
344           * shouldn't expect too much available memory. */
345          system_memory = MIN2(system_memory, 2048 << 20);
346 
347       caps->video_memory = system_memory >> 20;
348    } else {
349       caps->video_memory = 0;
350    }
351 
352    caps->uma = false;
353    caps->query_memory_info = true;
354    caps->conditional_render_inverted = true;
355    caps->clip_halfz = true;
356    caps->texture_float_linear = true;
357    caps->texture_half_float_linear = true;
358    caps->framebuffer_no_attachment = true;
359    caps->cull_distance = true;
360    caps->copy_between_compressed_and_plain_formats = true;
361    caps->shader_array_components = true;
362    caps->tgsi_texcoord = true;
363    caps->max_varyings = TGSI_EXEC_MAX_INPUT_ATTRIBS;
364    caps->pci_group =
365    caps->pci_bus =
366    caps->pci_device =
367    caps->pci_function = 0;
368    caps->max_gs_invocations = 32;
369    caps->max_shader_buffer_size = 1 << 27;
370    caps->shader_buffer_offset_alignment = 4;
371    caps->image_store_formatted = true;
372 
373    caps->min_line_width =
374    caps->min_line_width_aa =
375    caps->min_point_size =
376    caps->min_point_size_aa = 1;
377    caps->point_size_granularity =
378    caps->line_width_granularity = 0.1;
379    caps->max_line_width =
380    caps->max_line_width_aa = 255.0; /* arbitrary */
381    caps->max_point_size =
382    caps->max_point_size_aa = 255.0; /* arbitrary */
383    caps->max_texture_anisotropy = 16.0;
384    caps->max_texture_lod_bias = 16.0; /* arbitrary */
385 }
386 
387 
388 static void
softpipe_destroy_screen(struct pipe_screen * screen)389 softpipe_destroy_screen( struct pipe_screen *screen )
390 {
391    FREE(screen);
392 }
393 
394 
395 /* This is often overriden by the co-state tracker.
396  */
397 static void
softpipe_flush_frontbuffer(struct pipe_screen * _screen,struct pipe_context * pipe,struct pipe_resource * resource,unsigned level,unsigned layer,void * context_private,unsigned nboxes,struct pipe_box * sub_box)398 softpipe_flush_frontbuffer(struct pipe_screen *_screen,
399                            struct pipe_context *pipe,
400                            struct pipe_resource *resource,
401                            unsigned level, unsigned layer,
402                            void *context_private,
403                            unsigned nboxes,
404                            struct pipe_box *sub_box)
405 {
406    struct softpipe_screen *screen = softpipe_screen(_screen);
407    struct sw_winsys *winsys = screen->winsys;
408    struct softpipe_resource *texture = softpipe_resource(resource);
409 
410    assert(texture->dt);
411    if (texture->dt)
412       winsys->displaytarget_display(winsys, texture->dt, context_private, nboxes, sub_box);
413 }
414 
415 static int
softpipe_get_compute_param(struct pipe_screen * _screen,enum pipe_shader_ir ir_type,enum pipe_compute_cap param,void * ret)416 softpipe_get_compute_param(struct pipe_screen *_screen,
417                            enum pipe_shader_ir ir_type,
418                            enum pipe_compute_cap param,
419                            void *ret)
420 {
421    switch (param) {
422    case PIPE_COMPUTE_CAP_IR_TARGET:
423       return 0;
424    case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
425       if (ret) {
426          uint64_t *grid_size = ret;
427          grid_size[0] = 65535;
428          grid_size[1] = 65535;
429          grid_size[2] = 65535;
430       }
431       return 3 * sizeof(uint64_t) ;
432    case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
433       if (ret) {
434          uint64_t *block_size = ret;
435          block_size[0] = 1024;
436          block_size[1] = 1024;
437          block_size[2] = 1024;
438       }
439       return 3 * sizeof(uint64_t);
440    case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
441       if (ret) {
442          uint64_t *max_threads_per_block = ret;
443          *max_threads_per_block = 1024;
444       }
445       return sizeof(uint64_t);
446    case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
447       if (ret) {
448          uint64_t *max_local_size = ret;
449          *max_local_size = 32768;
450       }
451       return sizeof(uint64_t);
452    case PIPE_COMPUTE_CAP_GRID_DIMENSION:
453    case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE:
454    case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE:
455    case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:
456    case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE:
457    case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:
458    case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:
459    case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED:
460    case PIPE_COMPUTE_CAP_SUBGROUP_SIZES:
461    case PIPE_COMPUTE_CAP_MAX_SUBGROUPS:
462    case PIPE_COMPUTE_CAP_ADDRESS_BITS:
463    case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:
464       break;
465    }
466    return 0;
467 }
468 
469 static int
softpipe_screen_get_fd(struct pipe_screen * screen)470 softpipe_screen_get_fd(struct pipe_screen *screen)
471 {
472    struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
473 
474    if (winsys->get_fd)
475       return winsys->get_fd(winsys);
476    else
477       return -1;
478 }
479 
480 /**
481  * Create a new pipe_screen object
482  * Note: we're not presently subclassing pipe_screen (no softpipe_screen).
483  */
484 struct pipe_screen *
softpipe_create_screen(struct sw_winsys * winsys)485 softpipe_create_screen(struct sw_winsys *winsys)
486 {
487    struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen);
488 
489    if (!screen)
490       return NULL;
491 
492    sp_debug = debug_get_option_sp_debug();
493 
494    screen->winsys = winsys;
495 
496    screen->base.destroy = softpipe_destroy_screen;
497 
498    screen->base.get_name = softpipe_get_name;
499    screen->base.get_vendor = softpipe_get_vendor;
500    screen->base.get_device_vendor = softpipe_get_vendor; // TODO should be the CPU vendor
501    screen->base.get_screen_fd = softpipe_screen_get_fd;
502    screen->base.get_shader_param = softpipe_get_shader_param;
503    screen->base.get_timestamp = u_default_get_timestamp;
504    screen->base.query_memory_info = util_sw_query_memory_info;
505    screen->base.is_format_supported = softpipe_is_format_supported;
506    screen->base.context_create = softpipe_create_context;
507    screen->base.flush_frontbuffer = softpipe_flush_frontbuffer;
508    screen->base.get_compute_param = softpipe_get_compute_param;
509    screen->base.get_compiler_options = softpipe_get_compiler_options;
510    screen->use_llvm = sp_debug & SP_DBG_USE_LLVM;
511 
512    softpipe_init_screen_texture_funcs(&screen->base);
513    softpipe_init_screen_fence_funcs(&screen->base);
514 
515    softpipe_init_screen_caps(screen);
516 
517    return &screen->base;
518 }
519