Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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.                 DEBUG_NAMED_VALUE_END
  64. };
  65.  
  66. DEBUG_GET_ONCE_FLAGS_OPTION(fd_mesa_debug, "FD_MESA_DEBUG", debug_options, 0)
  67.  
  68. int fd_mesa_debug = 0;
  69.  
  70. static const char *
  71. fd_screen_get_name(struct pipe_screen *pscreen)
  72. {
  73.         static char buffer[128];
  74.         util_snprintf(buffer, sizeof(buffer), "FD%03d",
  75.                         fd_screen(pscreen)->device_id);
  76.         return buffer;
  77. }
  78.  
  79. static const char *
  80. fd_screen_get_vendor(struct pipe_screen *pscreen)
  81. {
  82.         return "freedreno";
  83. }
  84.  
  85. static uint64_t
  86. fd_screen_get_timestamp(struct pipe_screen *pscreen)
  87. {
  88.         int64_t cpu_time = os_time_get() * 1000;
  89.         return cpu_time + fd_screen(pscreen)->cpu_gpu_time_delta;
  90. }
  91.  
  92. static void
  93. fd_screen_fence_ref(struct pipe_screen *pscreen,
  94.                 struct pipe_fence_handle **ptr,
  95.                 struct pipe_fence_handle *pfence)
  96. {
  97.         fd_fence_ref(fd_fence(pfence), (struct fd_fence **)ptr);
  98. }
  99.  
  100. static boolean
  101. fd_screen_fence_signalled(struct pipe_screen *screen,
  102.                 struct pipe_fence_handle *pfence)
  103. {
  104.         return fd_fence_signalled(fd_fence(pfence));
  105. }
  106.  
  107. static boolean
  108. fd_screen_fence_finish(struct pipe_screen *screen,
  109.                 struct pipe_fence_handle *pfence,
  110.                 uint64_t timeout)
  111. {
  112.         return fd_fence_wait(fd_fence(pfence));
  113. }
  114.  
  115. static void
  116. fd_screen_destroy(struct pipe_screen *pscreen)
  117. {
  118.         struct fd_screen *screen = fd_screen(pscreen);
  119.  
  120.         if (screen->pipe)
  121.                 fd_pipe_del(screen->pipe);
  122.  
  123.         if (screen->dev)
  124.                 fd_device_del(screen->dev);
  125.  
  126.         free(screen);
  127. }
  128.  
  129. /*
  130. TODO either move caps to a2xx/a3xx specific code, or maybe have some
  131. tables for things that differ if the delta is not too much..
  132.  */
  133. static int
  134. fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
  135. {
  136.         /* this is probably not totally correct.. but it's a start: */
  137.         switch (param) {
  138.         /* Supported features (boolean caps). */
  139.         case PIPE_CAP_NPOT_TEXTURES:
  140.         case PIPE_CAP_TWO_SIDED_STENCIL:
  141.         case PIPE_CAP_ANISOTROPIC_FILTER:
  142.         case PIPE_CAP_POINT_SPRITE:
  143.         case PIPE_CAP_TEXTURE_SHADOW_MAP:
  144.         case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
  145.         case PIPE_CAP_BLEND_EQUATION_SEPARATE:
  146.         case PIPE_CAP_TEXTURE_SWIZZLE:
  147.         case PIPE_CAP_SHADER_STENCIL_EXPORT:
  148.         case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
  149.         case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
  150.         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
  151.         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
  152.         case PIPE_CAP_SM3:
  153.         case PIPE_CAP_SEAMLESS_CUBE_MAP:
  154.         case PIPE_CAP_PRIMITIVE_RESTART:
  155.         case PIPE_CAP_CONDITIONAL_RENDER:
  156.         case PIPE_CAP_TEXTURE_BARRIER:
  157.         case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
  158.         case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
  159.         case PIPE_CAP_TGSI_INSTANCEID:
  160.         case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
  161.         case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
  162.         case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
  163.         case PIPE_CAP_COMPUTE:
  164.         case PIPE_CAP_START_INSTANCE:
  165.         case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
  166.         case PIPE_CAP_TEXTURE_MULTISAMPLE:
  167.         case PIPE_CAP_USER_CONSTANT_BUFFERS:
  168.                 return 1;
  169.  
  170.         case PIPE_CAP_TGSI_TEXCOORD:
  171.         case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
  172.                 return 0;
  173.  
  174.         case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
  175.                 return 256;
  176.  
  177.         case PIPE_CAP_GLSL_FEATURE_LEVEL:
  178.                 return 120;
  179.  
  180.         /* Unsupported features. */
  181.         case PIPE_CAP_INDEP_BLEND_ENABLE:
  182.         case PIPE_CAP_INDEP_BLEND_FUNC:
  183.         case PIPE_CAP_DEPTH_CLIP_DISABLE:
  184.         case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
  185.         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
  186.         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
  187.         case PIPE_CAP_SCALED_RESOLVE:
  188.         case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
  189.         case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
  190.         case PIPE_CAP_VERTEX_COLOR_CLAMPED:
  191.         case PIPE_CAP_USER_VERTEX_BUFFERS:
  192.         case PIPE_CAP_USER_INDEX_BUFFERS:
  193.         case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
  194.         case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
  195.                 return 0;
  196.  
  197.         /* Stream output. */
  198.         case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
  199.         case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
  200.         case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
  201.         case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
  202.                 return 0;
  203.  
  204.         /* Texturing. */
  205.         case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
  206.         case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
  207.         case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
  208.                 return 14;
  209.         case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
  210.                 return 9192;
  211.         case PIPE_CAP_MAX_COMBINED_SAMPLERS:
  212.                 return 20;
  213.  
  214.         /* Render targets. */
  215.         case PIPE_CAP_MAX_RENDER_TARGETS:
  216.                 return 1;
  217.  
  218.         /* Timer queries. */
  219.         case PIPE_CAP_QUERY_TIME_ELAPSED:
  220.         case PIPE_CAP_OCCLUSION_QUERY:
  221.         case PIPE_CAP_QUERY_TIMESTAMP:
  222.                 return 0;
  223.  
  224.         case PIPE_CAP_MIN_TEXEL_OFFSET:
  225.                 return -8;
  226.  
  227.         case PIPE_CAP_MAX_TEXEL_OFFSET:
  228.                 return 7;
  229.  
  230.         case PIPE_CAP_ENDIANNESS:
  231.                 return PIPE_ENDIAN_LITTLE;
  232.  
  233.         default:
  234.                 DBG("unknown param %d", param);
  235.                 return 0;
  236.         }
  237. }
  238.  
  239. static float
  240. fd_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
  241. {
  242.         switch (param) {
  243.         case PIPE_CAPF_MAX_LINE_WIDTH:
  244.         case PIPE_CAPF_MAX_LINE_WIDTH_AA:
  245.         case PIPE_CAPF_MAX_POINT_WIDTH:
  246.         case PIPE_CAPF_MAX_POINT_WIDTH_AA:
  247.                 return 8192.0f;
  248.         case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
  249.                 return 16.0f;
  250.         case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
  251.                 return 16.0f;
  252.         case PIPE_CAPF_GUARD_BAND_LEFT:
  253.         case PIPE_CAPF_GUARD_BAND_TOP:
  254.         case PIPE_CAPF_GUARD_BAND_RIGHT:
  255.         case PIPE_CAPF_GUARD_BAND_BOTTOM:
  256.                 return 0.0f;
  257.         default:
  258.                 DBG("unknown paramf %d", param);
  259.                 return 0;
  260.         }
  261. }
  262.  
  263. static int
  264. fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
  265.                 enum pipe_shader_cap param)
  266. {
  267.         switch(shader)
  268.         {
  269.         case PIPE_SHADER_FRAGMENT:
  270.         case PIPE_SHADER_VERTEX:
  271.                 break;
  272.         case PIPE_SHADER_COMPUTE:
  273.         case PIPE_SHADER_GEOMETRY:
  274.                 /* maye we could emulate.. */
  275.                 return 0;
  276.         default:
  277.                 DBG("unknown shader type %d", shader);
  278.                 return 0;
  279.         }
  280.  
  281.         /* this is probably not totally correct.. but it's a start: */
  282.         switch (param) {
  283.         case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
  284.         case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
  285.         case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
  286.         case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
  287.                 return 16384;
  288.         case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
  289.                 return 8; /* XXX */
  290.         case PIPE_SHADER_CAP_MAX_INPUTS:
  291.                 return 32;
  292.         case PIPE_SHADER_CAP_MAX_TEMPS:
  293.                 return 256; /* Max native temporaries. */
  294.         case PIPE_SHADER_CAP_MAX_ADDRS:
  295.                 /* XXX Isn't this equal to TEMPS? */
  296.                 return 1; /* Max native address registers */
  297.         case PIPE_SHADER_CAP_MAX_CONSTS:
  298.         case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
  299.                 return 64;
  300.         case PIPE_SHADER_CAP_MAX_PREDS:
  301.                 return 0; /* nothing uses this */
  302.         case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
  303.                 return 1;
  304.         case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
  305.         case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
  306.         case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
  307.         case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
  308.                 return 1;
  309.         case PIPE_SHADER_CAP_SUBROUTINES:
  310.                 return 0;
  311.         case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
  312.         case PIPE_SHADER_CAP_INTEGERS:
  313.                 return 0;
  314.         case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
  315.                 return 16;
  316.         case PIPE_SHADER_CAP_PREFERRED_IR:
  317.                 return PIPE_SHADER_IR_TGSI;
  318.         default:
  319.                 DBG("unknown shader param %d", param);
  320.                 return 0;
  321.         }
  322.         return 0;
  323. }
  324.  
  325. boolean
  326. fd_screen_bo_get_handle(struct pipe_screen *pscreen,
  327.                 struct fd_bo *bo,
  328.                 unsigned stride,
  329.                 struct winsys_handle *whandle)
  330. {
  331.         whandle->stride = stride;
  332.  
  333.         if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
  334.                 return fd_bo_get_name(bo, &whandle->handle) == 0;
  335.         } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
  336.                 whandle->handle = fd_bo_handle(bo);
  337.                 return TRUE;
  338.         } else {
  339.                 return FALSE;
  340.         }
  341. }
  342.  
  343. struct fd_bo *
  344. fd_screen_bo_from_handle(struct pipe_screen *pscreen,
  345.                 struct winsys_handle *whandle,
  346.                 unsigned *out_stride)
  347. {
  348.         struct fd_screen *screen = fd_screen(pscreen);
  349.         struct fd_bo *bo;
  350.  
  351.         bo = fd_bo_from_name(screen->dev, whandle->handle);
  352.         if (!bo) {
  353.                 DBG("ref name 0x%08x failed", whandle->handle);
  354.                 return NULL;
  355.         }
  356.  
  357.         *out_stride = whandle->stride;
  358.  
  359.         return bo;
  360. }
  361.  
  362. struct pipe_screen *
  363. fd_screen_create(struct fd_device *dev)
  364. {
  365.         struct fd_screen *screen = CALLOC_STRUCT(fd_screen);
  366.         struct pipe_screen *pscreen;
  367.         uint64_t val;
  368.  
  369.         fd_mesa_debug = debug_get_option_fd_mesa_debug();
  370.  
  371.         if (!screen)
  372.                 return NULL;
  373.  
  374.         pscreen = &screen->base;
  375.  
  376.         screen->dev = dev;
  377.  
  378.         // maybe this should be in context?
  379.         screen->pipe = fd_pipe_new(screen->dev, FD_PIPE_3D);
  380.         if (!screen->pipe) {
  381.                 DBG("could not create 3d pipe");
  382.                 goto fail;
  383.         }
  384.  
  385.         if (fd_pipe_get_param(screen->pipe, FD_GMEM_SIZE, &val)) {
  386.                 DBG("could not get GMEM size");
  387.                 goto fail;
  388.         }
  389.         screen->gmemsize_bytes = val;
  390.  
  391.         if (fd_pipe_get_param(screen->pipe, FD_DEVICE_ID, &val)) {
  392.                 DBG("could not get device-id");
  393.                 goto fail;
  394.         }
  395.         screen->device_id = val;
  396.  
  397.         if (fd_pipe_get_param(screen->pipe, FD_GPU_ID, &val)) {
  398.                 DBG("could not get gpu-id");
  399.                 goto fail;
  400.         }
  401.         screen->gpu_id = val;
  402.  
  403.         /* explicitly checking for GPU revisions that are known to work.  This
  404.          * may be overly conservative for a3xx, where spoofing the gpu_id with
  405.          * the blob driver seems to generate identical cmdstream dumps.  But
  406.          * on a2xx, there seem to be small differences between the GPU revs
  407.          * so it is probably better to actually test first on real hardware
  408.          * before enabling:
  409.          *
  410.          * If you have a different adreno version, feel free to add it to one
  411.          * of the two cases below and see what happens.  And if it works, please
  412.          * send a patch ;-)
  413.          */
  414.         switch (screen->gpu_id) {
  415.         case 220:
  416.                 fd2_screen_init(pscreen);
  417.                 break;
  418.         case 320:
  419.                 fd3_screen_init(pscreen);
  420.                 break;
  421.         default:
  422.                 debug_printf("unsupported GPU: a%03d\n", screen->gpu_id);
  423.                 goto fail;
  424.         }
  425.  
  426.         pscreen->destroy = fd_screen_destroy;
  427.         pscreen->get_param = fd_screen_get_param;
  428.         pscreen->get_paramf = fd_screen_get_paramf;
  429.         pscreen->get_shader_param = fd_screen_get_shader_param;
  430.  
  431.         fd_resource_screen_init(pscreen);
  432.  
  433.         pscreen->get_name = fd_screen_get_name;
  434.         pscreen->get_vendor = fd_screen_get_vendor;
  435.  
  436.         pscreen->get_timestamp = fd_screen_get_timestamp;
  437.  
  438.         pscreen->fence_reference = fd_screen_fence_ref;
  439.         pscreen->fence_signalled = fd_screen_fence_signalled;
  440.         pscreen->fence_finish = fd_screen_fence_finish;
  441.  
  442.         util_format_s3tc_init();
  443.  
  444.         return pscreen;
  445.  
  446. fail:
  447.         fd_screen_destroy(pscreen);
  448.         return NULL;
  449. }
  450.