101e04c3fSmrg/**************************************************************************** 201e04c3fSmrg * Copyright (C) 2015 Intel Corporation. All Rights Reserved. 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2101e04c3fSmrg * IN THE SOFTWARE. 2201e04c3fSmrg ***************************************************************************/ 2301e04c3fSmrg 2401e04c3fSmrg#include "swr_context.h" 2501e04c3fSmrg#include "swr_public.h" 2601e04c3fSmrg#include "swr_screen.h" 2701e04c3fSmrg#include "swr_resource.h" 2801e04c3fSmrg#include "swr_fence.h" 2901e04c3fSmrg#include "gen_knobs.h" 3001e04c3fSmrg 3101e04c3fSmrg#include "pipe/p_screen.h" 3201e04c3fSmrg#include "pipe/p_defines.h" 3301e04c3fSmrg#include "util/u_memory.h" 347ec681f3Smrg#include "util/format/u_format.h" 3501e04c3fSmrg#include "util/u_inlines.h" 3601e04c3fSmrg#include "util/u_cpu_detect.h" 377ec681f3Smrg#include "util/format/u_format_s3tc.h" 3801e04c3fSmrg#include "util/u_string.h" 399f464c52Smaya#include "util/u_screen.h" 4001e04c3fSmrg 417ec681f3Smrg#include "frontend/sw_winsys.h" 4201e04c3fSmrg 4301e04c3fSmrg#include "jit_api.h" 4401e04c3fSmrg 4501e04c3fSmrg#include "memory/TilingFunctions.h" 4601e04c3fSmrg 4701e04c3fSmrg#include <stdio.h> 4801e04c3fSmrg#include <map> 4901e04c3fSmrg 5001e04c3fSmrg/* 5101e04c3fSmrg * Max texture sizes 5201e04c3fSmrg * XXX Check max texture size values against core and sampler. 5301e04c3fSmrg */ 5401e04c3fSmrg#define SWR_MAX_TEXTURE_SIZE (2 * 1024 * 1024 * 1024ULL) /* 2GB */ 557ec681f3Smrg/* Not all texture formats can fit into 2GB limit, but we have to 567ec681f3Smrg live with that. See lp_limits.h for more details */ 577ec681f3Smrg#define SWR_MAX_TEXTURE_2D_SIZE 16384 5801e04c3fSmrg#define SWR_MAX_TEXTURE_3D_LEVELS 12 /* 2K x 2K x 2K for now */ 5901e04c3fSmrg#define SWR_MAX_TEXTURE_CUBE_LEVELS 14 /* 8K x 8K for now */ 6001e04c3fSmrg#define SWR_MAX_TEXTURE_ARRAY_LAYERS 512 /* 8K x 512 / 8K x 8K x 512 */ 6101e04c3fSmrg 6201e04c3fSmrg/* Default max client_copy_limit */ 6301e04c3fSmrg#define SWR_CLIENT_COPY_LIMIT 8192 6401e04c3fSmrg 6501e04c3fSmrg/* Flag indicates creation of alternate surface, to prevent recursive loop 6601e04c3fSmrg * in resource creation when msaa_force_enable is set. */ 6701e04c3fSmrg#define SWR_RESOURCE_FLAG_ALT_SURFACE (PIPE_RESOURCE_FLAG_DRV_PRIV << 0) 6801e04c3fSmrg 6901e04c3fSmrg 7001e04c3fSmrgstatic const char * 7101e04c3fSmrgswr_get_name(struct pipe_screen *screen) 7201e04c3fSmrg{ 7301e04c3fSmrg static char buf[100]; 747ec681f3Smrg snprintf(buf, sizeof(buf), "SWR (LLVM " MESA_LLVM_VERSION_STRING ", %u bits)", 757ec681f3Smrg lp_native_vector_width); 7601e04c3fSmrg return buf; 7701e04c3fSmrg} 7801e04c3fSmrg 7901e04c3fSmrgstatic const char * 8001e04c3fSmrgswr_get_vendor(struct pipe_screen *screen) 8101e04c3fSmrg{ 8201e04c3fSmrg return "Intel Corporation"; 8301e04c3fSmrg} 8401e04c3fSmrg 857ec681f3Smrgstatic bool 8601e04c3fSmrgswr_is_format_supported(struct pipe_screen *_screen, 8701e04c3fSmrg enum pipe_format format, 8801e04c3fSmrg enum pipe_texture_target target, 8901e04c3fSmrg unsigned sample_count, 9001e04c3fSmrg unsigned storage_sample_count, 9101e04c3fSmrg unsigned bind) 9201e04c3fSmrg{ 9301e04c3fSmrg struct swr_screen *screen = swr_screen(_screen); 9401e04c3fSmrg struct sw_winsys *winsys = screen->winsys; 9501e04c3fSmrg const struct util_format_description *format_desc; 9601e04c3fSmrg 9701e04c3fSmrg assert(target == PIPE_BUFFER || target == PIPE_TEXTURE_1D 9801e04c3fSmrg || target == PIPE_TEXTURE_1D_ARRAY 9901e04c3fSmrg || target == PIPE_TEXTURE_2D 10001e04c3fSmrg || target == PIPE_TEXTURE_2D_ARRAY 10101e04c3fSmrg || target == PIPE_TEXTURE_RECT 10201e04c3fSmrg || target == PIPE_TEXTURE_3D 10301e04c3fSmrg || target == PIPE_TEXTURE_CUBE 10401e04c3fSmrg || target == PIPE_TEXTURE_CUBE_ARRAY); 10501e04c3fSmrg 10601e04c3fSmrg if (MAX2(1, sample_count) != MAX2(1, storage_sample_count)) 10701e04c3fSmrg return false; 10801e04c3fSmrg 10901e04c3fSmrg format_desc = util_format_description(format); 11001e04c3fSmrg if (!format_desc) 1117ec681f3Smrg return false; 11201e04c3fSmrg 11301e04c3fSmrg if ((sample_count > screen->msaa_max_count) 11401e04c3fSmrg || !util_is_power_of_two_or_zero(sample_count)) 1157ec681f3Smrg return false; 11601e04c3fSmrg 11701e04c3fSmrg if (bind & PIPE_BIND_DISPLAY_TARGET) { 11801e04c3fSmrg if (!winsys->is_displaytarget_format_supported(winsys, bind, format)) 1197ec681f3Smrg return false; 12001e04c3fSmrg } 12101e04c3fSmrg 12201e04c3fSmrg if (bind & PIPE_BIND_RENDER_TARGET) { 12301e04c3fSmrg if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) 1247ec681f3Smrg return false; 12501e04c3fSmrg 12601e04c3fSmrg if (mesa_to_swr_format(format) == (SWR_FORMAT)-1) 1277ec681f3Smrg return false; 12801e04c3fSmrg 12901e04c3fSmrg /* 13001e04c3fSmrg * Although possible, it is unnatural to render into compressed or YUV 13101e04c3fSmrg * surfaces. So disable these here to avoid going into weird paths 1327ec681f3Smrg * inside gallium frontends. 13301e04c3fSmrg */ 13401e04c3fSmrg if (format_desc->block.width != 1 || format_desc->block.height != 1) 1357ec681f3Smrg return false; 13601e04c3fSmrg } 13701e04c3fSmrg 13801e04c3fSmrg if (bind & PIPE_BIND_DEPTH_STENCIL) { 13901e04c3fSmrg if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) 1407ec681f3Smrg return false; 14101e04c3fSmrg 14201e04c3fSmrg if (mesa_to_swr_format(format) == (SWR_FORMAT)-1) 1437ec681f3Smrg return false; 14401e04c3fSmrg } 14501e04c3fSmrg 1467ec681f3Smrg if (bind & PIPE_BIND_VERTEX_BUFFER) { 1477ec681f3Smrg if (mesa_to_swr_format(format) == (SWR_FORMAT)-1) { 1487ec681f3Smrg return false; 1497ec681f3Smrg } 1507ec681f3Smrg } 1517ec681f3Smrg 1527ec681f3Smrg if (format_desc->layout == UTIL_FORMAT_LAYOUT_ASTC || 1537ec681f3Smrg format_desc->layout == UTIL_FORMAT_LAYOUT_FXT1) 1547ec681f3Smrg { 1557ec681f3Smrg return false; 15601e04c3fSmrg } 15701e04c3fSmrg 15801e04c3fSmrg if (format_desc->layout == UTIL_FORMAT_LAYOUT_ETC && 15901e04c3fSmrg format != PIPE_FORMAT_ETC1_RGB8) { 1607ec681f3Smrg return false; 1617ec681f3Smrg } 1627ec681f3Smrg 1637ec681f3Smrg if ((bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW)) && 1647ec681f3Smrg ((bind & PIPE_BIND_DISPLAY_TARGET) == 0)) { 1657ec681f3Smrg /* Disable all 3-channel formats, where channel size != 32 bits. 1667ec681f3Smrg * In some cases we run into crashes (in generate_unswizzled_blend()), 1677ec681f3Smrg * for 3-channel RGB16 variants, there was an apparent LLVM bug. 1687ec681f3Smrg * In any case, disabling the shallower 3-channel formats avoids a 1697ec681f3Smrg * number of issues with GL_ARB_copy_image support. 1707ec681f3Smrg */ 1717ec681f3Smrg if (format_desc->is_array && 1727ec681f3Smrg format_desc->nr_channels == 3 && 1737ec681f3Smrg format_desc->block.bits != 96) { 1747ec681f3Smrg return false; 1757ec681f3Smrg } 17601e04c3fSmrg } 17701e04c3fSmrg 17801e04c3fSmrg return TRUE; 17901e04c3fSmrg} 18001e04c3fSmrg 18101e04c3fSmrgstatic int 18201e04c3fSmrgswr_get_param(struct pipe_screen *screen, enum pipe_cap param) 18301e04c3fSmrg{ 18401e04c3fSmrg switch (param) { 18501e04c3fSmrg /* limits */ 18601e04c3fSmrg case PIPE_CAP_MAX_RENDER_TARGETS: 18701e04c3fSmrg return PIPE_MAX_COLOR_BUFS; 1887ec681f3Smrg case PIPE_CAP_MAX_TEXTURE_2D_SIZE: 1897ec681f3Smrg return SWR_MAX_TEXTURE_2D_SIZE; 19001e04c3fSmrg case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 19101e04c3fSmrg return SWR_MAX_TEXTURE_3D_LEVELS; 19201e04c3fSmrg case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 19301e04c3fSmrg return SWR_MAX_TEXTURE_CUBE_LEVELS; 19401e04c3fSmrg case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 19501e04c3fSmrg return MAX_SO_STREAMS; 19601e04c3fSmrg case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 19701e04c3fSmrg case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 19801e04c3fSmrg return MAX_ATTRIBUTES * 4; 19901e04c3fSmrg case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES: 20001e04c3fSmrg case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: 20101e04c3fSmrg return 1024; 20201e04c3fSmrg case PIPE_CAP_MAX_VERTEX_STREAMS: 2037ec681f3Smrg return 4; 20401e04c3fSmrg case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE: 20501e04c3fSmrg return 2048; 20601e04c3fSmrg case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 20701e04c3fSmrg return SWR_MAX_TEXTURE_ARRAY_LAYERS; 2087ec681f3Smrg case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET: 20901e04c3fSmrg case PIPE_CAP_MIN_TEXEL_OFFSET: 21001e04c3fSmrg return -8; 2117ec681f3Smrg case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: 21201e04c3fSmrg case PIPE_CAP_MAX_TEXEL_OFFSET: 21301e04c3fSmrg return 7; 2147ec681f3Smrg case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: 2157ec681f3Smrg return 4; 21601e04c3fSmrg case PIPE_CAP_GLSL_FEATURE_LEVEL: 21701e04c3fSmrg return 330; 21801e04c3fSmrg case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY: 21901e04c3fSmrg return 140; 22001e04c3fSmrg case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 22101e04c3fSmrg return 16; 22201e04c3fSmrg case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: 22301e04c3fSmrg return 64; 22401e04c3fSmrg case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE: 22501e04c3fSmrg return 65536; 22601e04c3fSmrg case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: 22701e04c3fSmrg return 1; 2287ec681f3Smrg case PIPE_CAP_MAX_VIEWPORTS: 2297ec681f3Smrg return KNOB_NUM_VIEWPORTS_SCISSORS; 23001e04c3fSmrg case PIPE_CAP_ENDIANNESS: 23101e04c3fSmrg return PIPE_ENDIAN_NATIVE; 23201e04c3fSmrg 23301e04c3fSmrg /* supported features */ 23401e04c3fSmrg case PIPE_CAP_NPOT_TEXTURES: 23501e04c3fSmrg case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: 23601e04c3fSmrg case PIPE_CAP_MIXED_COLOR_DEPTH_BITS: 2377ec681f3Smrg case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD: 2387ec681f3Smrg case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES: 2397ec681f3Smrg case PIPE_CAP_VERTEX_SHADER_SATURATE: 24001e04c3fSmrg case PIPE_CAP_POINT_SPRITE: 24101e04c3fSmrg case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 24201e04c3fSmrg case PIPE_CAP_OCCLUSION_QUERY: 24301e04c3fSmrg case PIPE_CAP_QUERY_TIME_ELAPSED: 24401e04c3fSmrg case PIPE_CAP_QUERY_PIPELINE_STATISTICS: 24501e04c3fSmrg case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 24601e04c3fSmrg case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE: 24701e04c3fSmrg case PIPE_CAP_TEXTURE_SWIZZLE: 24801e04c3fSmrg case PIPE_CAP_BLEND_EQUATION_SEPARATE: 24901e04c3fSmrg case PIPE_CAP_INDEP_BLEND_ENABLE: 25001e04c3fSmrg case PIPE_CAP_INDEP_BLEND_FUNC: 25101e04c3fSmrg case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 25201e04c3fSmrg case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 25301e04c3fSmrg case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 25401e04c3fSmrg case PIPE_CAP_DEPTH_CLIP_DISABLE: 25501e04c3fSmrg case PIPE_CAP_PRIMITIVE_RESTART: 2567ec681f3Smrg case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX: 25701e04c3fSmrg case PIPE_CAP_TGSI_INSTANCEID: 25801e04c3fSmrg case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 25901e04c3fSmrg case PIPE_CAP_START_INSTANCE: 26001e04c3fSmrg case PIPE_CAP_SEAMLESS_CUBE_MAP: 26101e04c3fSmrg case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 26201e04c3fSmrg case PIPE_CAP_CONDITIONAL_RENDER: 26301e04c3fSmrg case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 26401e04c3fSmrg case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 26501e04c3fSmrg case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 26601e04c3fSmrg case PIPE_CAP_USER_VERTEX_BUFFERS: 26701e04c3fSmrg case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS: 26801e04c3fSmrg case PIPE_CAP_QUERY_TIMESTAMP: 26901e04c3fSmrg case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: 27001e04c3fSmrg case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: 27101e04c3fSmrg case PIPE_CAP_DRAW_INDIRECT: 27201e04c3fSmrg case PIPE_CAP_UMA: 27301e04c3fSmrg case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: 27401e04c3fSmrg case PIPE_CAP_CLIP_HALFZ: 27501e04c3fSmrg case PIPE_CAP_POLYGON_OFFSET_CLAMP: 27601e04c3fSmrg case PIPE_CAP_DEPTH_BOUNDS_TEST: 27701e04c3fSmrg case PIPE_CAP_CLEAR_TEXTURE: 27801e04c3fSmrg case PIPE_CAP_TEXTURE_FLOAT_LINEAR: 27901e04c3fSmrg case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR: 28001e04c3fSmrg case PIPE_CAP_CULL_DISTANCE: 28101e04c3fSmrg case PIPE_CAP_CUBE_MAP_ARRAY: 28201e04c3fSmrg case PIPE_CAP_DOUBLES: 2837ec681f3Smrg case PIPE_CAP_TEXTURE_QUERY_LOD: 2847ec681f3Smrg case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS: 2857ec681f3Smrg case PIPE_CAP_TGSI_TG4_COMPONENT_IN_SWIZZLE: 2867ec681f3Smrg case PIPE_CAP_QUERY_SO_OVERFLOW: 2877ec681f3Smrg case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 28801e04c3fSmrg return 1; 28901e04c3fSmrg 2907ec681f3Smrg case PIPE_CAP_SHAREABLE_SHADERS: 2917ec681f3Smrg return 0; 2927ec681f3Smrg 29301e04c3fSmrg /* MSAA support 29401e04c3fSmrg * If user has explicitly set max_sample_count = 1 (via SWR_MSAA_MAX_COUNT) 29501e04c3fSmrg * then disable all MSAA support and go back to old (FAKE_SW_MSAA) caps. */ 29601e04c3fSmrg case PIPE_CAP_TEXTURE_MULTISAMPLE: 29701e04c3fSmrg case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: 29801e04c3fSmrg return (swr_screen(screen)->msaa_max_count > 1) ? 1 : 0; 29901e04c3fSmrg case PIPE_CAP_FAKE_SW_MSAA: 30001e04c3fSmrg return (swr_screen(screen)->msaa_max_count > 1) ? 0 : 1; 30101e04c3fSmrg 30201e04c3fSmrg /* fetch jit change for 2-4GB buffers requires alignment */ 30301e04c3fSmrg case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: 30401e04c3fSmrg case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: 30501e04c3fSmrg case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: 30601e04c3fSmrg return 1; 30701e04c3fSmrg 30801e04c3fSmrg /* unsupported features */ 30901e04c3fSmrg case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: 31001e04c3fSmrg case PIPE_CAP_PCI_GROUP: 31101e04c3fSmrg case PIPE_CAP_PCI_BUS: 31201e04c3fSmrg case PIPE_CAP_PCI_DEVICE: 31301e04c3fSmrg case PIPE_CAP_PCI_FUNCTION: 31401e04c3fSmrg case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY: 31501e04c3fSmrg return 0; 31601e04c3fSmrg case PIPE_CAP_MAX_GS_INVOCATIONS: 31701e04c3fSmrg return 32; 31801e04c3fSmrg case PIPE_CAP_MAX_SHADER_BUFFER_SIZE: 31901e04c3fSmrg return 1 << 27; 3209f464c52Smaya case PIPE_CAP_MAX_VARYINGS: 3219f464c52Smaya return 32; 32201e04c3fSmrg 32301e04c3fSmrg case PIPE_CAP_VENDOR_ID: 32401e04c3fSmrg return 0xFFFFFFFF; 32501e04c3fSmrg case PIPE_CAP_DEVICE_ID: 32601e04c3fSmrg return 0xFFFFFFFF; 32701e04c3fSmrg case PIPE_CAP_ACCELERATED: 32801e04c3fSmrg return 0; 32901e04c3fSmrg case PIPE_CAP_VIDEO_MEMORY: { 33001e04c3fSmrg /* XXX: Do we want to return the full amount of system memory ? */ 33101e04c3fSmrg uint64_t system_memory; 33201e04c3fSmrg 33301e04c3fSmrg if (!os_get_total_physical_memory(&system_memory)) 33401e04c3fSmrg return 0; 33501e04c3fSmrg 33601e04c3fSmrg return (int)(system_memory >> 20); 33701e04c3fSmrg } 3389f464c52Smaya default: 3399f464c52Smaya return u_pipe_screen_get_param_defaults(screen, param); 34001e04c3fSmrg } 34101e04c3fSmrg} 34201e04c3fSmrg 34301e04c3fSmrgstatic int 34401e04c3fSmrgswr_get_shader_param(struct pipe_screen *screen, 34501e04c3fSmrg enum pipe_shader_type shader, 34601e04c3fSmrg enum pipe_shader_cap param) 34701e04c3fSmrg{ 3487ec681f3Smrg if (shader != PIPE_SHADER_VERTEX && 3497ec681f3Smrg shader != PIPE_SHADER_FRAGMENT && 3507ec681f3Smrg shader != PIPE_SHADER_GEOMETRY && 3517ec681f3Smrg shader != PIPE_SHADER_TESS_CTRL && 3527ec681f3Smrg shader != PIPE_SHADER_TESS_EVAL) 3537ec681f3Smrg return 0; 35401e04c3fSmrg 3557ec681f3Smrg if (param == PIPE_SHADER_CAP_MAX_SHADER_BUFFERS || 3567ec681f3Smrg param == PIPE_SHADER_CAP_MAX_SHADER_IMAGES) { 3577ec681f3Smrg return 0; 3587ec681f3Smrg } 3597ec681f3Smrg 3607ec681f3Smrg return gallivm_get_shader_param(param); 36101e04c3fSmrg} 36201e04c3fSmrg 36301e04c3fSmrg 36401e04c3fSmrgstatic float 36501e04c3fSmrgswr_get_paramf(struct pipe_screen *screen, enum pipe_capf param) 36601e04c3fSmrg{ 36701e04c3fSmrg switch (param) { 36801e04c3fSmrg case PIPE_CAPF_MAX_LINE_WIDTH: 36901e04c3fSmrg case PIPE_CAPF_MAX_LINE_WIDTH_AA: 37001e04c3fSmrg case PIPE_CAPF_MAX_POINT_WIDTH: 37101e04c3fSmrg return 255.0; /* arbitrary */ 37201e04c3fSmrg case PIPE_CAPF_MAX_POINT_WIDTH_AA: 37301e04c3fSmrg return 0.0; 37401e04c3fSmrg case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 37501e04c3fSmrg return 0.0; 37601e04c3fSmrg case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 37701e04c3fSmrg return 16.0; /* arbitrary */ 37801e04c3fSmrg case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE: 37901e04c3fSmrg case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE: 38001e04c3fSmrg case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY: 38101e04c3fSmrg return 0.0f; 38201e04c3fSmrg } 38301e04c3fSmrg /* should only get here on unhandled cases */ 38401e04c3fSmrg debug_printf("Unexpected PIPE_CAPF %d query\n", param); 38501e04c3fSmrg return 0.0; 38601e04c3fSmrg} 38701e04c3fSmrg 38801e04c3fSmrgSWR_FORMAT 38901e04c3fSmrgmesa_to_swr_format(enum pipe_format format) 39001e04c3fSmrg{ 39101e04c3fSmrg static const std::map<pipe_format,SWR_FORMAT> mesa2swr = { 39201e04c3fSmrg /* depth / stencil */ 39301e04c3fSmrg {PIPE_FORMAT_Z16_UNORM, R16_UNORM}, // z 39401e04c3fSmrg {PIPE_FORMAT_Z32_FLOAT, R32_FLOAT}, // z 39501e04c3fSmrg {PIPE_FORMAT_Z24_UNORM_S8_UINT, R24_UNORM_X8_TYPELESS}, // z 39601e04c3fSmrg {PIPE_FORMAT_Z24X8_UNORM, R24_UNORM_X8_TYPELESS}, // z 39701e04c3fSmrg {PIPE_FORMAT_Z32_FLOAT_S8X24_UINT, R32_FLOAT_X8X24_TYPELESS}, // z 39801e04c3fSmrg 39901e04c3fSmrg /* alpha */ 40001e04c3fSmrg {PIPE_FORMAT_A8_UNORM, A8_UNORM}, 40101e04c3fSmrg {PIPE_FORMAT_A16_UNORM, A16_UNORM}, 40201e04c3fSmrg {PIPE_FORMAT_A16_FLOAT, A16_FLOAT}, 40301e04c3fSmrg {PIPE_FORMAT_A32_FLOAT, A32_FLOAT}, 40401e04c3fSmrg 40501e04c3fSmrg /* odd sizes, bgr */ 40601e04c3fSmrg {PIPE_FORMAT_B5G6R5_UNORM, B5G6R5_UNORM}, 40701e04c3fSmrg {PIPE_FORMAT_B5G6R5_SRGB, B5G6R5_UNORM_SRGB}, 40801e04c3fSmrg {PIPE_FORMAT_B5G5R5A1_UNORM, B5G5R5A1_UNORM}, 40901e04c3fSmrg {PIPE_FORMAT_B5G5R5X1_UNORM, B5G5R5X1_UNORM}, 41001e04c3fSmrg {PIPE_FORMAT_B4G4R4A4_UNORM, B4G4R4A4_UNORM}, 41101e04c3fSmrg {PIPE_FORMAT_B8G8R8A8_UNORM, B8G8R8A8_UNORM}, 41201e04c3fSmrg {PIPE_FORMAT_B8G8R8A8_SRGB, B8G8R8A8_UNORM_SRGB}, 41301e04c3fSmrg {PIPE_FORMAT_B8G8R8X8_UNORM, B8G8R8X8_UNORM}, 41401e04c3fSmrg {PIPE_FORMAT_B8G8R8X8_SRGB, B8G8R8X8_UNORM_SRGB}, 41501e04c3fSmrg 41601e04c3fSmrg /* rgb10a2 */ 41701e04c3fSmrg {PIPE_FORMAT_R10G10B10A2_UNORM, R10G10B10A2_UNORM}, 41801e04c3fSmrg {PIPE_FORMAT_R10G10B10A2_SNORM, R10G10B10A2_SNORM}, 41901e04c3fSmrg {PIPE_FORMAT_R10G10B10A2_USCALED, R10G10B10A2_USCALED}, 42001e04c3fSmrg {PIPE_FORMAT_R10G10B10A2_SSCALED, R10G10B10A2_SSCALED}, 42101e04c3fSmrg {PIPE_FORMAT_R10G10B10A2_UINT, R10G10B10A2_UINT}, 42201e04c3fSmrg 42301e04c3fSmrg /* rgb10x2 */ 42401e04c3fSmrg {PIPE_FORMAT_R10G10B10X2_USCALED, R10G10B10X2_USCALED}, 42501e04c3fSmrg 42601e04c3fSmrg /* bgr10a2 */ 42701e04c3fSmrg {PIPE_FORMAT_B10G10R10A2_UNORM, B10G10R10A2_UNORM}, 42801e04c3fSmrg {PIPE_FORMAT_B10G10R10A2_SNORM, B10G10R10A2_SNORM}, 42901e04c3fSmrg {PIPE_FORMAT_B10G10R10A2_USCALED, B10G10R10A2_USCALED}, 43001e04c3fSmrg {PIPE_FORMAT_B10G10R10A2_SSCALED, B10G10R10A2_SSCALED}, 43101e04c3fSmrg {PIPE_FORMAT_B10G10R10A2_UINT, B10G10R10A2_UINT}, 43201e04c3fSmrg 43301e04c3fSmrg /* bgr10x2 */ 43401e04c3fSmrg {PIPE_FORMAT_B10G10R10X2_UNORM, B10G10R10X2_UNORM}, 43501e04c3fSmrg 43601e04c3fSmrg /* r11g11b10 */ 43701e04c3fSmrg {PIPE_FORMAT_R11G11B10_FLOAT, R11G11B10_FLOAT}, 43801e04c3fSmrg 43901e04c3fSmrg /* 32 bits per component */ 44001e04c3fSmrg {PIPE_FORMAT_R32_FLOAT, R32_FLOAT}, 44101e04c3fSmrg {PIPE_FORMAT_R32G32_FLOAT, R32G32_FLOAT}, 44201e04c3fSmrg {PIPE_FORMAT_R32G32B32_FLOAT, R32G32B32_FLOAT}, 44301e04c3fSmrg {PIPE_FORMAT_R32G32B32A32_FLOAT, R32G32B32A32_FLOAT}, 44401e04c3fSmrg {PIPE_FORMAT_R32G32B32X32_FLOAT, R32G32B32X32_FLOAT}, 44501e04c3fSmrg 44601e04c3fSmrg {PIPE_FORMAT_R32_USCALED, R32_USCALED}, 44701e04c3fSmrg {PIPE_FORMAT_R32G32_USCALED, R32G32_USCALED}, 44801e04c3fSmrg {PIPE_FORMAT_R32G32B32_USCALED, R32G32B32_USCALED}, 44901e04c3fSmrg {PIPE_FORMAT_R32G32B32A32_USCALED, R32G32B32A32_USCALED}, 45001e04c3fSmrg 45101e04c3fSmrg {PIPE_FORMAT_R32_SSCALED, R32_SSCALED}, 45201e04c3fSmrg {PIPE_FORMAT_R32G32_SSCALED, R32G32_SSCALED}, 45301e04c3fSmrg {PIPE_FORMAT_R32G32B32_SSCALED, R32G32B32_SSCALED}, 45401e04c3fSmrg {PIPE_FORMAT_R32G32B32A32_SSCALED, R32G32B32A32_SSCALED}, 45501e04c3fSmrg 45601e04c3fSmrg {PIPE_FORMAT_R32_UINT, R32_UINT}, 45701e04c3fSmrg {PIPE_FORMAT_R32G32_UINT, R32G32_UINT}, 45801e04c3fSmrg {PIPE_FORMAT_R32G32B32_UINT, R32G32B32_UINT}, 45901e04c3fSmrg {PIPE_FORMAT_R32G32B32A32_UINT, R32G32B32A32_UINT}, 46001e04c3fSmrg 46101e04c3fSmrg {PIPE_FORMAT_R32_SINT, R32_SINT}, 46201e04c3fSmrg {PIPE_FORMAT_R32G32_SINT, R32G32_SINT}, 46301e04c3fSmrg {PIPE_FORMAT_R32G32B32_SINT, R32G32B32_SINT}, 46401e04c3fSmrg {PIPE_FORMAT_R32G32B32A32_SINT, R32G32B32A32_SINT}, 46501e04c3fSmrg 46601e04c3fSmrg /* 16 bits per component */ 46701e04c3fSmrg {PIPE_FORMAT_R16_UNORM, R16_UNORM}, 46801e04c3fSmrg {PIPE_FORMAT_R16G16_UNORM, R16G16_UNORM}, 46901e04c3fSmrg {PIPE_FORMAT_R16G16B16_UNORM, R16G16B16_UNORM}, 47001e04c3fSmrg {PIPE_FORMAT_R16G16B16A16_UNORM, R16G16B16A16_UNORM}, 47101e04c3fSmrg {PIPE_FORMAT_R16G16B16X16_UNORM, R16G16B16X16_UNORM}, 47201e04c3fSmrg 47301e04c3fSmrg {PIPE_FORMAT_R16_USCALED, R16_USCALED}, 47401e04c3fSmrg {PIPE_FORMAT_R16G16_USCALED, R16G16_USCALED}, 47501e04c3fSmrg {PIPE_FORMAT_R16G16B16_USCALED, R16G16B16_USCALED}, 47601e04c3fSmrg {PIPE_FORMAT_R16G16B16A16_USCALED, R16G16B16A16_USCALED}, 47701e04c3fSmrg 47801e04c3fSmrg {PIPE_FORMAT_R16_SNORM, R16_SNORM}, 47901e04c3fSmrg {PIPE_FORMAT_R16G16_SNORM, R16G16_SNORM}, 48001e04c3fSmrg {PIPE_FORMAT_R16G16B16_SNORM, R16G16B16_SNORM}, 48101e04c3fSmrg {PIPE_FORMAT_R16G16B16A16_SNORM, R16G16B16A16_SNORM}, 48201e04c3fSmrg 48301e04c3fSmrg {PIPE_FORMAT_R16_SSCALED, R16_SSCALED}, 48401e04c3fSmrg {PIPE_FORMAT_R16G16_SSCALED, R16G16_SSCALED}, 48501e04c3fSmrg {PIPE_FORMAT_R16G16B16_SSCALED, R16G16B16_SSCALED}, 48601e04c3fSmrg {PIPE_FORMAT_R16G16B16A16_SSCALED, R16G16B16A16_SSCALED}, 48701e04c3fSmrg 48801e04c3fSmrg {PIPE_FORMAT_R16_UINT, R16_UINT}, 48901e04c3fSmrg {PIPE_FORMAT_R16G16_UINT, R16G16_UINT}, 49001e04c3fSmrg {PIPE_FORMAT_R16G16B16_UINT, R16G16B16_UINT}, 49101e04c3fSmrg {PIPE_FORMAT_R16G16B16A16_UINT, R16G16B16A16_UINT}, 49201e04c3fSmrg 49301e04c3fSmrg {PIPE_FORMAT_R16_SINT, R16_SINT}, 49401e04c3fSmrg {PIPE_FORMAT_R16G16_SINT, R16G16_SINT}, 49501e04c3fSmrg {PIPE_FORMAT_R16G16B16_SINT, R16G16B16_SINT}, 49601e04c3fSmrg {PIPE_FORMAT_R16G16B16A16_SINT, R16G16B16A16_SINT}, 49701e04c3fSmrg 49801e04c3fSmrg {PIPE_FORMAT_R16_FLOAT, R16_FLOAT}, 49901e04c3fSmrg {PIPE_FORMAT_R16G16_FLOAT, R16G16_FLOAT}, 50001e04c3fSmrg {PIPE_FORMAT_R16G16B16_FLOAT, R16G16B16_FLOAT}, 50101e04c3fSmrg {PIPE_FORMAT_R16G16B16A16_FLOAT, R16G16B16A16_FLOAT}, 50201e04c3fSmrg {PIPE_FORMAT_R16G16B16X16_FLOAT, R16G16B16X16_FLOAT}, 50301e04c3fSmrg 50401e04c3fSmrg /* 8 bits per component */ 50501e04c3fSmrg {PIPE_FORMAT_R8_UNORM, R8_UNORM}, 50601e04c3fSmrg {PIPE_FORMAT_R8G8_UNORM, R8G8_UNORM}, 50701e04c3fSmrg {PIPE_FORMAT_R8G8B8_UNORM, R8G8B8_UNORM}, 50801e04c3fSmrg {PIPE_FORMAT_R8G8B8_SRGB, R8G8B8_UNORM_SRGB}, 50901e04c3fSmrg {PIPE_FORMAT_R8G8B8A8_UNORM, R8G8B8A8_UNORM}, 51001e04c3fSmrg {PIPE_FORMAT_R8G8B8A8_SRGB, R8G8B8A8_UNORM_SRGB}, 51101e04c3fSmrg {PIPE_FORMAT_R8G8B8X8_UNORM, R8G8B8X8_UNORM}, 51201e04c3fSmrg {PIPE_FORMAT_R8G8B8X8_SRGB, R8G8B8X8_UNORM_SRGB}, 51301e04c3fSmrg 51401e04c3fSmrg {PIPE_FORMAT_R8_USCALED, R8_USCALED}, 51501e04c3fSmrg {PIPE_FORMAT_R8G8_USCALED, R8G8_USCALED}, 51601e04c3fSmrg {PIPE_FORMAT_R8G8B8_USCALED, R8G8B8_USCALED}, 51701e04c3fSmrg {PIPE_FORMAT_R8G8B8A8_USCALED, R8G8B8A8_USCALED}, 51801e04c3fSmrg 51901e04c3fSmrg {PIPE_FORMAT_R8_SNORM, R8_SNORM}, 52001e04c3fSmrg {PIPE_FORMAT_R8G8_SNORM, R8G8_SNORM}, 52101e04c3fSmrg {PIPE_FORMAT_R8G8B8_SNORM, R8G8B8_SNORM}, 52201e04c3fSmrg {PIPE_FORMAT_R8G8B8A8_SNORM, R8G8B8A8_SNORM}, 52301e04c3fSmrg 52401e04c3fSmrg {PIPE_FORMAT_R8_SSCALED, R8_SSCALED}, 52501e04c3fSmrg {PIPE_FORMAT_R8G8_SSCALED, R8G8_SSCALED}, 52601e04c3fSmrg {PIPE_FORMAT_R8G8B8_SSCALED, R8G8B8_SSCALED}, 52701e04c3fSmrg {PIPE_FORMAT_R8G8B8A8_SSCALED, R8G8B8A8_SSCALED}, 52801e04c3fSmrg 52901e04c3fSmrg {PIPE_FORMAT_R8_UINT, R8_UINT}, 53001e04c3fSmrg {PIPE_FORMAT_R8G8_UINT, R8G8_UINT}, 53101e04c3fSmrg {PIPE_FORMAT_R8G8B8_UINT, R8G8B8_UINT}, 53201e04c3fSmrg {PIPE_FORMAT_R8G8B8A8_UINT, R8G8B8A8_UINT}, 53301e04c3fSmrg 53401e04c3fSmrg {PIPE_FORMAT_R8_SINT, R8_SINT}, 53501e04c3fSmrg {PIPE_FORMAT_R8G8_SINT, R8G8_SINT}, 53601e04c3fSmrg {PIPE_FORMAT_R8G8B8_SINT, R8G8B8_SINT}, 53701e04c3fSmrg {PIPE_FORMAT_R8G8B8A8_SINT, R8G8B8A8_SINT}, 53801e04c3fSmrg 53901e04c3fSmrg /* These formats are valid for vertex data, but should not be used 54001e04c3fSmrg * for render targets. 54101e04c3fSmrg */ 54201e04c3fSmrg 54301e04c3fSmrg {PIPE_FORMAT_R32_FIXED, R32_SFIXED}, 54401e04c3fSmrg {PIPE_FORMAT_R32G32_FIXED, R32G32_SFIXED}, 54501e04c3fSmrg {PIPE_FORMAT_R32G32B32_FIXED, R32G32B32_SFIXED}, 54601e04c3fSmrg {PIPE_FORMAT_R32G32B32A32_FIXED, R32G32B32A32_SFIXED}, 54701e04c3fSmrg 54801e04c3fSmrg {PIPE_FORMAT_R64_FLOAT, R64_FLOAT}, 54901e04c3fSmrg {PIPE_FORMAT_R64G64_FLOAT, R64G64_FLOAT}, 55001e04c3fSmrg {PIPE_FORMAT_R64G64B64_FLOAT, R64G64B64_FLOAT}, 55101e04c3fSmrg {PIPE_FORMAT_R64G64B64A64_FLOAT, R64G64B64A64_FLOAT}, 55201e04c3fSmrg 55301e04c3fSmrg /* These formats have entries in SWR but don't have Load/StoreTile 55401e04c3fSmrg * implementations. That means these aren't renderable, and thus having 55501e04c3fSmrg * a mapping entry here is detrimental. 55601e04c3fSmrg */ 55701e04c3fSmrg /* 55801e04c3fSmrg 55901e04c3fSmrg {PIPE_FORMAT_L8_UNORM, L8_UNORM}, 56001e04c3fSmrg {PIPE_FORMAT_I8_UNORM, I8_UNORM}, 56101e04c3fSmrg {PIPE_FORMAT_L8A8_UNORM, L8A8_UNORM}, 56201e04c3fSmrg {PIPE_FORMAT_L16_UNORM, L16_UNORM}, 56301e04c3fSmrg {PIPE_FORMAT_UYVY, YCRCB_SWAPUVY}, 56401e04c3fSmrg 56501e04c3fSmrg {PIPE_FORMAT_L8_SRGB, L8_UNORM_SRGB}, 56601e04c3fSmrg {PIPE_FORMAT_L8A8_SRGB, L8A8_UNORM_SRGB}, 56701e04c3fSmrg 56801e04c3fSmrg {PIPE_FORMAT_DXT1_RGBA, BC1_UNORM}, 56901e04c3fSmrg {PIPE_FORMAT_DXT3_RGBA, BC2_UNORM}, 57001e04c3fSmrg {PIPE_FORMAT_DXT5_RGBA, BC3_UNORM}, 57101e04c3fSmrg 57201e04c3fSmrg {PIPE_FORMAT_DXT1_SRGBA, BC1_UNORM_SRGB}, 57301e04c3fSmrg {PIPE_FORMAT_DXT3_SRGBA, BC2_UNORM_SRGB}, 57401e04c3fSmrg {PIPE_FORMAT_DXT5_SRGBA, BC3_UNORM_SRGB}, 57501e04c3fSmrg 57601e04c3fSmrg {PIPE_FORMAT_RGTC1_UNORM, BC4_UNORM}, 57701e04c3fSmrg {PIPE_FORMAT_RGTC1_SNORM, BC4_SNORM}, 57801e04c3fSmrg {PIPE_FORMAT_RGTC2_UNORM, BC5_UNORM}, 57901e04c3fSmrg {PIPE_FORMAT_RGTC2_SNORM, BC5_SNORM}, 58001e04c3fSmrg 58101e04c3fSmrg {PIPE_FORMAT_L16A16_UNORM, L16A16_UNORM}, 58201e04c3fSmrg {PIPE_FORMAT_I16_UNORM, I16_UNORM}, 58301e04c3fSmrg {PIPE_FORMAT_L16_FLOAT, L16_FLOAT}, 58401e04c3fSmrg {PIPE_FORMAT_L16A16_FLOAT, L16A16_FLOAT}, 58501e04c3fSmrg {PIPE_FORMAT_I16_FLOAT, I16_FLOAT}, 58601e04c3fSmrg {PIPE_FORMAT_L32_FLOAT, L32_FLOAT}, 58701e04c3fSmrg {PIPE_FORMAT_L32A32_FLOAT, L32A32_FLOAT}, 58801e04c3fSmrg {PIPE_FORMAT_I32_FLOAT, I32_FLOAT}, 58901e04c3fSmrg 59001e04c3fSmrg {PIPE_FORMAT_I8_UINT, I8_UINT}, 59101e04c3fSmrg {PIPE_FORMAT_L8_UINT, L8_UINT}, 59201e04c3fSmrg {PIPE_FORMAT_L8A8_UINT, L8A8_UINT}, 59301e04c3fSmrg 59401e04c3fSmrg {PIPE_FORMAT_I8_SINT, I8_SINT}, 59501e04c3fSmrg {PIPE_FORMAT_L8_SINT, L8_SINT}, 59601e04c3fSmrg {PIPE_FORMAT_L8A8_SINT, L8A8_SINT}, 59701e04c3fSmrg 59801e04c3fSmrg */ 59901e04c3fSmrg }; 60001e04c3fSmrg 60101e04c3fSmrg auto it = mesa2swr.find(format); 60201e04c3fSmrg if (it == mesa2swr.end()) 60301e04c3fSmrg return (SWR_FORMAT)-1; 60401e04c3fSmrg else 60501e04c3fSmrg return it->second; 60601e04c3fSmrg} 60701e04c3fSmrg 6087ec681f3Smrgstatic bool 60901e04c3fSmrgswr_displaytarget_layout(struct swr_screen *screen, struct swr_resource *res) 61001e04c3fSmrg{ 61101e04c3fSmrg struct sw_winsys *winsys = screen->winsys; 61201e04c3fSmrg struct sw_displaytarget *dt; 61301e04c3fSmrg 61401e04c3fSmrg const unsigned width = align(res->swr.width, res->swr.halign); 61501e04c3fSmrg const unsigned height = align(res->swr.height, res->swr.valign); 61601e04c3fSmrg 61701e04c3fSmrg UINT stride; 61801e04c3fSmrg dt = winsys->displaytarget_create(winsys, 61901e04c3fSmrg res->base.bind, 62001e04c3fSmrg res->base.format, 62101e04c3fSmrg width, height, 62201e04c3fSmrg 64, NULL, 62301e04c3fSmrg &stride); 62401e04c3fSmrg 62501e04c3fSmrg if (dt == NULL) 6267ec681f3Smrg return false; 62701e04c3fSmrg 62801e04c3fSmrg void *map = winsys->displaytarget_map(winsys, dt, 0); 62901e04c3fSmrg 63001e04c3fSmrg res->display_target = dt; 63101e04c3fSmrg res->swr.xpBaseAddress = (gfxptr_t)map; 63201e04c3fSmrg 63301e04c3fSmrg /* Clear the display target surface */ 63401e04c3fSmrg if (map) 63501e04c3fSmrg memset(map, 0, height * stride); 63601e04c3fSmrg 63701e04c3fSmrg winsys->displaytarget_unmap(winsys, dt); 63801e04c3fSmrg 6397ec681f3Smrg return true; 64001e04c3fSmrg} 64101e04c3fSmrg 64201e04c3fSmrgstatic bool 64301e04c3fSmrgswr_texture_layout(struct swr_screen *screen, 64401e04c3fSmrg struct swr_resource *res, 6457ec681f3Smrg bool allocate) 64601e04c3fSmrg{ 64701e04c3fSmrg struct pipe_resource *pt = &res->base; 64801e04c3fSmrg 64901e04c3fSmrg pipe_format fmt = pt->format; 65001e04c3fSmrg const struct util_format_description *desc = util_format_description(fmt); 65101e04c3fSmrg 65201e04c3fSmrg res->has_depth = util_format_has_depth(desc); 65301e04c3fSmrg res->has_stencil = util_format_has_stencil(desc); 65401e04c3fSmrg 65501e04c3fSmrg if (res->has_stencil && !res->has_depth) 65601e04c3fSmrg fmt = PIPE_FORMAT_R8_UINT; 65701e04c3fSmrg 65801e04c3fSmrg /* We always use the SWR layout. For 2D and 3D textures this looks like: 65901e04c3fSmrg * 66001e04c3fSmrg * |<------- pitch ------->| 66101e04c3fSmrg * +=======================+------- 66201e04c3fSmrg * |Array 0 | ^ 66301e04c3fSmrg * | | | 66401e04c3fSmrg * | Level 0 | | 66501e04c3fSmrg * | | | 66601e04c3fSmrg * | | qpitch 66701e04c3fSmrg * +-----------+-----------+ | 66801e04c3fSmrg * | | L2L2L2L2 | | 66901e04c3fSmrg * | Level 1 | L3L3 | | 67001e04c3fSmrg * | | L4 | v 67101e04c3fSmrg * +===========+===========+------- 67201e04c3fSmrg * |Array 1 | 67301e04c3fSmrg * | | 67401e04c3fSmrg * | Level 0 | 67501e04c3fSmrg * | | 67601e04c3fSmrg * | | 67701e04c3fSmrg * +-----------+-----------+ 67801e04c3fSmrg * | | L2L2L2L2 | 67901e04c3fSmrg * | Level 1 | L3L3 | 68001e04c3fSmrg * | | L4 | 68101e04c3fSmrg * +===========+===========+ 68201e04c3fSmrg * 68301e04c3fSmrg * The overall width in bytes is known as the pitch, while the overall 68401e04c3fSmrg * height in rows is the qpitch. Array slices are laid out logically below 68501e04c3fSmrg * one another, qpitch rows apart. For 3D surfaces, the "level" values are 68601e04c3fSmrg * just invalid for the higher array numbers (since depth is also 68701e04c3fSmrg * minified). 1D and 1D array surfaces are stored effectively the same way, 68801e04c3fSmrg * except that pitch never plays into it. All the levels are logically 68901e04c3fSmrg * adjacent to each other on the X axis. The qpitch becomes the number of 69001e04c3fSmrg * elements between array slices, while the pitch is unused. 69101e04c3fSmrg * 69201e04c3fSmrg * Each level's sizes are subject to the valign and halign settings of the 69301e04c3fSmrg * surface. For compressed formats that swr is unaware of, we will use an 69401e04c3fSmrg * appropriately-sized uncompressed format, and scale the widths/heights. 69501e04c3fSmrg * 69601e04c3fSmrg * This surface is stored inside res->swr. For depth/stencil textures, 69701e04c3fSmrg * res->secondary will have an identically-laid-out but R8_UINT-formatted 69801e04c3fSmrg * stencil tree. In the Z32F_S8 case, the primary surface still has 64-bpp 69901e04c3fSmrg * texels, to simplify map/unmap logic which copies the stencil values 70001e04c3fSmrg * in/out. 70101e04c3fSmrg */ 70201e04c3fSmrg 70301e04c3fSmrg res->swr.width = pt->width0; 70401e04c3fSmrg res->swr.height = pt->height0; 70501e04c3fSmrg res->swr.type = swr_convert_target_type(pt->target); 70601e04c3fSmrg res->swr.tileMode = SWR_TILE_NONE; 70701e04c3fSmrg res->swr.format = mesa_to_swr_format(fmt); 70801e04c3fSmrg res->swr.numSamples = std::max(1u, pt->nr_samples); 70901e04c3fSmrg 71001e04c3fSmrg if (pt->bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL)) { 71101e04c3fSmrg res->swr.halign = KNOB_MACROTILE_X_DIM; 71201e04c3fSmrg res->swr.valign = KNOB_MACROTILE_Y_DIM; 71301e04c3fSmrg 71401e04c3fSmrg /* If SWR_MSAA_FORCE_ENABLE is set, turn on MSAA and override requested 71501e04c3fSmrg * surface sample count. */ 71601e04c3fSmrg if (screen->msaa_force_enable) { 71701e04c3fSmrg res->swr.numSamples = screen->msaa_max_count; 7187ec681f3Smrg swr_print_info("swr_texture_layout: forcing sample count: %d\n", 71901e04c3fSmrg res->swr.numSamples); 72001e04c3fSmrg } 72101e04c3fSmrg } else { 72201e04c3fSmrg res->swr.halign = 1; 72301e04c3fSmrg res->swr.valign = 1; 72401e04c3fSmrg } 72501e04c3fSmrg 72601e04c3fSmrg unsigned halign = res->swr.halign * util_format_get_blockwidth(fmt); 72701e04c3fSmrg unsigned width = align(pt->width0, halign); 72801e04c3fSmrg if (pt->target == PIPE_TEXTURE_1D || pt->target == PIPE_TEXTURE_1D_ARRAY) { 72901e04c3fSmrg for (int level = 1; level <= pt->last_level; level++) 73001e04c3fSmrg width += align(u_minify(pt->width0, level), halign); 73101e04c3fSmrg res->swr.pitch = util_format_get_blocksize(fmt); 73201e04c3fSmrg res->swr.qpitch = util_format_get_nblocksx(fmt, width); 73301e04c3fSmrg } else { 73401e04c3fSmrg // The pitch is the overall width of the texture in bytes. Most of the 73501e04c3fSmrg // time this is the pitch of level 0 since all the other levels fit 73601e04c3fSmrg // underneath it. However in some degenerate situations, the width of 73701e04c3fSmrg // level1 + level2 may be larger. In that case, we use those 73801e04c3fSmrg // widths. This can happen if, e.g. halign is 32, and the width of level 73901e04c3fSmrg // 0 is 32 or less. In that case, the aligned levels 1 and 2 will also 74001e04c3fSmrg // be 32 each, adding up to 64. 74101e04c3fSmrg unsigned valign = res->swr.valign * util_format_get_blockheight(fmt); 74201e04c3fSmrg if (pt->last_level > 1) { 74301e04c3fSmrg width = std::max<uint32_t>( 74401e04c3fSmrg width, 74501e04c3fSmrg align(u_minify(pt->width0, 1), halign) + 74601e04c3fSmrg align(u_minify(pt->width0, 2), halign)); 74701e04c3fSmrg } 74801e04c3fSmrg res->swr.pitch = util_format_get_stride(fmt, width); 74901e04c3fSmrg 75001e04c3fSmrg // The qpitch is controlled by either the height of the second LOD, or 75101e04c3fSmrg // the combination of all the later LODs. 75201e04c3fSmrg unsigned height = align(pt->height0, valign); 75301e04c3fSmrg if (pt->last_level == 1) { 75401e04c3fSmrg height += align(u_minify(pt->height0, 1), valign); 75501e04c3fSmrg } else if (pt->last_level > 1) { 75601e04c3fSmrg unsigned level1 = align(u_minify(pt->height0, 1), valign); 75701e04c3fSmrg unsigned level2 = 0; 75801e04c3fSmrg for (int level = 2; level <= pt->last_level; level++) { 75901e04c3fSmrg level2 += align(u_minify(pt->height0, level), valign); 76001e04c3fSmrg } 76101e04c3fSmrg height += std::max(level1, level2); 76201e04c3fSmrg } 76301e04c3fSmrg res->swr.qpitch = util_format_get_nblocksy(fmt, height); 76401e04c3fSmrg } 76501e04c3fSmrg 76601e04c3fSmrg if (pt->target == PIPE_TEXTURE_3D) 76701e04c3fSmrg res->swr.depth = pt->depth0; 76801e04c3fSmrg else 76901e04c3fSmrg res->swr.depth = pt->array_size; 77001e04c3fSmrg 77101e04c3fSmrg // Fix up swr format if necessary so that LOD offset computation works 77201e04c3fSmrg if (res->swr.format == (SWR_FORMAT)-1) { 77301e04c3fSmrg switch (util_format_get_blocksize(fmt)) { 77401e04c3fSmrg default: 77501e04c3fSmrg unreachable("Unexpected format block size"); 77601e04c3fSmrg case 1: res->swr.format = R8_UINT; break; 77701e04c3fSmrg case 2: res->swr.format = R16_UINT; break; 77801e04c3fSmrg case 4: res->swr.format = R32_UINT; break; 77901e04c3fSmrg case 8: 78001e04c3fSmrg if (util_format_is_compressed(fmt)) 78101e04c3fSmrg res->swr.format = BC4_UNORM; 78201e04c3fSmrg else 78301e04c3fSmrg res->swr.format = R32G32_UINT; 78401e04c3fSmrg break; 78501e04c3fSmrg case 16: 78601e04c3fSmrg if (util_format_is_compressed(fmt)) 78701e04c3fSmrg res->swr.format = BC5_UNORM; 78801e04c3fSmrg else 78901e04c3fSmrg res->swr.format = R32G32B32A32_UINT; 79001e04c3fSmrg break; 79101e04c3fSmrg } 79201e04c3fSmrg } 79301e04c3fSmrg 79401e04c3fSmrg for (int level = 0; level <= pt->last_level; level++) { 79501e04c3fSmrg res->mip_offsets[level] = 79601e04c3fSmrg ComputeSurfaceOffset<false>(0, 0, 0, 0, 0, level, &res->swr); 79701e04c3fSmrg } 79801e04c3fSmrg 79901e04c3fSmrg size_t total_size = (uint64_t)res->swr.depth * res->swr.qpitch * 80001e04c3fSmrg res->swr.pitch * res->swr.numSamples; 801993e1d59Smrg 802993e1d59Smrg // Let non-sampled textures (e.g. buffer objects) bypass the size limit 803993e1d59Smrg if (swr_resource_is_texture(&res->base) && total_size > SWR_MAX_TEXTURE_SIZE) 80401e04c3fSmrg return false; 80501e04c3fSmrg 80601e04c3fSmrg if (allocate) { 80701e04c3fSmrg res->swr.xpBaseAddress = (gfxptr_t)AlignedMalloc(total_size, 64); 80801e04c3fSmrg if (!res->swr.xpBaseAddress) 80901e04c3fSmrg return false; 81001e04c3fSmrg 81101e04c3fSmrg if (res->has_depth && res->has_stencil) { 81201e04c3fSmrg res->secondary = res->swr; 81301e04c3fSmrg res->secondary.format = R8_UINT; 81401e04c3fSmrg res->secondary.pitch = res->swr.pitch / util_format_get_blocksize(fmt); 81501e04c3fSmrg 81601e04c3fSmrg for (int level = 0; level <= pt->last_level; level++) { 81701e04c3fSmrg res->secondary_mip_offsets[level] = 81801e04c3fSmrg ComputeSurfaceOffset<false>(0, 0, 0, 0, 0, level, &res->secondary); 81901e04c3fSmrg } 82001e04c3fSmrg 82101e04c3fSmrg total_size = res->secondary.depth * res->secondary.qpitch * 82201e04c3fSmrg res->secondary.pitch * res->secondary.numSamples; 82301e04c3fSmrg 82401e04c3fSmrg res->secondary.xpBaseAddress = (gfxptr_t) AlignedMalloc(total_size, 64); 82501e04c3fSmrg if (!res->secondary.xpBaseAddress) { 82601e04c3fSmrg AlignedFree((void *)res->swr.xpBaseAddress); 82701e04c3fSmrg return false; 82801e04c3fSmrg } 82901e04c3fSmrg } 83001e04c3fSmrg } 83101e04c3fSmrg 83201e04c3fSmrg return true; 83301e04c3fSmrg} 83401e04c3fSmrg 8357ec681f3Smrgstatic bool 83601e04c3fSmrgswr_can_create_resource(struct pipe_screen *screen, 83701e04c3fSmrg const struct pipe_resource *templat) 83801e04c3fSmrg{ 83901e04c3fSmrg struct swr_resource res; 84001e04c3fSmrg memset(&res, 0, sizeof(res)); 84101e04c3fSmrg res.base = *templat; 84201e04c3fSmrg return swr_texture_layout(swr_screen(screen), &res, false); 84301e04c3fSmrg} 84401e04c3fSmrg 84501e04c3fSmrg/* Helper function that conditionally creates a single-sample resolve resource 84601e04c3fSmrg * and attaches it to main multisample resource. */ 8477ec681f3Smrgstatic bool 84801e04c3fSmrgswr_create_resolve_resource(struct pipe_screen *_screen, 84901e04c3fSmrg struct swr_resource *msaa_res) 85001e04c3fSmrg{ 85101e04c3fSmrg struct swr_screen *screen = swr_screen(_screen); 85201e04c3fSmrg 85301e04c3fSmrg /* If resource is multisample, create a single-sample resolve resource */ 85401e04c3fSmrg if (msaa_res->base.nr_samples > 1 || (screen->msaa_force_enable && 85501e04c3fSmrg !(msaa_res->base.flags & SWR_RESOURCE_FLAG_ALT_SURFACE))) { 85601e04c3fSmrg 85701e04c3fSmrg /* Create a single-sample copy of the resource. Copy the original 85801e04c3fSmrg * resource parameters and set flag to prevent recursion when re-calling 85901e04c3fSmrg * resource_create */ 86001e04c3fSmrg struct pipe_resource alt_template = msaa_res->base; 86101e04c3fSmrg alt_template.nr_samples = 0; 86201e04c3fSmrg alt_template.flags |= SWR_RESOURCE_FLAG_ALT_SURFACE; 86301e04c3fSmrg 86401e04c3fSmrg /* Note: Display_target is a special single-sample resource, only the 86501e04c3fSmrg * display_target has been created already. */ 86601e04c3fSmrg if (msaa_res->base.bind & (PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT 86701e04c3fSmrg | PIPE_BIND_SHARED)) { 86801e04c3fSmrg /* Allocate the multisample buffers. */ 86901e04c3fSmrg if (!swr_texture_layout(screen, msaa_res, true)) 87001e04c3fSmrg return false; 87101e04c3fSmrg 87201e04c3fSmrg /* Alt resource will only be bound as PIPE_BIND_RENDER_TARGET 87301e04c3fSmrg * remove the DISPLAY_TARGET, SCANOUT, and SHARED bindings */ 87401e04c3fSmrg alt_template.bind = PIPE_BIND_RENDER_TARGET; 87501e04c3fSmrg } 87601e04c3fSmrg 87701e04c3fSmrg /* Allocate single-sample resolve surface */ 87801e04c3fSmrg struct pipe_resource *alt; 87901e04c3fSmrg alt = _screen->resource_create(_screen, &alt_template); 88001e04c3fSmrg if (!alt) 88101e04c3fSmrg return false; 88201e04c3fSmrg 88301e04c3fSmrg /* Attach it to the multisample resource */ 88401e04c3fSmrg msaa_res->resolve_target = alt; 88501e04c3fSmrg 88601e04c3fSmrg /* Hang resolve surface state off the multisample surface state to so 88701e04c3fSmrg * StoreTiles knows where to resolve the surface. */ 88801e04c3fSmrg msaa_res->swr.xpAuxBaseAddress = (gfxptr_t)&swr_resource(alt)->swr; 88901e04c3fSmrg } 89001e04c3fSmrg 89101e04c3fSmrg return true; /* success */ 89201e04c3fSmrg} 89301e04c3fSmrg 89401e04c3fSmrgstatic struct pipe_resource * 89501e04c3fSmrgswr_resource_create(struct pipe_screen *_screen, 89601e04c3fSmrg const struct pipe_resource *templat) 89701e04c3fSmrg{ 89801e04c3fSmrg struct swr_screen *screen = swr_screen(_screen); 89901e04c3fSmrg struct swr_resource *res = CALLOC_STRUCT(swr_resource); 90001e04c3fSmrg if (!res) 90101e04c3fSmrg return NULL; 90201e04c3fSmrg 90301e04c3fSmrg res->base = *templat; 90401e04c3fSmrg pipe_reference_init(&res->base.reference, 1); 90501e04c3fSmrg res->base.screen = &screen->base; 90601e04c3fSmrg 90701e04c3fSmrg if (swr_resource_is_texture(&res->base)) { 90801e04c3fSmrg if (res->base.bind & (PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT 90901e04c3fSmrg | PIPE_BIND_SHARED)) { 91001e04c3fSmrg /* displayable surface 91101e04c3fSmrg * first call swr_texture_layout without allocating to finish 91201e04c3fSmrg * filling out the SWR_SURFACE_STATE in res */ 91301e04c3fSmrg swr_texture_layout(screen, res, false); 91401e04c3fSmrg if (!swr_displaytarget_layout(screen, res)) 91501e04c3fSmrg goto fail; 91601e04c3fSmrg } else { 91701e04c3fSmrg /* texture map */ 91801e04c3fSmrg if (!swr_texture_layout(screen, res, true)) 91901e04c3fSmrg goto fail; 92001e04c3fSmrg } 92101e04c3fSmrg 92201e04c3fSmrg /* If resource was multisample, create resolve resource and attach 92301e04c3fSmrg * it to multisample resource. */ 92401e04c3fSmrg if (!swr_create_resolve_resource(_screen, res)) 92501e04c3fSmrg goto fail; 92601e04c3fSmrg 92701e04c3fSmrg } else { 92801e04c3fSmrg /* other data (vertex buffer, const buffer, etc) */ 92901e04c3fSmrg assert(util_format_get_blocksize(templat->format) == 1); 93001e04c3fSmrg assert(templat->height0 == 1); 93101e04c3fSmrg assert(templat->depth0 == 1); 93201e04c3fSmrg assert(templat->last_level == 0); 93301e04c3fSmrg 93401e04c3fSmrg /* Easiest to just call swr_texture_layout, as it sets up 93501e04c3fSmrg * SWR_SURFACE_STATE in res */ 93601e04c3fSmrg if (!swr_texture_layout(screen, res, true)) 93701e04c3fSmrg goto fail; 93801e04c3fSmrg } 93901e04c3fSmrg 94001e04c3fSmrg return &res->base; 94101e04c3fSmrg 94201e04c3fSmrgfail: 94301e04c3fSmrg FREE(res); 94401e04c3fSmrg return NULL; 94501e04c3fSmrg} 94601e04c3fSmrg 94701e04c3fSmrgstatic void 94801e04c3fSmrgswr_resource_destroy(struct pipe_screen *p_screen, struct pipe_resource *pt) 94901e04c3fSmrg{ 95001e04c3fSmrg struct swr_screen *screen = swr_screen(p_screen); 95101e04c3fSmrg struct swr_resource *spr = swr_resource(pt); 95201e04c3fSmrg 95301e04c3fSmrg if (spr->display_target) { 95401e04c3fSmrg /* If resource is display target, winsys manages the buffer and will 95501e04c3fSmrg * free it on displaytarget_destroy. */ 95601e04c3fSmrg swr_fence_finish(p_screen, NULL, screen->flush_fence, 0); 95701e04c3fSmrg 95801e04c3fSmrg struct sw_winsys *winsys = screen->winsys; 95901e04c3fSmrg winsys->displaytarget_destroy(winsys, spr->display_target); 96001e04c3fSmrg 96101e04c3fSmrg if (spr->swr.numSamples > 1) { 96201e04c3fSmrg /* Free an attached resolve resource */ 96301e04c3fSmrg struct swr_resource *alt = swr_resource(spr->resolve_target); 96401e04c3fSmrg swr_fence_work_free(screen->flush_fence, (void*)(alt->swr.xpBaseAddress), true); 96501e04c3fSmrg 96601e04c3fSmrg /* Free multisample buffer */ 96701e04c3fSmrg swr_fence_work_free(screen->flush_fence, (void*)(spr->swr.xpBaseAddress), true); 96801e04c3fSmrg } 96901e04c3fSmrg } else { 97001e04c3fSmrg /* For regular resources, defer deletion */ 97101e04c3fSmrg swr_resource_unused(pt); 97201e04c3fSmrg 97301e04c3fSmrg if (spr->swr.numSamples > 1) { 97401e04c3fSmrg /* Free an attached resolve resource */ 97501e04c3fSmrg struct swr_resource *alt = swr_resource(spr->resolve_target); 97601e04c3fSmrg swr_fence_work_free(screen->flush_fence, (void*)(alt->swr.xpBaseAddress), true); 97701e04c3fSmrg } 97801e04c3fSmrg 97901e04c3fSmrg swr_fence_work_free(screen->flush_fence, (void*)(spr->swr.xpBaseAddress), true); 98001e04c3fSmrg swr_fence_work_free(screen->flush_fence, 98101e04c3fSmrg (void*)(spr->secondary.xpBaseAddress), true); 98201e04c3fSmrg 98301e04c3fSmrg /* If work queue grows too large, submit a fence to force queue to 98401e04c3fSmrg * drain. This is mainly to decrease the amount of memory used by the 98501e04c3fSmrg * piglit streaming-texture-leak test */ 98601e04c3fSmrg if (screen->pipe && swr_fence(screen->flush_fence)->work.count > 64) 98701e04c3fSmrg swr_fence_submit(swr_context(screen->pipe), screen->flush_fence); 98801e04c3fSmrg } 98901e04c3fSmrg 99001e04c3fSmrg FREE(spr); 99101e04c3fSmrg} 99201e04c3fSmrg 99301e04c3fSmrg 99401e04c3fSmrgstatic void 99501e04c3fSmrgswr_flush_frontbuffer(struct pipe_screen *p_screen, 9967ec681f3Smrg struct pipe_context *pipe, 99701e04c3fSmrg struct pipe_resource *resource, 99801e04c3fSmrg unsigned level, 99901e04c3fSmrg unsigned layer, 100001e04c3fSmrg void *context_private, 100101e04c3fSmrg struct pipe_box *sub_box) 100201e04c3fSmrg{ 100301e04c3fSmrg struct swr_screen *screen = swr_screen(p_screen); 100401e04c3fSmrg struct sw_winsys *winsys = screen->winsys; 100501e04c3fSmrg struct swr_resource *spr = swr_resource(resource); 100601e04c3fSmrg struct swr_context *ctx = swr_context(pipe); 100701e04c3fSmrg 100801e04c3fSmrg if (pipe) { 100901e04c3fSmrg swr_fence_finish(p_screen, NULL, screen->flush_fence, 0); 101001e04c3fSmrg swr_resource_unused(resource); 101101e04c3fSmrg ctx->api.pfnSwrEndFrame(ctx->swrContext); 101201e04c3fSmrg } 101301e04c3fSmrg 101401e04c3fSmrg /* Multisample resolved into resolve_target at flush with store_resource */ 101501e04c3fSmrg if (pipe && spr->swr.numSamples > 1) { 101601e04c3fSmrg struct pipe_resource *resolve_target = spr->resolve_target; 101701e04c3fSmrg 101801e04c3fSmrg /* Once resolved, copy into display target */ 101901e04c3fSmrg SWR_SURFACE_STATE *resolve = &swr_resource(resolve_target)->swr; 102001e04c3fSmrg 102101e04c3fSmrg void *map = winsys->displaytarget_map(winsys, spr->display_target, 10227ec681f3Smrg PIPE_MAP_WRITE); 102301e04c3fSmrg memcpy(map, (void*)(resolve->xpBaseAddress), resolve->pitch * resolve->height); 102401e04c3fSmrg winsys->displaytarget_unmap(winsys, spr->display_target); 102501e04c3fSmrg } 102601e04c3fSmrg 102701e04c3fSmrg debug_assert(spr->display_target); 102801e04c3fSmrg if (spr->display_target) 102901e04c3fSmrg winsys->displaytarget_display( 103001e04c3fSmrg winsys, spr->display_target, context_private, sub_box); 103101e04c3fSmrg} 103201e04c3fSmrg 103301e04c3fSmrg 103401e04c3fSmrgvoid 103501e04c3fSmrgswr_destroy_screen_internal(struct swr_screen **screen) 103601e04c3fSmrg{ 103701e04c3fSmrg struct pipe_screen *p_screen = &(*screen)->base; 103801e04c3fSmrg 103901e04c3fSmrg swr_fence_finish(p_screen, NULL, (*screen)->flush_fence, 0); 104001e04c3fSmrg swr_fence_reference(p_screen, &(*screen)->flush_fence, NULL); 104101e04c3fSmrg 104201e04c3fSmrg JitDestroyContext((*screen)->hJitMgr); 104301e04c3fSmrg 104401e04c3fSmrg if ((*screen)->pLibrary) 104501e04c3fSmrg util_dl_close((*screen)->pLibrary); 104601e04c3fSmrg 104701e04c3fSmrg FREE(*screen); 104801e04c3fSmrg *screen = NULL; 104901e04c3fSmrg} 105001e04c3fSmrg 105101e04c3fSmrg 105201e04c3fSmrgstatic void 105301e04c3fSmrgswr_destroy_screen(struct pipe_screen *p_screen) 105401e04c3fSmrg{ 105501e04c3fSmrg struct swr_screen *screen = swr_screen(p_screen); 105601e04c3fSmrg struct sw_winsys *winsys = screen->winsys; 105701e04c3fSmrg 10587ec681f3Smrg swr_print_info("SWR destroy screen!\n"); 105901e04c3fSmrg 106001e04c3fSmrg if (winsys->destroy) 106101e04c3fSmrg winsys->destroy(winsys); 106201e04c3fSmrg 106301e04c3fSmrg swr_destroy_screen_internal(&screen); 106401e04c3fSmrg} 106501e04c3fSmrg 106601e04c3fSmrg 106701e04c3fSmrgstatic void 106801e04c3fSmrgswr_validate_env_options(struct swr_screen *screen) 106901e04c3fSmrg{ 107001e04c3fSmrg /* The client_copy_limit sets a maximum on the amount of user-buffer memory 107101e04c3fSmrg * copied to scratch space on a draw. Past this, the draw will access 107201e04c3fSmrg * user-buffer directly and then block. This is faster than queuing many 107301e04c3fSmrg * large client draws. */ 107401e04c3fSmrg screen->client_copy_limit = SWR_CLIENT_COPY_LIMIT; 107501e04c3fSmrg int client_copy_limit = 107601e04c3fSmrg debug_get_num_option("SWR_CLIENT_COPY_LIMIT", SWR_CLIENT_COPY_LIMIT); 107701e04c3fSmrg if (client_copy_limit > 0) 107801e04c3fSmrg screen->client_copy_limit = client_copy_limit; 107901e04c3fSmrg 108001e04c3fSmrg /* XXX msaa under development, disable by default for now */ 108101e04c3fSmrg screen->msaa_max_count = 1; /* was SWR_MAX_NUM_MULTISAMPLES; */ 108201e04c3fSmrg 108301e04c3fSmrg /* validate env override values, within range and power of 2 */ 108401e04c3fSmrg int msaa_max_count = debug_get_num_option("SWR_MSAA_MAX_COUNT", 1); 108501e04c3fSmrg if (msaa_max_count != 1) { 108601e04c3fSmrg if ((msaa_max_count < 1) || (msaa_max_count > SWR_MAX_NUM_MULTISAMPLES) 108701e04c3fSmrg || !util_is_power_of_two_or_zero(msaa_max_count)) { 108801e04c3fSmrg fprintf(stderr, "SWR_MSAA_MAX_COUNT invalid: %d\n", msaa_max_count); 108901e04c3fSmrg fprintf(stderr, "must be power of 2 between 1 and %d" \ 109001e04c3fSmrg " (or 1 to disable msaa)\n", 109101e04c3fSmrg SWR_MAX_NUM_MULTISAMPLES); 10927ec681f3Smrg fprintf(stderr, "(msaa disabled)\n"); 109301e04c3fSmrg msaa_max_count = 1; 109401e04c3fSmrg } 109501e04c3fSmrg 10967ec681f3Smrg swr_print_info("SWR_MSAA_MAX_COUNT: %d\n", msaa_max_count); 109701e04c3fSmrg 109801e04c3fSmrg screen->msaa_max_count = msaa_max_count; 109901e04c3fSmrg } 110001e04c3fSmrg 110101e04c3fSmrg screen->msaa_force_enable = debug_get_bool_option( 110201e04c3fSmrg "SWR_MSAA_FORCE_ENABLE", false); 110301e04c3fSmrg if (screen->msaa_force_enable) 11047ec681f3Smrg swr_print_info("SWR_MSAA_FORCE_ENABLE: true\n"); 110501e04c3fSmrg} 110601e04c3fSmrg 110701e04c3fSmrg 110801e04c3fSmrgstruct pipe_screen * 110901e04c3fSmrgswr_create_screen_internal(struct sw_winsys *winsys) 111001e04c3fSmrg{ 111101e04c3fSmrg struct swr_screen *screen = CALLOC_STRUCT(swr_screen); 111201e04c3fSmrg 111301e04c3fSmrg if (!screen) 111401e04c3fSmrg return NULL; 111501e04c3fSmrg 111601e04c3fSmrg if (!lp_build_init()) { 111701e04c3fSmrg FREE(screen); 111801e04c3fSmrg return NULL; 111901e04c3fSmrg } 112001e04c3fSmrg 112101e04c3fSmrg screen->winsys = winsys; 112201e04c3fSmrg screen->base.get_name = swr_get_name; 112301e04c3fSmrg screen->base.get_vendor = swr_get_vendor; 112401e04c3fSmrg screen->base.is_format_supported = swr_is_format_supported; 112501e04c3fSmrg screen->base.context_create = swr_create_context; 112601e04c3fSmrg screen->base.can_create_resource = swr_can_create_resource; 112701e04c3fSmrg 112801e04c3fSmrg screen->base.destroy = swr_destroy_screen; 112901e04c3fSmrg screen->base.get_param = swr_get_param; 113001e04c3fSmrg screen->base.get_shader_param = swr_get_shader_param; 113101e04c3fSmrg screen->base.get_paramf = swr_get_paramf; 113201e04c3fSmrg 113301e04c3fSmrg screen->base.resource_create = swr_resource_create; 113401e04c3fSmrg screen->base.resource_destroy = swr_resource_destroy; 113501e04c3fSmrg 113601e04c3fSmrg screen->base.flush_frontbuffer = swr_flush_frontbuffer; 113701e04c3fSmrg 113801e04c3fSmrg // Pass in "" for architecture for run-time determination 113901e04c3fSmrg screen->hJitMgr = JitCreateContext(KNOB_SIMD_WIDTH, "", "swr"); 114001e04c3fSmrg 114101e04c3fSmrg swr_fence_init(&screen->base); 114201e04c3fSmrg 114301e04c3fSmrg swr_validate_env_options(screen); 114401e04c3fSmrg 114501e04c3fSmrg return &screen->base; 114601e04c3fSmrg} 1147