Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
  2.  
  3. /*
  4.  * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the next
  14.  * paragraph) shall be included in all copies or substantial portions of the
  15.  * Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23.  * SOFTWARE.
  24.  *
  25.  * Authors:
  26.  *    Rob Clark <robclark@freedesktop.org>
  27.  */
  28.  
  29.  
  30. #include "pipe/p_defines.h"
  31. #include "pipe/p_screen.h"
  32. #include "pipe/p_state.h"
  33.  
  34. #include "util/u_memory.h"
  35. #include "util/u_inlines.h"
  36. #include "util/u_format.h"
  37. #include "util/u_format_s3tc.h"
  38. #include "util/u_string.h"
  39. #include "util/u_debug.h"
  40.  
  41. #include "os/os_time.h"
  42.  
  43. #include <stdio.h>
  44. #include <errno.h>
  45. #include <stdlib.h>
  46.  
  47. #include "freedreno_screen.h"
  48. #include "freedreno_resource.h"
  49. #include "freedreno_fence.h"
  50. #include "freedreno_util.h"
  51.  
  52. #include "fd2_screen.h"
  53. #include "fd3_screen.h"
  54.  
  55. /* XXX this should go away */
  56. #include "state_tracker/drm_driver.h"
  57.  
  58. static const struct debug_named_value debug_options[] = {
  59.                 {"msgs",      FD_DBG_MSGS,   "Print debug messages"},
  60.                 {"disasm",    FD_DBG_DISASM, "Dump TGSI and adreno shader disassembly"},
  61.                 {"dclear",    FD_DBG_DCLEAR, "Mark all state dirty after clear"},
  62.                 {"dgmem",     FD_DBG_DGMEM,  "Mark all state dirty after GMEM tile pass"},
  63.                 {"dscis",     FD_DBG_DSCIS,  "Disable scissor optimization"},
  64.                 DEBUG_NAMED_VALUE_END
  65. };
  66.  
  67. DEBUG_GET_ONCE_FLAGS_OPTION(fd_mesa_debug, "FD_MESA_DEBUG", debug_options, 0)
  68.  
  69. int fd_mesa_debug = 0;
  70.  
  71. static const char *
  72. fd_screen_get_name(struct pipe_screen *pscreen)
  73. {
  74.         static char buffer[128];
  75.         util_snprintf(buffer, sizeof(buffer), "FD%03d",
  76.                         fd_screen(pscreen)->device_id);
  77.         return buffer;
  78. }
  79.  
  80. static const char *
  81. fd_screen_get_vendor(struct pipe_screen *pscreen)
  82. {
  83.         return "freedreno";
  84. }
  85.  
  86. static uint64_t
  87. fd_screen_get_timestamp(struct pipe_screen *pscreen)
  88. {
  89.         int64_t cpu_time = os_time_get() * 1000;
  90.         return cpu_time + fd_screen(pscreen)->cpu_gpu_time_delta;
  91. }
  92.  
  93. static void
  94. fd_screen_fence_ref(struct pipe_screen *pscreen,
  95.                 struct pipe_fence_handle **ptr,
  96.                 struct pipe_fence_handle *pfence)
  97. {
  98.         fd_fence_ref(fd_fence(pfence), (struct fd_fence **)ptr);
  99. }
  100.  
  101. static boolean
  102. fd_screen_fence_signalled(struct pipe_screen *screen,
  103.                 struct pipe_fence_handle *pfence)
  104. {
  105.         return fd_fence_signalled(fd_fence(pfence));
  106. }
  107.  
  108. static boolean
  109. fd_screen_fence_finish(struct pipe_screen *screen,
  110.                 struct pipe_fence_handle *pfence,
  111.                 uint64_t timeout)
  112. {
  113.         return fd_fence_wait(fd_fence(pfence));
  114. }
  115.  
  116. static void
  117. fd_screen_destroy(struct pipe_screen *pscreen)
  118. {
  119.         struct fd_screen *screen = fd_screen(pscreen);
  120.  
  121.         if (screen->pipe)
  122.                 fd_pipe_del(screen->pipe);
  123.  
  124.         if (screen->dev)
  125.                 fd_device_del(screen->dev);
  126.  
  127.         free(screen);
  128. }
  129.  
  130. /*
  131. TODO either move caps to a2xx/a3xx specific code, or maybe have some
  132. tables for things that differ if the delta is not too much..
  133.  */
  134. static int
  135. fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
  136. {
  137.         /* this is probably not totally correct.. but it's a start: */
  138.         switch (param) {
  139.         /* Supported features (boolean caps). */
  140.         case PIPE_CAP_NPOT_TEXTURES:
  141.         case PIPE_CAP_TWO_SIDED_STENCIL:
  142.         case PIPE_CAP_ANISOTROPIC_FILTER:
  143.         case PIPE_CAP_POINT_SPRITE:
  144.         case PIPE_CAP_TEXTURE_SHADOW_MAP:
  145.         case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
  146.         case PIPE_CAP_BLEND_EQUATION_SEPARATE:
  147.         case PIPE_CAP_TEXTURE_SWIZZLE:
  148.         case PIPE_CAP_SHADER_STENCIL_EXPORT:
  149.         case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
  150.         case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
  151.         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
  152.         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
  153.         case PIPE_CAP_SM3:
  154.         case PIPE_CAP_SEAMLESS_CUBE_MAP:
  155.         case PIPE_CAP_PRIMITIVE_RESTART:
  156.         case PIPE_CAP_CONDITIONAL_RENDER:
  157.         case PIPE_CAP_TEXTURE_BARRIER:
  158.         case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
  159.         case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
  160.         case PIPE_CAP_TGSI_INSTANCEID:
  161.         case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
  162.         case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
  163.         case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
  164.         case PIPE_CAP_COMPUTE:
  165.         case PIPE_CAP_START_INSTANCE:
  166.         case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
  167.         case PIPE_CAP_TEXTURE_MULTISAMPLE:
  168.         case PIPE_CAP_USER_CONSTANT_BUFFERS:
  169.                 return 1;
  170.  
  171.         case PIPE_CAP_TGSI_TEXCOORD:
  172.         case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
  173.                 return 0;
  174.  
  175.         case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
  176.                 return 256;
  177.  
  178.         case PIPE_CAP_GLSL_FEATURE_LEVEL:
  179.                 return 120;
  180.  
  181.         /* Unsupported features. */
  182.         case PIPE_CAP_INDEP_BLEND_ENABLE:
  183.         case PIPE_CAP_INDEP_BLEND_FUNC:
  184.         case PIPE_CAP_DEPTH_CLIP_DISABLE:
  185.         case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
  186.         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
  187.         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
  188.         case PIPE_CAP_SCALED_RESOLVE:
  189.         case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
  190.         case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
  191.         case PIPE_CAP_VERTEX_COLOR_CLAMPED:
  192.         case PIPE_CAP_USER_VERTEX_BUFFERS:
  193.         case PIPE_CAP_USER_INDEX_BUFFERS:
  194.         case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
  195.         case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
  196.                 return 0;
  197.  
  198.         /* Stream output. */
  199.         case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
  200.         case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
  201.         case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
  202.         case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
  203.                 return 0;
  204.  
  205.         /* Texturing. */
  206.         case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
  207.         case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
  208.         case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
  209.                 return 14;
  210.         case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
  211.                 return 9192;
  212.         case PIPE_CAP_MAX_COMBINED_SAMPLERS:
  213.                 return 20;
  214.  
  215.         /* Render targets. */
  216.         case PIPE_CAP_MAX_RENDER_TARGETS:
  217.                 return 1;
  218.  
  219.         /* Timer queries. */
  220.         case PIPE_CAP_QUERY_TIME_ELAPSED:
  221.         case PIPE_CAP_OCCLUSION_QUERY:
  222.         case PIPE_CAP_QUERY_TIMESTAMP:
  223.                 return 0;
  224.  
  225.         case PIPE_CAP_MIN_TEXEL_OFFSET:
  226.                 return -8;
  227.  
  228.         case PIPE_CAP_MAX_TEXEL_OFFSET:
  229.                 return 7;
  230.  
  231.         case PIPE_CAP_ENDIANNESS:
  232.                 return PIPE_ENDIAN_LITTLE;
  233.  
  234.         default:
  235.                 DBG("unknown param %d", param);
  236.                 return 0;
  237.         }
  238. }
  239.  
  240. static float
  241. fd_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
  242. {
  243.         switch (param) {
  244.         case PIPE_CAPF_MAX_LINE_WIDTH:
  245.         case PIPE_CAPF_MAX_LINE_WIDTH_AA:
  246.         case PIPE_CAPF_MAX_POINT_WIDTH:
  247.         case PIPE_CAPF_MAX_POINT_WIDTH_AA:
  248.                 return 8192.0f;
  249.         case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
  250.                 return 16.0f;
  251.         case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
  252.                 return 16.0f;
  253.         case PIPE_CAPF_GUARD_BAND_LEFT:
  254.         case PIPE_CAPF_GUARD_BAND_TOP:
  255.         case PIPE_CAPF_GUARD_BAND_RIGHT:
  256.         case PIPE_CAPF_GUARD_BAND_BOTTOM:
  257.                 return 0.0f;
  258.         default:
  259.                 DBG("unknown paramf %d", param);
  260.                 return 0;
  261.         }
  262. }
  263.  
  264. static int
  265. fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
  266.                 enum pipe_shader_cap param)
  267. {
  268.         switch(shader)
  269.         {
  270.         case PIPE_SHADER_FRAGMENT:
  271.         case PIPE_SHADER_VERTEX:
  272.                 break;
  273.         case PIPE_SHADER_COMPUTE:
  274.         case PIPE_SHADER_GEOMETRY:
  275.                 /* maye we could emulate.. */
  276.                 return 0;
  277.         default:
  278.                 DBG("unknown shader type %d", shader);
  279.                 return 0;
  280.         }
  281.  
  282.         /* this is probably not totally correct.. but it's a start: */
  283.         switch (param) {
  284.         case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
  285.         case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
  286.         case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
  287.         case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
  288.                 return 16384;
  289.         case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
  290.                 return 8; /* XXX */
  291.         case PIPE_SHADER_CAP_MAX_INPUTS:
  292.                 return 32;
  293.         case PIPE_SHADER_CAP_MAX_TEMPS:
  294.                 return 256; /* Max native temporaries. */
  295.         case PIPE_SHADER_CAP_MAX_ADDRS:
  296.                 /* XXX Isn't this equal to TEMPS? */
  297.                 return 1; /* Max native address registers */
  298.         case PIPE_SHADER_CAP_MAX_CONSTS:
  299.         case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
  300.                 return 64;
  301.         case PIPE_SHADER_CAP_MAX_PREDS:
  302.                 return 0; /* nothing uses this */
  303.         case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
  304.                 return 1;
  305.         case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
  306.         case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
  307.         case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
  308.         case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
  309.                 return 1;
  310.         case PIPE_SHADER_CAP_SUBROUTINES:
  311.                 return 0;
  312.         case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
  313.         case PIPE_SHADER_CAP_INTEGERS:
  314.                 return 0;
  315.         case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
  316.                 return 16;
  317.         case PIPE_SHADER_CAP_PREFERRED_IR:
  318.                 return PIPE_SHADER_IR_TGSI;
  319.         default:
  320.                 DBG("unknown shader param %d", param);
  321.                 return 0;
  322.         }
  323.         return 0;
  324. }
  325.  
  326. boolean
  327. fd_screen_bo_get_handle(struct pipe_screen *pscreen,
  328.                 struct fd_bo *bo,
  329.                 unsigned stride,
  330.                 struct winsys_handle *whandle)
  331. {
  332.         whandle->stride = stride;
  333.  
  334.         if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
  335.                 return fd_bo_get_name(bo, &whandle->handle) == 0;
  336.         } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
  337.                 whandle->handle = fd_bo_handle(bo);
  338.                 return TRUE;
  339.         } else {
  340.                 return FALSE;
  341.         }
  342. }
  343.  
  344. struct fd_bo *
  345. fd_screen_bo_from_handle(struct pipe_screen *pscreen,
  346.                 struct winsys_handle *whandle,
  347.                 unsigned *out_stride)
  348. {
  349.         struct fd_screen *screen = fd_screen(pscreen);
  350.         struct fd_bo *bo;
  351.  
  352.         bo = fd_bo_from_name(screen->dev, whandle->handle);
  353.         if (!bo) {
  354.                 DBG("ref name 0x%08x failed", whandle->handle);
  355.                 return NULL;
  356.         }
  357.  
  358.         *out_stride = whandle->stride;
  359.  
  360.         return bo;
  361. }
  362.  
  363. struct pipe_screen *
  364. fd_screen_create(struct fd_device *dev)
  365. {
  366.         struct fd_screen *screen = CALLOC_STRUCT(fd_screen);
  367.         struct pipe_screen *pscreen;
  368.         uint64_t val;
  369.  
  370.         fd_mesa_debug = debug_get_option_fd_mesa_debug();
  371.  
  372.         if (!screen)
  373.                 return NULL;
  374.  
  375.         pscreen = &screen->base;
  376.  
  377.         screen->dev = dev;
  378.  
  379.         // maybe this should be in context?
  380.         screen->pipe = fd_pipe_new(screen->dev, FD_PIPE_3D);
  381.         if (!screen->pipe) {
  382.                 DBG("could not create 3d pipe");
  383.                 goto fail;
  384.         }
  385.  
  386.         if (fd_pipe_get_param(screen->pipe, FD_GMEM_SIZE, &val)) {
  387.                 DBG("could not get GMEM size");
  388.                 goto fail;
  389.         }
  390.         screen->gmemsize_bytes = val;
  391.  
  392.         if (fd_pipe_get_param(screen->pipe, FD_DEVICE_ID, &val)) {
  393.                 DBG("could not get device-id");
  394.                 goto fail;
  395.         }
  396.         screen->device_id = val;
  397.  
  398.         if (fd_pipe_get_param(screen->pipe, FD_GPU_ID, &val)) {
  399.                 DBG("could not get gpu-id");
  400.                 goto fail;
  401.         }
  402.         screen->gpu_id = val;
  403.  
  404.         /* explicitly checking for GPU revisions that are known to work.  This
  405.          * may be overly conservative for a3xx, where spoofing the gpu_id with
  406.          * the blob driver seems to generate identical cmdstream dumps.  But
  407.          * on a2xx, there seem to be small differences between the GPU revs
  408.          * so it is probably better to actually test first on real hardware
  409.          * before enabling:
  410.          *
  411.          * If you have a different adreno version, feel free to add it to one
  412.          * of the two cases below and see what happens.  And if it works, please
  413.          * send a patch ;-)
  414.          */
  415.         switch (screen->gpu_id) {
  416.         case 220:
  417.                 fd2_screen_init(pscreen);
  418.                 break;
  419.         case 320:
  420.                 fd3_screen_init(pscreen);
  421.                 break;
  422.         default:
  423.                 debug_printf("unsupported GPU: a%03d\n", screen->gpu_id);
  424.                 goto fail;
  425.         }
  426.  
  427.         pscreen->destroy = fd_screen_destroy;
  428.         pscreen->get_param = fd_screen_get_param;
  429.         pscreen->get_paramf = fd_screen_get_paramf;
  430.         pscreen->get_shader_param = fd_screen_get_shader_param;
  431.  
  432.         fd_resource_screen_init(pscreen);
  433.  
  434.         pscreen->get_name = fd_screen_get_name;
  435.         pscreen->get_vendor = fd_screen_get_vendor;
  436.  
  437.         pscreen->get_timestamp = fd_screen_get_timestamp;
  438.  
  439.         pscreen->fence_reference = fd_screen_fence_ref;
  440.         pscreen->fence_signalled = fd_screen_fence_signalled;
  441.         pscreen->fence_finish = fd_screen_fence_finish;
  442.  
  443.         util_format_s3tc_init();
  444.  
  445.         return pscreen;
  446.  
  447. fail:
  448.         fd_screen_destroy(pscreen);
  449.         return NULL;
  450. }
  451.