Path: blob/21.2-virgl/src/gallium/drivers/softpipe/sp_screen.c
4570 views
/**************************************************************************1*2* Copyright 2008 VMware, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/262728#include "compiler/nir/nir.h"29#include "util/u_memory.h"30#include "util/format/u_format.h"31#include "util/format/u_format_s3tc.h"32#include "util/u_screen.h"33#include "util/u_video.h"34#include "util/os_misc.h"35#include "util/os_time.h"36#include "pipe/p_defines.h"37#include "pipe/p_screen.h"38#include "draw/draw_context.h"3940#include "frontend/sw_winsys.h"41#include "tgsi/tgsi_exec.h"4243#include "sp_texture.h"44#include "sp_screen.h"45#include "sp_context.h"46#include "sp_fence.h"47#include "sp_public.h"4849static const struct debug_named_value sp_debug_options[] = {50{"vs", SP_DBG_VS, "dump vertex shader assembly to stderr"},51{"gs", SP_DBG_GS, "dump geometry shader assembly to stderr"},52{"fs", SP_DBG_FS, "dump fragment shader assembly to stderr"},53{"cs", SP_DBG_CS, "dump compute shader assembly to stderr"},54{"no_rast", SP_DBG_NO_RAST, "no-ops rasterization, for profiling purposes"},55{"use_llvm", SP_DBG_USE_LLVM, "Use LLVM if available for shaders"},56{"use_tgsi", SP_DBG_USE_TGSI, "Request TGSI from the API instead of NIR"},57DEBUG_NAMED_VALUE_END58};5960int sp_debug;61DEBUG_GET_ONCE_FLAGS_OPTION(sp_debug, "SOFTPIPE_DEBUG", sp_debug_options, 0)6263static const char *64softpipe_get_vendor(struct pipe_screen *screen)65{66return "Mesa/X.org";67}686970static const char *71softpipe_get_name(struct pipe_screen *screen)72{73return "softpipe";74}7576static const nir_shader_compiler_options sp_compiler_options = {77.fuse_ffma32 = true,78.fuse_ffma64 = true,79.lower_extract_byte = true,80.lower_extract_word = true,81.lower_insert_byte = true,82.lower_insert_word = true,83.lower_fdph = true,84.lower_flrp64 = true,85.lower_fmod = true,86.lower_rotate = true,87.lower_uniforms_to_ubo = true,88.lower_vector_cmp = true,89.use_interpolated_input_intrinsics = true,90};9192static const void *93softpipe_get_compiler_options(struct pipe_screen *pscreen,94enum pipe_shader_ir ir,95enum pipe_shader_type shader)96{97assert(ir == PIPE_SHADER_IR_NIR);98return &sp_compiler_options;99}100101static int102softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)103{104struct softpipe_screen *sp_screen = softpipe_screen(screen);105switch (param) {106case PIPE_CAP_NPOT_TEXTURES:107case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:108case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:109return 1;110case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:111case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:112case PIPE_CAP_VERTEX_SHADER_SATURATE:113return 1;114case PIPE_CAP_ANISOTROPIC_FILTER:115return 1;116case PIPE_CAP_POINT_SPRITE:117return 1;118case PIPE_CAP_MAX_RENDER_TARGETS:119return PIPE_MAX_COLOR_BUFS;120case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:121return 1;122case PIPE_CAP_OCCLUSION_QUERY:123return 1;124case PIPE_CAP_QUERY_TIME_ELAPSED:125return 1;126case PIPE_CAP_QUERY_PIPELINE_STATISTICS:127return 1;128case PIPE_CAP_TEXTURE_MIRROR_CLAMP:129case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:130return 1;131case PIPE_CAP_TEXTURE_SWIZZLE:132return 1;133case PIPE_CAP_MAX_TEXTURE_2D_SIZE:134return 1 << (SP_MAX_TEXTURE_2D_LEVELS - 1);135case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:136return SP_MAX_TEXTURE_3D_LEVELS;137case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:138return SP_MAX_TEXTURE_CUBE_LEVELS;139case PIPE_CAP_BLEND_EQUATION_SEPARATE:140return 1;141case PIPE_CAP_INDEP_BLEND_ENABLE:142return 1;143case PIPE_CAP_INDEP_BLEND_FUNC:144return 1;145case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:146case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:147case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:148case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:149return 1;150case PIPE_CAP_DEPTH_CLIP_DISABLE:151case PIPE_CAP_DEPTH_BOUNDS_TEST:152return 1;153case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:154return PIPE_MAX_SO_BUFFERS;155case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:156case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:157return 16*4;158case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:159case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:160return 1024;161case PIPE_CAP_MAX_VERTEX_STREAMS:162if (sp_screen->use_llvm)163return 1;164else165return PIPE_MAX_VERTEX_STREAMS;166case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:167return 2048;168case PIPE_CAP_PRIMITIVE_RESTART:169case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:170return 1;171case PIPE_CAP_SHADER_STENCIL_EXPORT:172return 1;173case PIPE_CAP_TGSI_ATOMFADD:174case PIPE_CAP_TGSI_INSTANCEID:175case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:176case PIPE_CAP_START_INSTANCE:177return 1;178case PIPE_CAP_SEAMLESS_CUBE_MAP:179case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:180return 1;181case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:182return 256; /* for GL3 */183case PIPE_CAP_MIN_TEXEL_OFFSET:184return -8;185case PIPE_CAP_MAX_TEXEL_OFFSET:186return 7;187case PIPE_CAP_CONDITIONAL_RENDER:188case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:189case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: /* draw module */190case PIPE_CAP_VERTEX_COLOR_CLAMPED: /* draw module */191return 1;192case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:193return 1;194case PIPE_CAP_GLSL_FEATURE_LEVEL:195case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:196return 400;197case PIPE_CAP_COMPUTE:198return 1;199case PIPE_CAP_USER_VERTEX_BUFFERS:200case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:201case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:202case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:203case PIPE_CAP_DOUBLES:204case PIPE_CAP_INT64:205case PIPE_CAP_INT64_DIVMOD:206case PIPE_CAP_TGSI_DIV:207return 1;208case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:209return 16;210case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:211return 64;212case PIPE_CAP_QUERY_TIMESTAMP:213case PIPE_CAP_CUBE_MAP_ARRAY:214return 1;215case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:216return 1;217case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:218return 65536;219case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:220return 16;221case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:222return 0;223case PIPE_CAP_MAX_VIEWPORTS:224return PIPE_MAX_VIEWPORTS;225case PIPE_CAP_ENDIANNESS:226return PIPE_ENDIAN_NATIVE;227case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:228return 4;229case PIPE_CAP_TEXTURE_GATHER_SM5:230case PIPE_CAP_TEXTURE_QUERY_LOD:231return 1;232case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:233return 1;234case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:235return 1;236case PIPE_CAP_SAMPLER_VIEW_TARGET:237return 1;238case PIPE_CAP_FAKE_SW_MSAA:239return 1;240case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:241return -32;242case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:243return 31;244case PIPE_CAP_DRAW_INDIRECT:245return 1;246case PIPE_CAP_QUERY_SO_OVERFLOW:247return 1;248case PIPE_CAP_NIR_IMAGES_AS_DEREF:249return 0;250251case PIPE_CAP_SHAREABLE_SHADERS:252/* Can't expose shareable shaders because the draw shaders reference the253* draw module's state, which is per-context.254*/255return 0;256257case PIPE_CAP_VENDOR_ID:258return 0xFFFFFFFF;259case PIPE_CAP_DEVICE_ID:260return 0xFFFFFFFF;261case PIPE_CAP_ACCELERATED:262return 0;263case PIPE_CAP_VIDEO_MEMORY: {264/* XXX: Do we want to return the full amount fo system memory ? */265uint64_t system_memory;266267if (!os_get_total_physical_memory(&system_memory))268return 0;269270if (sizeof(void *) == 4)271/* Cap to 2 GB on 32 bits system. We do this because softpipe does272* eat application memory, which is quite limited on 32 bits. App273* shouldn't expect too much available memory. */274system_memory = MIN2(system_memory, 2048 << 20);275276return (int)(system_memory >> 20);277}278case PIPE_CAP_UMA:279return 0;280case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:281return 1;282case PIPE_CAP_CLIP_HALFZ:283case PIPE_CAP_TEXTURE_FLOAT_LINEAR:284case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:285return 1;286case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:287case PIPE_CAP_CULL_DISTANCE:288case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:289case PIPE_CAP_TGSI_ARRAY_COMPONENTS:290case PIPE_CAP_TGSI_TEXCOORD:291case PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS:292return 1;293case PIPE_CAP_CLEAR_TEXTURE:294return 1;295case PIPE_CAP_MAX_VARYINGS:296return TGSI_EXEC_MAX_INPUT_ATTRIBS;297case PIPE_CAP_PCI_GROUP:298case PIPE_CAP_PCI_BUS:299case PIPE_CAP_PCI_DEVICE:300case PIPE_CAP_PCI_FUNCTION:301return 0;302case PIPE_CAP_MAX_GS_INVOCATIONS:303return 32;304case PIPE_CAP_MAX_SHADER_BUFFER_SIZE:305return 1 << 27;306case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:307return 4;308default:309return u_pipe_screen_get_param_defaults(screen, param);310}311}312313static int314softpipe_get_shader_param(struct pipe_screen *screen,315enum pipe_shader_type shader,316enum pipe_shader_cap param)317{318struct softpipe_screen *sp_screen = softpipe_screen(screen);319320switch (param) {321case PIPE_SHADER_CAP_PREFERRED_IR:322return (sp_debug & SP_DBG_USE_TGSI) ? PIPE_SHADER_IR_TGSI : PIPE_SHADER_IR_NIR;323case PIPE_SHADER_CAP_SUPPORTED_IRS:324return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI);325default:326break;327}328329switch(shader)330{331case PIPE_SHADER_FRAGMENT:332return tgsi_exec_get_shader_param(param);333case PIPE_SHADER_COMPUTE:334return tgsi_exec_get_shader_param(param);335case PIPE_SHADER_VERTEX:336case PIPE_SHADER_GEOMETRY:337if (sp_screen->use_llvm)338return draw_get_shader_param(shader, param);339else340return draw_get_shader_param_no_llvm(shader, param);341default:342return 0;343}344}345346static float347softpipe_get_paramf(struct pipe_screen *screen, enum pipe_capf param)348{349switch (param) {350case PIPE_CAPF_MAX_LINE_WIDTH:351FALLTHROUGH;352case PIPE_CAPF_MAX_LINE_WIDTH_AA:353return 255.0; /* arbitrary */354case PIPE_CAPF_MAX_POINT_WIDTH:355FALLTHROUGH;356case PIPE_CAPF_MAX_POINT_WIDTH_AA:357return 255.0; /* arbitrary */358case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:359return 16.0;360case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:361return 16.0; /* arbitrary */362case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:363return 0.0;364case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:365return 0.0;366case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:367return 0.0;368}369/* should only get here on unhandled cases */370debug_printf("Unexpected PIPE_CAPF %d query\n", param);371return 0.0;372}373374/**375* Query format support for creating a texture, drawing surface, etc.376* \param format the format to test377* \param type one of PIPE_TEXTURE, PIPE_SURFACE378*/379static bool380softpipe_is_format_supported( struct pipe_screen *screen,381enum pipe_format format,382enum pipe_texture_target target,383unsigned sample_count,384unsigned storage_sample_count,385unsigned bind)386{387struct sw_winsys *winsys = softpipe_screen(screen)->winsys;388const struct util_format_description *format_desc;389390assert(target == PIPE_BUFFER ||391target == PIPE_TEXTURE_1D ||392target == PIPE_TEXTURE_1D_ARRAY ||393target == PIPE_TEXTURE_2D ||394target == PIPE_TEXTURE_2D_ARRAY ||395target == PIPE_TEXTURE_RECT ||396target == PIPE_TEXTURE_3D ||397target == PIPE_TEXTURE_CUBE ||398target == PIPE_TEXTURE_CUBE_ARRAY);399400if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))401return false;402403format_desc = util_format_description(format);404if (!format_desc)405return false;406407if (sample_count > 1)408return false;409410if (bind & (PIPE_BIND_DISPLAY_TARGET |411PIPE_BIND_SCANOUT |412PIPE_BIND_SHARED)) {413if(!winsys->is_displaytarget_format_supported(winsys, bind, format))414return false;415}416417if (bind & PIPE_BIND_RENDER_TARGET) {418if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)419return false;420421/*422* Although possible, it is unnatural to render into compressed or YUV423* surfaces. So disable these here to avoid going into weird paths424* inside gallium frontends.425*/426if (format_desc->block.width != 1 ||427format_desc->block.height != 1)428return false;429}430431if (bind & PIPE_BIND_DEPTH_STENCIL) {432if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)433return false;434}435436if (format_desc->layout == UTIL_FORMAT_LAYOUT_ASTC ||437format_desc->layout == UTIL_FORMAT_LAYOUT_ATC) {438/* Software decoding is not hooked up. */439return false;440}441442if ((bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW)) &&443((bind & PIPE_BIND_DISPLAY_TARGET) == 0) &&444target != PIPE_BUFFER) {445const struct util_format_description *desc =446util_format_description(format);447if (desc->nr_channels == 3 && desc->is_array) {448/* Don't support any 3-component formats for rendering/texturing449* since we don't support the corresponding 8-bit 3 channel UNORM450* formats. This allows us to support GL_ARB_copy_image between451* GL_RGB8 and GL_RGB8UI, for example. Otherwise, we may be asked to452* do a resource copy between PIPE_FORMAT_R8G8B8_UINT and453* PIPE_FORMAT_R8G8B8X8_UNORM, for example, which will not work454* (different bpp).455*/456return false;457}458}459460if (format_desc->layout == UTIL_FORMAT_LAYOUT_ETC &&461format != PIPE_FORMAT_ETC1_RGB8)462return false;463464/*465* All other operations (sampling, transfer, etc).466*/467468/*469* Everything else should be supported by u_format.470*/471return true;472}473474475static void476softpipe_destroy_screen( struct pipe_screen *screen )477{478struct softpipe_screen *sp_screen = softpipe_screen(screen);479struct sw_winsys *winsys = sp_screen->winsys;480481if(winsys->destroy)482winsys->destroy(winsys);483484FREE(screen);485}486487488/* This is often overriden by the co-state tracker.489*/490static void491softpipe_flush_frontbuffer(struct pipe_screen *_screen,492struct pipe_context *pipe,493struct pipe_resource *resource,494unsigned level, unsigned layer,495void *context_private,496struct pipe_box *sub_box)497{498struct softpipe_screen *screen = softpipe_screen(_screen);499struct sw_winsys *winsys = screen->winsys;500struct softpipe_resource *texture = softpipe_resource(resource);501502assert(texture->dt);503if (texture->dt)504winsys->displaytarget_display(winsys, texture->dt, context_private, sub_box);505}506507static uint64_t508softpipe_get_timestamp(struct pipe_screen *_screen)509{510return os_time_get_nano();511}512513static int514softpipe_get_compute_param(struct pipe_screen *_screen,515enum pipe_shader_ir ir_type,516enum pipe_compute_cap param,517void *ret)518{519switch (param) {520case PIPE_COMPUTE_CAP_IR_TARGET:521return 0;522case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:523if (ret) {524uint64_t *grid_size = ret;525grid_size[0] = 65535;526grid_size[1] = 65535;527grid_size[2] = 65535;528}529return 3 * sizeof(uint64_t) ;530case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:531if (ret) {532uint64_t *block_size = ret;533block_size[0] = 1024;534block_size[1] = 1024;535block_size[2] = 1024;536}537return 3 * sizeof(uint64_t);538case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:539if (ret) {540uint64_t *max_threads_per_block = ret;541*max_threads_per_block = 1024;542}543return sizeof(uint64_t);544case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:545if (ret) {546uint64_t *max_local_size = ret;547*max_local_size = 32768;548}549return sizeof(uint64_t);550case PIPE_COMPUTE_CAP_GRID_DIMENSION:551case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE:552case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE:553case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:554case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE:555case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:556case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:557case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED:558case PIPE_COMPUTE_CAP_SUBGROUP_SIZE:559case PIPE_COMPUTE_CAP_ADDRESS_BITS:560case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:561break;562}563return 0;564}565566/**567* Create a new pipe_screen object568* Note: we're not presently subclassing pipe_screen (no softpipe_screen).569*/570struct pipe_screen *571softpipe_create_screen(struct sw_winsys *winsys)572{573struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen);574575if (!screen)576return NULL;577578sp_debug = debug_get_option_sp_debug();579580screen->winsys = winsys;581582screen->base.destroy = softpipe_destroy_screen;583584screen->base.get_name = softpipe_get_name;585screen->base.get_vendor = softpipe_get_vendor;586screen->base.get_device_vendor = softpipe_get_vendor; // TODO should be the CPU vendor587screen->base.get_param = softpipe_get_param;588screen->base.get_shader_param = softpipe_get_shader_param;589screen->base.get_paramf = softpipe_get_paramf;590screen->base.get_timestamp = softpipe_get_timestamp;591screen->base.is_format_supported = softpipe_is_format_supported;592screen->base.context_create = softpipe_create_context;593screen->base.flush_frontbuffer = softpipe_flush_frontbuffer;594screen->base.get_compute_param = softpipe_get_compute_param;595screen->base.get_compiler_options = softpipe_get_compiler_options;596screen->use_llvm = sp_debug & SP_DBG_USE_LLVM;597598softpipe_init_screen_texture_funcs(&screen->base);599softpipe_init_screen_fence_funcs(&screen->base);600601return &screen->base;602}603604605