Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  8.  * license, and/or sell copies of the Software, and to permit persons to whom
  9.  * the Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  18.  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  21.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  22.  */
  23. #include <stdio.h>
  24. #include <errno.h>
  25. #include "pipe/p_defines.h"
  26. #include "pipe/p_state.h"
  27. #include "pipe/p_context.h"
  28. #include "tgsi/tgsi_scan.h"
  29. #include "tgsi/tgsi_parse.h"
  30. #include "tgsi/tgsi_util.h"
  31. #include "util/u_blitter.h"
  32. #include "util/u_double_list.h"
  33. #include "util/u_format.h"
  34. #include "util/u_format_s3tc.h"
  35. #include "util/u_transfer.h"
  36. #include "util/u_surface.h"
  37. #include "util/u_pack_color.h"
  38. #include "util/u_memory.h"
  39. #include "util/u_inlines.h"
  40. #include "util/u_simple_shaders.h"
  41. #include "util/u_upload_mgr.h"
  42. #include "vl/vl_decoder.h"
  43. #include "vl/vl_video_buffer.h"
  44. #include "os/os_time.h"
  45. #include "pipebuffer/pb_buffer.h"
  46. #include "radeonsi_pipe.h"
  47. #include "radeon/radeon_uvd.h"
  48. #include "r600.h"
  49. #include "sid.h"
  50. #include "r600_resource.h"
  51. #include "radeonsi_pipe.h"
  52. #include "r600_hw_context_priv.h"
  53. #include "si_state.h"
  54.  
  55. /*
  56.  * pipe_context
  57.  */
  58. static struct r600_fence *r600_create_fence(struct r600_context *rctx)
  59. {
  60.         struct r600_screen *rscreen = rctx->screen;
  61.         struct r600_fence *fence = NULL;
  62.  
  63.         pipe_mutex_lock(rscreen->fences.mutex);
  64.  
  65.         if (!rscreen->fences.bo) {
  66.                 /* Create the shared buffer object */
  67.                 rscreen->fences.bo = si_resource_create_custom(&rscreen->screen,
  68.                                                                PIPE_USAGE_STAGING,
  69.                                                                4096);
  70.                 if (!rscreen->fences.bo) {
  71.                         R600_ERR("r600: failed to create bo for fence objects\n");
  72.                         goto out;
  73.                 }
  74.                 rscreen->fences.data = rctx->ws->buffer_map(rscreen->fences.bo->cs_buf,
  75.                                                            rctx->cs,
  76.                                                            PIPE_TRANSFER_READ_WRITE);
  77.         }
  78.  
  79.         if (!LIST_IS_EMPTY(&rscreen->fences.pool)) {
  80.                 struct r600_fence *entry;
  81.  
  82.                 /* Try to find a freed fence that has been signalled */
  83.                 LIST_FOR_EACH_ENTRY(entry, &rscreen->fences.pool, head) {
  84.                         if (rscreen->fences.data[entry->index] != 0) {
  85.                                 LIST_DELINIT(&entry->head);
  86.                                 fence = entry;
  87.                                 break;
  88.                         }
  89.                 }
  90.         }
  91.  
  92.         if (!fence) {
  93.                 /* Allocate a new fence */
  94.                 struct r600_fence_block *block;
  95.                 unsigned index;
  96.  
  97.                 if ((rscreen->fences.next_index + 1) >= 1024) {
  98.                         R600_ERR("r600: too many concurrent fences\n");
  99.                         goto out;
  100.                 }
  101.  
  102.                 index = rscreen->fences.next_index++;
  103.  
  104.                 if (!(index % FENCE_BLOCK_SIZE)) {
  105.                         /* Allocate a new block */
  106.                         block = CALLOC_STRUCT(r600_fence_block);
  107.                         if (block == NULL)
  108.                                 goto out;
  109.  
  110.                         LIST_ADD(&block->head, &rscreen->fences.blocks);
  111.                 } else {
  112.                         block = LIST_ENTRY(struct r600_fence_block, rscreen->fences.blocks.next, head);
  113.                 }
  114.  
  115.                 fence = &block->fences[index % FENCE_BLOCK_SIZE];
  116.                 fence->index = index;
  117.         }
  118.  
  119.         pipe_reference_init(&fence->reference, 1);
  120.  
  121.         rscreen->fences.data[fence->index] = 0;
  122.         si_context_emit_fence(rctx, rscreen->fences.bo, fence->index, 1);
  123.  
  124.         /* Create a dummy BO so that fence_finish without a timeout can sleep waiting for completion */
  125.         fence->sleep_bo = si_resource_create_custom(&rctx->screen->screen, PIPE_USAGE_STAGING, 1);
  126.  
  127.         /* Add the fence as a dummy relocation. */
  128.         r600_context_bo_reloc(rctx, fence->sleep_bo, RADEON_USAGE_READWRITE);
  129.  
  130. out:
  131.         pipe_mutex_unlock(rscreen->fences.mutex);
  132.         return fence;
  133. }
  134.  
  135.  
  136. void radeonsi_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence,
  137.                     unsigned flags)
  138. {
  139.         struct r600_context *rctx = (struct r600_context *)ctx;
  140.         struct r600_fence **rfence = (struct r600_fence**)fence;
  141.         struct pipe_query *render_cond = NULL;
  142.         boolean render_cond_cond = FALSE;
  143.         unsigned render_cond_mode = 0;
  144.  
  145.         if (rfence)
  146.                 *rfence = r600_create_fence(rctx);
  147.  
  148.         /* Disable render condition. */
  149.         if (rctx->current_render_cond) {
  150.                 render_cond = rctx->current_render_cond;
  151.                 render_cond_cond = rctx->current_render_cond_cond;
  152.                 render_cond_mode = rctx->current_render_cond_mode;
  153.                 ctx->render_condition(ctx, NULL, FALSE, 0);
  154.         }
  155.  
  156.         si_context_flush(rctx, flags);
  157.  
  158.         /* Re-enable render condition. */
  159.         if (render_cond) {
  160.                 ctx->render_condition(ctx, render_cond, render_cond_cond, render_cond_mode);
  161.         }
  162. }
  163.  
  164. static void r600_flush_from_st(struct pipe_context *ctx,
  165.                                struct pipe_fence_handle **fence,
  166.                                unsigned flags)
  167. {
  168.         radeonsi_flush(ctx, fence,
  169.                        flags & PIPE_FLUSH_END_OF_FRAME ? RADEON_FLUSH_END_OF_FRAME : 0);
  170. }
  171.  
  172. static void r600_flush_from_winsys(void *ctx, unsigned flags)
  173. {
  174.         radeonsi_flush((struct pipe_context*)ctx, NULL, flags);
  175. }
  176.  
  177. static void r600_destroy_context(struct pipe_context *context)
  178. {
  179.         struct r600_context *rctx = (struct r600_context *)context;
  180.  
  181.         si_resource_reference(&rctx->border_color_table, NULL);
  182.  
  183.         if (rctx->dummy_pixel_shader) {
  184.                 rctx->context.delete_fs_state(&rctx->context, rctx->dummy_pixel_shader);
  185.         }
  186.         rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush_depth_stencil);
  187.         rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush_depth);
  188.         rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush_stencil);
  189.         rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush_inplace);
  190.         util_unreference_framebuffer_state(&rctx->framebuffer);
  191.  
  192.         util_blitter_destroy(rctx->blitter);
  193.  
  194.         if (rctx->uploader) {
  195.                 u_upload_destroy(rctx->uploader);
  196.         }
  197.         util_slab_destroy(&rctx->pool_transfers);
  198.         FREE(rctx);
  199. }
  200.  
  201. static struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
  202. {
  203.         struct r600_context *rctx = CALLOC_STRUCT(r600_context);
  204.         struct r600_screen* rscreen = (struct r600_screen *)screen;
  205.  
  206.         if (rctx == NULL)
  207.                 return NULL;
  208.  
  209.         rctx->context.screen = screen;
  210.         rctx->context.priv = priv;
  211.         rctx->context.destroy = r600_destroy_context;
  212.         rctx->context.flush = r600_flush_from_st;
  213.  
  214.         /* Easy accessing of screen/winsys. */
  215.         rctx->screen = rscreen;
  216.         rctx->ws = rscreen->ws;
  217.         rctx->family = rscreen->family;
  218.         rctx->chip_class = rscreen->chip_class;
  219.  
  220.         si_init_blit_functions(rctx);
  221.         r600_init_query_functions(rctx);
  222.         r600_init_context_resource_functions(rctx);
  223.         si_init_surface_functions(rctx);
  224.         si_init_compute_functions(rctx);
  225.  
  226.         if (rscreen->info.has_uvd) {
  227.                 rctx->context.create_video_decoder = radeonsi_uvd_create_decoder;
  228.                 rctx->context.create_video_buffer = radeonsi_video_buffer_create;
  229.         } else {
  230.                 rctx->context.create_video_decoder = vl_create_decoder;
  231.                 rctx->context.create_video_buffer = vl_video_buffer_create;
  232.         }
  233.  
  234.         switch (rctx->chip_class) {
  235.         case SI:
  236.                 si_init_state_functions(rctx);
  237.                 LIST_INITHEAD(&rctx->active_query_list);
  238.                 rctx->cs = rctx->ws->cs_create(rctx->ws, RING_GFX, NULL);
  239.                 rctx->max_db = 8;
  240.                 si_init_config(rctx);
  241.                 break;
  242.         case CIK:
  243.                 si_init_state_functions(rctx);
  244.                 LIST_INITHEAD(&rctx->active_query_list);
  245.                 rctx->cs = rctx->ws->cs_create(rctx->ws, RING_GFX, NULL);
  246.                 rctx->max_db = 8;
  247.                 si_init_config(rctx);
  248.                 break;
  249.         default:
  250.                 R600_ERR("Unsupported chip class %d.\n", rctx->chip_class);
  251.                 r600_destroy_context(&rctx->context);
  252.                 return NULL;
  253.         }
  254.  
  255.         rctx->ws->cs_set_flush_callback(rctx->cs, r600_flush_from_winsys, rctx);
  256.  
  257.         util_slab_create(&rctx->pool_transfers,
  258.                          sizeof(struct pipe_transfer), 64,
  259.                          UTIL_SLAB_SINGLETHREADED);
  260.  
  261.         rctx->uploader = u_upload_create(&rctx->context, 1024 * 1024, 256,
  262.                                          PIPE_BIND_INDEX_BUFFER |
  263.                                          PIPE_BIND_CONSTANT_BUFFER);
  264.         if (!rctx->uploader) {
  265.                 r600_destroy_context(&rctx->context);
  266.                 return NULL;
  267.         }
  268.  
  269.         rctx->blitter = util_blitter_create(&rctx->context);
  270.         if (rctx->blitter == NULL) {
  271.                 r600_destroy_context(&rctx->context);
  272.                 return NULL;
  273.         }
  274.  
  275.         si_get_backend_mask(rctx); /* this emits commands and must be last */
  276.  
  277.         rctx->dummy_pixel_shader =
  278.                 util_make_fragment_cloneinput_shader(&rctx->context, 0,
  279.                                                      TGSI_SEMANTIC_GENERIC,
  280.                                                      TGSI_INTERPOLATE_CONSTANT);
  281.         rctx->context.bind_fs_state(&rctx->context, rctx->dummy_pixel_shader);
  282.  
  283.         return &rctx->context;
  284. }
  285.  
  286. /*
  287.  * pipe_screen
  288.  */
  289. static const char* r600_get_vendor(struct pipe_screen* pscreen)
  290. {
  291.         return "X.Org";
  292. }
  293.  
  294. const char *r600_get_llvm_processor_name(enum radeon_family family)
  295. {
  296.         switch (family) {
  297.                 case CHIP_TAHITI: return "tahiti";
  298.                 case CHIP_PITCAIRN: return "pitcairn";
  299.                 case CHIP_VERDE: return "verde";
  300.                 case CHIP_OLAND: return "oland";
  301. #if HAVE_LLVM <= 0x0303
  302.                 default: return "SI";
  303. #else
  304.                 case CHIP_HAINAN: return "hainan";
  305.                 case CHIP_BONAIRE: return "bonaire";
  306.                 case CHIP_KABINI: return "kabini";
  307.                 case CHIP_KAVERI: return "kaveri";
  308.                 default: return "";
  309. #endif
  310.         }
  311. }
  312.  
  313. static const char *r600_get_family_name(enum radeon_family family)
  314. {
  315.         switch(family) {
  316.         case CHIP_TAHITI: return "AMD TAHITI";
  317.         case CHIP_PITCAIRN: return "AMD PITCAIRN";
  318.         case CHIP_VERDE: return "AMD CAPE VERDE";
  319.         case CHIP_OLAND: return "AMD OLAND";
  320.         case CHIP_HAINAN: return "AMD HAINAN";
  321.         case CHIP_BONAIRE: return "AMD BONAIRE";
  322.         case CHIP_KAVERI: return "AMD KAVERI";
  323.         case CHIP_KABINI: return "AMD KABINI";
  324.         default: return "AMD unknown";
  325.         }
  326. }
  327.  
  328. static const char* r600_get_name(struct pipe_screen* pscreen)
  329. {
  330.         struct r600_screen *rscreen = (struct r600_screen *)pscreen;
  331.  
  332.         return r600_get_family_name(rscreen->family);
  333. }
  334.  
  335. static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
  336. {
  337.         struct r600_screen *rscreen = (struct r600_screen *)pscreen;
  338.  
  339.         switch (param) {
  340.         /* Supported features (boolean caps). */
  341.         case PIPE_CAP_TWO_SIDED_STENCIL:
  342.         case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
  343.         case PIPE_CAP_ANISOTROPIC_FILTER:
  344.         case PIPE_CAP_POINT_SPRITE:
  345.         case PIPE_CAP_OCCLUSION_QUERY:
  346.         case PIPE_CAP_TEXTURE_SHADOW_MAP:
  347.         case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
  348.         case PIPE_CAP_BLEND_EQUATION_SEPARATE:
  349.         case PIPE_CAP_TEXTURE_SWIZZLE:
  350.         case PIPE_CAP_DEPTH_CLIP_DISABLE:
  351.         case PIPE_CAP_SHADER_STENCIL_EXPORT:
  352.         case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
  353.         case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
  354.         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
  355.         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
  356.         case PIPE_CAP_SM3:
  357.         case PIPE_CAP_SEAMLESS_CUBE_MAP:
  358.         case PIPE_CAP_PRIMITIVE_RESTART:
  359.         case PIPE_CAP_CONDITIONAL_RENDER:
  360.         case PIPE_CAP_TEXTURE_BARRIER:
  361.         case PIPE_CAP_INDEP_BLEND_ENABLE:
  362.         case PIPE_CAP_INDEP_BLEND_FUNC:
  363.         case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
  364.         case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
  365.         case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
  366.         case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
  367.         case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
  368.         case PIPE_CAP_USER_INDEX_BUFFERS:
  369.         case PIPE_CAP_USER_CONSTANT_BUFFERS:
  370.         case PIPE_CAP_START_INSTANCE:
  371.         case PIPE_CAP_NPOT_TEXTURES:
  372.         case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
  373.         case PIPE_CAP_TGSI_INSTANCEID:
  374.         case PIPE_CAP_COMPUTE:
  375.                 return 1;
  376.         case PIPE_CAP_TGSI_TEXCOORD:
  377.                 return 0;
  378.  
  379.         case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
  380.                 return 64;
  381.  
  382.         case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
  383.                 return 256;
  384.  
  385.         case PIPE_CAP_GLSL_FEATURE_LEVEL:
  386.                 return 130;
  387.  
  388.         /* Unsupported features. */
  389.         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
  390.         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
  391.         case PIPE_CAP_SCALED_RESOLVE:
  392.         case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
  393.         case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
  394.         case PIPE_CAP_VERTEX_COLOR_CLAMPED:
  395.         case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
  396.         case PIPE_CAP_USER_VERTEX_BUFFERS:
  397.         case PIPE_CAP_TEXTURE_MULTISAMPLE:
  398.         case PIPE_CAP_QUERY_TIMESTAMP:
  399.         case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
  400.         case PIPE_CAP_CUBE_MAP_ARRAY:
  401.         case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
  402.         case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
  403.         case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
  404.         case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
  405.                 return 0;
  406.  
  407.         /* Stream output. */
  408. #if 0
  409.         case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
  410.                 return debug_get_bool_option("R600_STREAMOUT", FALSE) ? 4 : 0;
  411.         case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
  412.                 return debug_get_bool_option("R600_STREAMOUT", FALSE) ? 1 : 0;
  413.         case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
  414.         case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
  415.                 return 16*4;
  416. #endif
  417.         case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
  418.         case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
  419.         case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
  420.         case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
  421.                 return 0;
  422.  
  423.         /* Texturing. */
  424.         case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
  425.         case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
  426.         case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
  427.                         return 15;
  428.         case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
  429.                 return 16384;
  430.         case PIPE_CAP_MAX_COMBINED_SAMPLERS:
  431.                 return 32;
  432.  
  433.         /* Render targets. */
  434.         case PIPE_CAP_MAX_RENDER_TARGETS:
  435.                 /* FIXME some r6xx are buggy and can only do 4 */
  436.                 return 8;
  437.  
  438.         /* Timer queries, present when the clock frequency is non zero. */
  439.         case PIPE_CAP_QUERY_TIME_ELAPSED:
  440.                 return rscreen->info.r600_clock_crystal_freq != 0;
  441.  
  442.         case PIPE_CAP_MIN_TEXEL_OFFSET:
  443.                 return -8;
  444.  
  445.         case PIPE_CAP_MAX_TEXEL_OFFSET:
  446.                 return 7;
  447.         case PIPE_CAP_ENDIANNESS:
  448.                 return PIPE_ENDIAN_LITTLE;
  449.         }
  450.         return 0;
  451. }
  452.  
  453. static float r600_get_paramf(struct pipe_screen* pscreen,
  454.                              enum pipe_capf param)
  455. {
  456.         switch (param) {
  457.         case PIPE_CAPF_MAX_LINE_WIDTH:
  458.         case PIPE_CAPF_MAX_LINE_WIDTH_AA:
  459.         case PIPE_CAPF_MAX_POINT_WIDTH:
  460.         case PIPE_CAPF_MAX_POINT_WIDTH_AA:
  461.                 return 16384.0f;
  462.         case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
  463.                 return 16.0f;
  464.         case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
  465.                 return 16.0f;
  466.         case PIPE_CAPF_GUARD_BAND_LEFT:
  467.         case PIPE_CAPF_GUARD_BAND_TOP:
  468.         case PIPE_CAPF_GUARD_BAND_RIGHT:
  469.         case PIPE_CAPF_GUARD_BAND_BOTTOM:
  470.                 return 0.0f;
  471.         }
  472.         return 0.0f;
  473. }
  474.  
  475. static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enum pipe_shader_cap param)
  476. {
  477.         switch(shader)
  478.         {
  479.         case PIPE_SHADER_FRAGMENT:
  480.         case PIPE_SHADER_VERTEX:
  481.                 break;
  482.         case PIPE_SHADER_GEOMETRY:
  483.                 /* TODO: support and enable geometry programs */
  484.                 return 0;
  485.         case PIPE_SHADER_COMPUTE:
  486.                 switch (param) {
  487.                 case PIPE_SHADER_CAP_PREFERRED_IR:
  488.                         return PIPE_SHADER_IR_LLVM;
  489.                 default:
  490.                         return 0;
  491.                 }
  492.         default:
  493.                 /* TODO: support tessellation */
  494.                 return 0;
  495.         }
  496.  
  497.         switch (param) {
  498.         case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
  499.         case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
  500.         case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
  501.         case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
  502.                 return 16384;
  503.         case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
  504.                 return 32;
  505.         case PIPE_SHADER_CAP_MAX_INPUTS:
  506.                 return 32;
  507.         case PIPE_SHADER_CAP_MAX_TEMPS:
  508.                 return 256; /* Max native temporaries. */
  509.         case PIPE_SHADER_CAP_MAX_ADDRS:
  510.                 /* FIXME Isn't this equal to TEMPS? */
  511.                 return 1; /* Max native address registers */
  512.         case PIPE_SHADER_CAP_MAX_CONSTS:
  513.                 return 4096; /* actually only memory limits this */
  514.         case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
  515.                 return 1;
  516.         case PIPE_SHADER_CAP_MAX_PREDS:
  517.                 return 0; /* FIXME */
  518.         case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
  519.                 return 1;
  520.         case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
  521.                 return 0;
  522.         case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
  523.         case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
  524.         case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
  525.         case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
  526.                 return 1;
  527.         case PIPE_SHADER_CAP_INTEGERS:
  528.                 return 1;
  529.         case PIPE_SHADER_CAP_SUBROUTINES:
  530.                 return 0;
  531.         case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
  532.                 return 16;
  533.         case PIPE_SHADER_CAP_PREFERRED_IR:
  534.                 return PIPE_SHADER_IR_TGSI;
  535.         }
  536.         return 0;
  537. }
  538.  
  539. static int r600_get_video_param(struct pipe_screen *screen,
  540.                                 enum pipe_video_profile profile,
  541.                                 enum pipe_video_cap param)
  542. {
  543.         switch (param) {
  544.         case PIPE_VIDEO_CAP_SUPPORTED:
  545.                 return vl_profile_supported(screen, profile);
  546.         case PIPE_VIDEO_CAP_NPOT_TEXTURES:
  547.                 return 1;
  548.         case PIPE_VIDEO_CAP_MAX_WIDTH:
  549.         case PIPE_VIDEO_CAP_MAX_HEIGHT:
  550.                 return vl_video_buffer_max_size(screen);
  551.         case PIPE_VIDEO_CAP_PREFERED_FORMAT:
  552.                 return PIPE_FORMAT_NV12;
  553.         default:
  554.                 return 0;
  555.         }
  556. }
  557.  
  558. static int r600_get_compute_param(struct pipe_screen *screen,
  559.         enum pipe_compute_cap param,
  560.         void *ret)
  561. {
  562.         struct r600_screen *rscreen = (struct r600_screen *)screen;
  563.         //TODO: select these params by asic
  564.         switch (param) {
  565.         case PIPE_COMPUTE_CAP_IR_TARGET: {
  566.                 const char *gpu = r600_get_llvm_processor_name(rscreen->family);
  567.                 if (ret) {
  568.                         sprintf(ret, "%s-r600--", gpu);
  569.                 }
  570.                 return (8 + strlen(gpu)) * sizeof(char);
  571.         }
  572.         case PIPE_COMPUTE_CAP_GRID_DIMENSION:
  573.                 if (ret) {
  574.                         uint64_t * grid_dimension = ret;
  575.                         grid_dimension[0] = 3;
  576.                 }
  577.                 return 1 * sizeof(uint64_t);
  578.         case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
  579.                 if (ret) {
  580.                         uint64_t * grid_size = ret;
  581.                         grid_size[0] = 65535;
  582.                         grid_size[1] = 65535;
  583.                         grid_size[2] = 1;
  584.                 }
  585.                 return 3 * sizeof(uint64_t) ;
  586.  
  587.         case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
  588.                 if (ret) {
  589.                         uint64_t * block_size = ret;
  590.                         block_size[0] = 256;
  591.                         block_size[1] = 256;
  592.                         block_size[2] = 256;
  593.                 }
  594.                 return 3 * sizeof(uint64_t);
  595.         case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
  596.                 if (ret) {
  597.                         uint64_t * max_threads_per_block = ret;
  598.                         *max_threads_per_block = 256;
  599.                 }
  600.                 return sizeof(uint64_t);
  601.  
  602.         case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE:
  603.                 if (ret) {
  604.                         uint64_t *max_global_size = ret;
  605.                         /* XXX: Not sure what to put here. */
  606.                         *max_global_size = 2000000000;
  607.                 }
  608.                 return sizeof(uint64_t);
  609.  
  610.         case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE:
  611.                 if (ret) {
  612.                         uint64_t max_global_size;
  613.                         uint64_t *max_mem_alloc_size = ret;
  614.                         r600_get_compute_param(screen, PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE, &max_global_size);
  615.                         *max_mem_alloc_size = max_global_size / 4;
  616.                 }
  617.                 return sizeof(uint64_t);
  618.         default:
  619.                 fprintf(stderr, "unknown PIPE_COMPUTE_CAP %d\n", param);
  620.                 return 0;
  621.         }
  622. }
  623.  
  624. static void r600_destroy_screen(struct pipe_screen* pscreen)
  625. {
  626.         struct r600_screen *rscreen = (struct r600_screen *)pscreen;
  627.  
  628.         if (rscreen == NULL)
  629.                 return;
  630.  
  631.         if (rscreen->fences.bo) {
  632.                 struct r600_fence_block *entry, *tmp;
  633.  
  634.                 LIST_FOR_EACH_ENTRY_SAFE(entry, tmp, &rscreen->fences.blocks, head) {
  635.                         LIST_DEL(&entry->head);
  636.                         FREE(entry);
  637.                 }
  638.  
  639.                 rscreen->ws->buffer_unmap(rscreen->fences.bo->cs_buf);
  640.                 si_resource_reference(&rscreen->fences.bo, NULL);
  641.         }
  642.  
  643. #if R600_TRACE_CS
  644.         if (rscreen->trace_bo) {
  645.                 rscreen->ws->buffer_unmap(rscreen->trace_bo->cs_buf);
  646.                 pipe_resource_reference((struct pipe_resource**)&rscreen->trace_bo, NULL);
  647.         }
  648. #endif
  649.  
  650.         pipe_mutex_destroy(rscreen->fences.mutex);
  651.  
  652.         rscreen->ws->destroy(rscreen->ws);
  653.         FREE(rscreen);
  654. }
  655.  
  656. static void r600_fence_reference(struct pipe_screen *pscreen,
  657.                                  struct pipe_fence_handle **ptr,
  658.                                  struct pipe_fence_handle *fence)
  659. {
  660.         struct r600_fence **oldf = (struct r600_fence**)ptr;
  661.         struct r600_fence *newf = (struct r600_fence*)fence;
  662.  
  663.         if (pipe_reference(&(*oldf)->reference, &newf->reference)) {
  664.                 struct r600_screen *rscreen = (struct r600_screen *)pscreen;
  665.                 pipe_mutex_lock(rscreen->fences.mutex);
  666.                 si_resource_reference(&(*oldf)->sleep_bo, NULL);
  667.                 LIST_ADDTAIL(&(*oldf)->head, &rscreen->fences.pool);
  668.                 pipe_mutex_unlock(rscreen->fences.mutex);
  669.         }
  670.  
  671.         *ptr = fence;
  672. }
  673.  
  674. static boolean r600_fence_signalled(struct pipe_screen *pscreen,
  675.                                     struct pipe_fence_handle *fence)
  676. {
  677.         struct r600_screen *rscreen = (struct r600_screen *)pscreen;
  678.         struct r600_fence *rfence = (struct r600_fence*)fence;
  679.  
  680.         return rscreen->fences.data[rfence->index] != 0;
  681. }
  682.  
  683. static boolean r600_fence_finish(struct pipe_screen *pscreen,
  684.                                  struct pipe_fence_handle *fence,
  685.                                  uint64_t timeout)
  686. {
  687.         struct r600_screen *rscreen = (struct r600_screen *)pscreen;
  688.         struct r600_fence *rfence = (struct r600_fence*)fence;
  689.         int64_t start_time = 0;
  690.         unsigned spins = 0;
  691.  
  692.         if (timeout != PIPE_TIMEOUT_INFINITE) {
  693.                 start_time = os_time_get();
  694.  
  695.                 /* Convert to microseconds. */
  696.                 timeout /= 1000;
  697.         }
  698.  
  699.         while (rscreen->fences.data[rfence->index] == 0) {
  700.                 /* Special-case infinite timeout - wait for the dummy BO to become idle */
  701.                 if (timeout == PIPE_TIMEOUT_INFINITE) {
  702.                         rscreen->ws->buffer_wait(rfence->sleep_bo->buf, RADEON_USAGE_READWRITE);
  703.                         break;
  704.                 }
  705.  
  706.                 /* The dummy BO will be busy until the CS including the fence has completed, or
  707.                  * the GPU is reset. Don't bother continuing to spin when the BO is idle. */
  708.                 if (!rscreen->ws->buffer_is_busy(rfence->sleep_bo->buf, RADEON_USAGE_READWRITE))
  709.                         break;
  710.  
  711.                 if (++spins % 256)
  712.                         continue;
  713. #ifdef PIPE_OS_UNIX
  714.                 sched_yield();
  715. #else
  716.                 os_time_sleep(10);
  717. #endif
  718.                 if (timeout != PIPE_TIMEOUT_INFINITE &&
  719.                     os_time_get() - start_time >= timeout) {
  720.                         break;
  721.                 }
  722.         }
  723.  
  724.         return rscreen->fences.data[rfence->index] != 0;
  725. }
  726.  
  727. static int evergreen_interpret_tiling(struct r600_screen *rscreen, uint32_t tiling_config)
  728. {
  729.         switch (tiling_config & 0xf) {
  730.         case 0:
  731.                 rscreen->tiling_info.num_channels = 1;
  732.                 break;
  733.         case 1:
  734.                 rscreen->tiling_info.num_channels = 2;
  735.                 break;
  736.         case 2:
  737.                 rscreen->tiling_info.num_channels = 4;
  738.                 break;
  739.         case 3:
  740.                 rscreen->tiling_info.num_channels = 8;
  741.                 break;
  742.         default:
  743.                 return -EINVAL;
  744.         }
  745.  
  746.         switch ((tiling_config & 0xf0) >> 4) {
  747.         case 0:
  748.                 rscreen->tiling_info.num_banks = 4;
  749.                 break;
  750.         case 1:
  751.                 rscreen->tiling_info.num_banks = 8;
  752.                 break;
  753.         case 2:
  754.                 rscreen->tiling_info.num_banks = 16;
  755.                 break;
  756.         default:
  757.                 return -EINVAL;
  758.         }
  759.  
  760.         switch ((tiling_config & 0xf00) >> 8) {
  761.         case 0:
  762.                 rscreen->tiling_info.group_bytes = 256;
  763.                 break;
  764.         case 1:
  765.                 rscreen->tiling_info.group_bytes = 512;
  766.                 break;
  767.         default:
  768.                 return -EINVAL;
  769.         }
  770.         return 0;
  771. }
  772.  
  773. static int r600_init_tiling(struct r600_screen *rscreen)
  774. {
  775.         uint32_t tiling_config = rscreen->info.r600_tiling_config;
  776.  
  777.         /* set default group bytes, overridden by tiling info ioctl */
  778.         rscreen->tiling_info.group_bytes = 512;
  779.  
  780.         if (!tiling_config)
  781.                 return 0;
  782.  
  783.         return evergreen_interpret_tiling(rscreen, tiling_config);
  784. }
  785.  
  786. static unsigned radeon_family_from_device(unsigned device)
  787. {
  788.         switch (device) {
  789. #define CHIPSET(pciid, name, family) case pciid: return CHIP_##family;
  790. #include "pci_ids/radeonsi_pci_ids.h"
  791. #undef CHIPSET
  792.         default:
  793.                 return CHIP_UNKNOWN;
  794.         }
  795. }
  796.  
  797. struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws)
  798. {
  799.         struct r600_screen *rscreen = CALLOC_STRUCT(r600_screen);
  800.         if (rscreen == NULL) {
  801.                 return NULL;
  802.         }
  803.  
  804.         rscreen->ws = ws;
  805.         ws->query_info(ws, &rscreen->info);
  806.  
  807.         rscreen->family = radeon_family_from_device(rscreen->info.pci_id);
  808.         if (rscreen->family == CHIP_UNKNOWN) {
  809.                 fprintf(stderr, "r600: Unknown chipset 0x%04X\n", rscreen->info.pci_id);
  810.                 FREE(rscreen);
  811.                 return NULL;
  812.         }
  813.  
  814.         /* setup class */
  815.         if (rscreen->family >= CHIP_BONAIRE) {
  816.                 rscreen->chip_class = CIK;
  817.         } else if (rscreen->family >= CHIP_TAHITI) {
  818.                 rscreen->chip_class = SI;
  819.         } else {
  820.                 fprintf(stderr, "r600: Unsupported family %d\n", rscreen->family);
  821.                 FREE(rscreen);
  822.                 return NULL;
  823.         }
  824.  
  825.         if (r600_init_tiling(rscreen)) {
  826.                 FREE(rscreen);
  827.                 return NULL;
  828.         }
  829.  
  830.         rscreen->screen.destroy = r600_destroy_screen;
  831.         rscreen->screen.get_name = r600_get_name;
  832.         rscreen->screen.get_vendor = r600_get_vendor;
  833.         rscreen->screen.get_param = r600_get_param;
  834.         rscreen->screen.get_shader_param = r600_get_shader_param;
  835.         rscreen->screen.get_paramf = r600_get_paramf;
  836.         rscreen->screen.get_compute_param = r600_get_compute_param;
  837.         rscreen->screen.is_format_supported = si_is_format_supported;
  838.         rscreen->screen.context_create = r600_create_context;
  839.         rscreen->screen.fence_reference = r600_fence_reference;
  840.         rscreen->screen.fence_signalled = r600_fence_signalled;
  841.         rscreen->screen.fence_finish = r600_fence_finish;
  842.         r600_init_screen_resource_functions(&rscreen->screen);
  843.  
  844.         if (rscreen->info.has_uvd) {
  845.                 rscreen->screen.get_video_param = ruvd_get_video_param;
  846.                 rscreen->screen.is_video_format_supported = ruvd_is_format_supported;
  847.         } else {
  848.                 rscreen->screen.get_video_param = r600_get_video_param;
  849.                 rscreen->screen.is_video_format_supported = vl_video_buffer_is_format_supported;
  850.         }
  851.  
  852.         util_format_s3tc_init();
  853.  
  854.         rscreen->fences.bo = NULL;
  855.         rscreen->fences.data = NULL;
  856.         rscreen->fences.next_index = 0;
  857.         LIST_INITHEAD(&rscreen->fences.pool);
  858.         LIST_INITHEAD(&rscreen->fences.blocks);
  859.         pipe_mutex_init(rscreen->fences.mutex);
  860.  
  861. #if R600_TRACE_CS
  862.         rscreen->cs_count = 0;
  863.         if (rscreen->info.drm_minor >= 28) {
  864.                 rscreen->trace_bo = (struct si_resource*)pipe_buffer_create(&rscreen->screen,
  865.                                                                                 PIPE_BIND_CUSTOM,
  866.                                                                                 PIPE_USAGE_STAGING,
  867.                                                                                 4096);
  868.                 if (rscreen->trace_bo) {
  869.                         rscreen->trace_ptr = rscreen->ws->buffer_map(rscreen->trace_bo->cs_buf, NULL,
  870.                                                                         PIPE_TRANSFER_UNSYNCHRONIZED);
  871.                 }
  872.         }
  873. #endif
  874.  
  875.         return &rscreen->screen;
  876. }
  877.