X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fetnaviv%2Fetnaviv_screen.c;h=c72793920abe4ad6ef704d550f2e9a3812ae134d;hb=e4ca1d64565b4d665bcaf5d08922bfbe1d920e7a;hp=11053c6461cf1294aa4208a1a4677291281947ce;hpb=d0c7f924a36f5a93c5a432baf3c653b9b07e006b;p=mesa.git diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c index 11053c6461c..c72793920ab 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c @@ -38,13 +38,18 @@ #include "etnaviv_resource.h" #include "etnaviv_translate.h" -#include "os/os_time.h" +#include "util/os_time.h" #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_string.h" #include "state_tracker/drm_driver.h" +#include + +#define ETNA_DRM_VERSION(major, minor) ((major) << 16 | (minor)) +#define ETNA_DRM_VERSION_FENCE_FD ETNA_DRM_VERSION(1, 1) + static const struct debug_named_value debug_options[] = { {"dbg_msgs", ETNA_DBG_MSGS, "Print debug messages"}, {"frame_msgs", ETNA_DBG_FRAME_MSGS, "Print frame messages"}, @@ -120,10 +125,8 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) switch (param) { /* Supported features (boolean caps). */ - case PIPE_CAP_TWO_SIDED_STENCIL: case PIPE_CAP_ANISOTROPIC_FILTER: case PIPE_CAP_POINT_SPRITE: - case PIPE_CAP_TEXTURE_SHADOW_MAP: case PIPE_CAP_BLEND_EQUATION_SEPARATE: case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: @@ -133,10 +136,11 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: - case PIPE_CAP_USER_CONSTANT_BUFFERS: case PIPE_CAP_TGSI_TEXCOORD: case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: return 1; + case PIPE_CAP_NATIVE_FENCE_FD: + return screen->drm_version >= ETNA_DRM_VERSION_FENCE_FD; /* Memory */ case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: @@ -150,6 +154,7 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return true; /* VIV_FEATURE(priv->dev, chipMinorFeatures1, NON_POWER_OF_TWO); */ + case PIPE_CAP_TEXTURE_SWIZZLE: case PIPE_CAP_PRIMITIVE_RESTART: return VIV_FEATURE(screen, chipMinorFeatures1, HALTI0); @@ -159,7 +164,6 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) /* Unsupported features. */ case PIPE_CAP_SEAMLESS_CUBE_MAP: - case PIPE_CAP_TEXTURE_SWIZZLE: /* XXX supported on gc2000 */ case PIPE_CAP_COMPUTE: /* XXX supported on gc2000 */ case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: /* only one colorbuffer supported, so mixing makes no sense */ case PIPE_CAP_CONDITIONAL_RENDER: /* no occlusion queries */ @@ -237,7 +241,6 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TGSI_ARRAY_COMPONENTS: case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS: case PIPE_CAP_TGSI_CAN_READ_OUTPUTS: - case PIPE_CAP_NATIVE_FENCE_FD: case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY: case PIPE_CAP_TGSI_FS_FBFETCH: case PIPE_CAP_TGSI_MUL_ZERO_WINS: @@ -246,6 +249,23 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_INT64_DIVMOD: case PIPE_CAP_TGSI_TEX_TXF_LZ: case PIPE_CAP_TGSI_CLOCK: + case PIPE_CAP_POLYGON_MODE_FILL_RECTANGLE: + case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE: + case PIPE_CAP_TGSI_BALLOT: + case PIPE_CAP_TGSI_TES_LAYER_VIEWPORT: + case PIPE_CAP_CAN_BIND_CONST_BUFFER_AS_VERTEX: + case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION: + case PIPE_CAP_POST_DEPTH_COVERAGE: + case PIPE_CAP_BINDLESS_TEXTURE: + case PIPE_CAP_NIR_SAMPLERS_AS_DEREF: + case PIPE_CAP_QUERY_SO_OVERFLOW: + case PIPE_CAP_MEMOBJ: + case PIPE_CAP_LOAD_CONSTBUF: + case PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS: + case PIPE_CAP_TILE_RASTER_ORDER: + case PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES: + case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET: + case PIPE_CAP_CONTEXT_PRIORITY_MASK: return 0; /* Stream output. */ @@ -299,8 +319,9 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) /* Timer queries. */ case PIPE_CAP_QUERY_TIME_ELAPSED: - case PIPE_CAP_OCCLUSION_QUERY: return 0; + case PIPE_CAP_OCCLUSION_QUERY: + return VIV_FEATURE(screen, chipMinorFeatures1, HALTI0); case PIPE_CAP_QUERY_TIMESTAMP: return 1; case PIPE_CAP_QUERY_PIPELINE_STATISTICS: @@ -333,6 +354,8 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) static float etna_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) { + struct etna_screen *screen = etna_screen(pscreen); + switch (param) { case PIPE_CAPF_MAX_LINE_WIDTH: case PIPE_CAPF_MAX_LINE_WIDTH_AA: @@ -342,7 +365,7 @@ etna_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: return 16.0f; case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: - return 16.0f; + return util_last_bit(screen->specs.max_texture_size); case PIPE_CAPF_GUARD_BAND_LEFT: case PIPE_CAPF_GUARD_BAND_TOP: case PIPE_CAPF_GUARD_BAND_RIGHT: @@ -396,8 +419,6 @@ etna_screen_get_shader_param(struct pipe_screen *pscreen, return 64; /* Max native temporaries. */ case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: return 1; - case PIPE_SHADER_CAP_MAX_PREDS: - return 0; /* nothing uses this */ case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: return 1; case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: @@ -410,6 +431,8 @@ etna_screen_get_shader_param(struct pipe_screen *pscreen, case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: return VIV_FEATURE(screen, chipMinorFeatures0, HAS_SQRT_TRIG); case PIPE_SHADER_CAP_INTEGERS: + case PIPE_SHADER_CAP_INT64_ATOMICS: + case PIPE_SHADER_CAP_FP16: return 0; case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: @@ -422,6 +445,7 @@ etna_screen_get_shader_param(struct pipe_screen *pscreen, return 4096; case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED: case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED: + case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED: case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED: case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: return false; @@ -432,6 +456,9 @@ etna_screen_get_shader_param(struct pipe_screen *pscreen, case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD: + case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS: + case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS: + case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS: return 0; } @@ -446,13 +473,42 @@ etna_screen_get_timestamp(struct pipe_screen *pscreen) } static bool -gpu_supports_texure_format(struct etna_screen *screen, uint32_t fmt) +gpu_supports_texure_format(struct etna_screen *screen, uint32_t fmt, + enum pipe_format format) { + bool supported = true; + if (fmt == TEXTURE_FORMAT_ETC1) - return VIV_FEATURE(screen, chipFeatures, ETC1_TEXTURE_COMPRESSION); + supported = VIV_FEATURE(screen, chipFeatures, ETC1_TEXTURE_COMPRESSION); if (fmt >= TEXTURE_FORMAT_DXT1 && fmt <= TEXTURE_FORMAT_DXT4_DXT5) - return VIV_FEATURE(screen, chipFeatures, DXT_TEXTURE_COMPRESSION); + supported = VIV_FEATURE(screen, chipFeatures, DXT_TEXTURE_COMPRESSION); + + if (util_format_is_srgb(format)) + supported = VIV_FEATURE(screen, chipMinorFeatures1, HALTI0); + + if (fmt & EXT_FORMAT) { + supported = VIV_FEATURE(screen, chipMinorFeatures1, HALTI0); + + /* ETC1 is checked above, as it has its own feature bit. ETC2 is + * supported with HALTI0, however that implementation is buggy in hardware. + * The blob driver does per-block patching to work around this. As this + * is currently not implemented by etnaviv, enable it for HALTI1 (GC3000) + * only. + */ + if (util_format_is_etc(format)) + supported = VIV_FEATURE(screen, chipMinorFeatures2, HALTI1); + } + + if (fmt & ASTC_FORMAT) { + supported = screen->specs.tex_astc; + } + + if (!supported) + return false; + + if (texture_format_needs_swiz(format)) + return VIV_FEATURE(screen, chipMinorFeatures1, HALTI0); return true; } @@ -475,11 +531,8 @@ etna_screen_is_format_supported(struct pipe_screen *pscreen, return FALSE; if (usage & PIPE_BIND_RENDER_TARGET) { - /* If render target, must be RS-supported format that is not rb swapped. - * Exposing rb swapped (or other swizzled) formats for rendering would - * involve swizzing in the pixel shader. - */ - if (translate_rs_format(format) != ETNA_NO_MATCH && !translate_rs_format_rb_swap(format)) { + /* if render target, must be RS-supported format */ + if (translate_rs_format(format) != ETNA_NO_MATCH) { /* Validate MSAA; number of samples must be allowed, and render target * must have MSAA'able format. */ if (sample_count > 1) { @@ -501,7 +554,7 @@ etna_screen_is_format_supported(struct pipe_screen *pscreen, if (usage & PIPE_BIND_SAMPLER_VIEW) { uint32_t fmt = translate_texture_format(format); - if (!gpu_supports_texure_format(screen, fmt)) + if (!gpu_supports_texure_format(screen, fmt, format)) fmt = ETNA_NO_MATCH; if (sample_count < 2 && fmt != ETNA_NO_MATCH) @@ -535,6 +588,47 @@ etna_screen_is_format_supported(struct pipe_screen *pscreen, return usage == allowed; } +const uint64_t supported_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_VIVANTE_TILED, + DRM_FORMAT_MOD_VIVANTE_SUPER_TILED, + DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED, + DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED, +}; + +static void +etna_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, + enum pipe_format format, int max, + uint64_t *modifiers, + unsigned int *external_only, int *count) +{ + struct etna_screen *screen = etna_screen(pscreen); + int i, num_modifiers = 0; + + if (max > ARRAY_SIZE(supported_modifiers)) + max = ARRAY_SIZE(supported_modifiers); + + if (!max) { + modifiers = NULL; + max = ARRAY_SIZE(supported_modifiers); + } + + for (i = 0; num_modifiers < max; i++) { + /* don't advertise split tiled formats on single pipe/buffer GPUs */ + if ((screen->specs.pixel_pipes == 1 || screen->specs.single_buffer) && + i >= 3) + break; + + if (modifiers) + modifiers[num_modifiers] = supported_modifiers[i]; + if (external_only) + external_only[num_modifiers] = 0; + num_modifiers++; + } + + *count = num_modifiers; +} + static boolean etna_get_specs(struct etna_screen *screen) { @@ -594,6 +688,27 @@ etna_get_specs(struct etna_screen *screen) } screen->specs.num_constants = val; + /* Figure out gross GPU architecture. See rnndb/common.xml for a specific + * description of the differences. */ + if (VIV_FEATURE(screen, chipMinorFeatures5, HALTI5)) + screen->specs.halti = 5; /* New GC7000/GC8x00 */ + else if (VIV_FEATURE(screen, chipMinorFeatures5, HALTI4)) + screen->specs.halti = 4; /* Old GC7000/GC7400 */ + else if (VIV_FEATURE(screen, chipMinorFeatures5, HALTI3)) + screen->specs.halti = 3; /* None? */ + else if (VIV_FEATURE(screen, chipMinorFeatures4, HALTI2)) + screen->specs.halti = 2; /* GC2500/GC3000/GC5000/GC6400 */ + else if (VIV_FEATURE(screen, chipMinorFeatures2, HALTI1)) + screen->specs.halti = 1; /* GC900/GC4000/GC7000UL */ + else if (VIV_FEATURE(screen, chipMinorFeatures1, HALTI0)) + screen->specs.halti = 0; /* GC880/GC2000/GC7000TM */ + else + screen->specs.halti = -1; /* GC7000nanolite / pre-GC2000 except GC880 */ + if (screen->specs.halti >= 0) + DBG("etnaviv: GPU arch: HALTI%d\n", screen->specs.halti); + else + DBG("etnaviv: GPU arch: pre-HALTI\n"); + screen->specs.can_supertile = VIV_FEATURE(screen, chipMinorFeatures0, SUPER_TILED); screen->specs.bits_per_tile = @@ -616,10 +731,18 @@ etna_get_specs(struct etna_screen *screen) screen->model >= 0x1000 || screen->model == 0x880; screen->specs.npot_tex_any_wrap = VIV_FEATURE(screen, chipMinorFeatures1, NON_POWER_OF_TWO); - screen->specs.has_new_sin_cos = + screen->specs.has_new_transcendentals = VIV_FEATURE(screen, chipMinorFeatures3, HAS_FAST_TRANSCENDENTALS); - - if (VIV_FEATURE(screen, chipMinorFeatures3, INSTRUCTION_CACHE)) { + screen->specs.has_halti2_instructions = + VIV_FEATURE(screen, chipMinorFeatures4, HALTI2); + + if (screen->specs.halti >= 5) { + /* GC7000 - this core must load shaders from memory. */ + screen->specs.vs_offset = 0; + screen->specs.ps_offset = 0; + screen->specs.max_instructions = 0; /* Do not program shaders manually */ + screen->specs.has_icache = true; + } else if (VIV_FEATURE(screen, chipMinorFeatures3, INSTRUCTION_CACHE)) { /* GC3000 - this core is capable of loading shaders from * memory. It can also run shaders from registers, as a fallback, but * "max_instructions" does not have the correct value. It has place for @@ -632,7 +755,8 @@ etna_get_specs(struct etna_screen *screen) * same. */ screen->specs.ps_offset = 0x8000 + 0x1000; - screen->specs.max_instructions = 256; + screen->specs.max_instructions = 256; /* maximum number instructions for non-icache use */ + screen->specs.has_icache = true; } else { if (instruction_count > 256) { /* unified instruction memory? */ screen->specs.vs_offset = 0xC000; @@ -643,6 +767,7 @@ etna_get_specs(struct etna_screen *screen) screen->specs.ps_offset = 0x6000; screen->specs.max_instructions = instruction_count / 2; } + screen->specs.has_icache = false; } if (VIV_FEATURE(screen, chipMinorFeatures1, HALTI0)) { @@ -671,36 +796,45 @@ etna_get_specs(struct etna_screen *screen) screen->specs.max_ps_uniforms = 256; } + if (screen->specs.halti >= 5) { + screen->specs.has_unified_uniforms = true; + screen->specs.vs_uniforms_offset = VIVS_SH_HALTI5_UNIFORMS_MIRROR(0); + screen->specs.ps_uniforms_offset = VIVS_SH_HALTI5_UNIFORMS(screen->specs.max_vs_uniforms*4); + } else if (screen->specs.halti >= 1) { + /* unified uniform memory on GC3000 - HALTI1 feature bit is just a guess + */ + screen->specs.has_unified_uniforms = true; + screen->specs.vs_uniforms_offset = VIVS_SH_UNIFORMS(0); + /* hardcode PS uniforms to start after end of VS uniforms - + * for more flexibility this offset could be variable based on the + * shader. + */ + screen->specs.ps_uniforms_offset = VIVS_SH_UNIFORMS(screen->specs.max_vs_uniforms*4); + } else { + screen->specs.has_unified_uniforms = false; + screen->specs.vs_uniforms_offset = VIVS_VS_UNIFORMS(0); + screen->specs.ps_uniforms_offset = VIVS_PS_UNIFORMS(0); + } + screen->specs.max_texture_size = VIV_FEATURE(screen, chipMinorFeatures0, TEXTURE_8K) ? 8192 : 2048; screen->specs.max_rendertarget_size = VIV_FEATURE(screen, chipMinorFeatures0, RENDERTARGET_8K) ? 8192 : 2048; + screen->specs.single_buffer = VIV_FEATURE(screen, chipMinorFeatures4, SINGLE_BUFFER); + if (screen->specs.single_buffer) + DBG("etnaviv: Single buffer mode enabled with %d pixel pipes\n", screen->specs.pixel_pipes); + + screen->specs.tex_astc = VIV_FEATURE(screen, chipMinorFeatures4, TEXTURE_ASTC); + + screen->specs.use_blt = VIV_FEATURE(screen, chipMinorFeatures5, BLT_ENGINE); + return true; fail: return false; } -boolean -etna_screen_bo_get_handle(struct pipe_screen *pscreen, struct etna_bo *bo, - unsigned stride, struct winsys_handle *whandle) -{ - whandle->stride = stride; - - if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { - return etna_bo_get_name(bo, &whandle->handle) == 0; - } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { - whandle->handle = etna_bo_handle(bo); - return TRUE; - } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) { - whandle->handle = etna_bo_dmabuf(bo); - return TRUE; - } else { - return FALSE; - } -} - struct etna_bo * etna_screen_bo_from_handle(struct pipe_screen *pscreen, struct winsys_handle *whandle, unsigned *out_stride) @@ -733,6 +867,7 @@ etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu, { struct etna_screen *screen = CALLOC_STRUCT(etna_screen); struct pipe_screen *pscreen; + drmVersionPtr version; uint64_t val; if (!screen) @@ -742,16 +877,22 @@ etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu, screen->dev = dev; screen->gpu = gpu; screen->ro = renderonly_dup(ro); + screen->refcnt = 1; if (!screen->ro) { DBG("could not create renderonly object"); goto fail; } + version = drmGetVersion(screen->ro->gpu_fd); + screen->drm_version = ETNA_DRM_VERSION(version->version_major, + version->version_minor); + drmFreeVersion(version); + etna_mesa_debug = debug_get_option_etna_mesa_debug(); - /* FIXME: Disable tile status for stability at the moment */ - etna_mesa_debug |= ETNA_DBG_NO_TS; + /* Disable autodisable for correct rendering with TS */ + etna_mesa_debug |= ETNA_DBG_NO_AUTODISABLE; screen->pipe = etna_pipe_new(gpu, ETNA_PIPE_3D); if (!screen->pipe) { @@ -801,9 +942,31 @@ etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu, } screen->features[4] = val; + if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_5, &val)) { + DBG("could not get ETNA_GPU_FEATURES_5"); + goto fail; + } + screen->features[5] = val; + + if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_6, &val)) { + DBG("could not get ETNA_GPU_FEATURES_6"); + goto fail; + } + screen->features[6] = val; + if (!etna_get_specs(screen)) goto fail; + /* apply debug options that disable individual features */ + if (DBG_ENABLED(ETNA_DBG_NO_EARLY_Z)) + screen->features[viv_chipFeatures] |= chipFeatures_NO_EARLY_Z; + if (DBG_ENABLED(ETNA_DBG_NO_TS)) + screen->features[viv_chipFeatures] &= ~chipFeatures_FAST_CLEAR; + if (DBG_ENABLED(ETNA_DBG_NO_AUTODISABLE)) + screen->features[viv_chipMinorFeatures1] &= ~chipMinorFeatures1_AUTO_DISABLE; + if (DBG_ENABLED(ETNA_DBG_NO_SUPERTILE)) + screen->specs.can_supertile = 0; + pscreen->destroy = etna_screen_destroy; pscreen->get_param = etna_screen_get_param; pscreen->get_paramf = etna_screen_get_paramf; @@ -816,6 +979,7 @@ etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu, pscreen->get_timestamp = etna_screen_get_timestamp; pscreen->context_create = etna_context_create; pscreen->is_format_supported = etna_screen_is_format_supported; + pscreen->query_dmabuf_modifiers = etna_screen_query_dmabuf_modifiers; etna_fence_screen_init(pscreen); etna_query_screen_init(pscreen);