Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2010 Christoph Bumiller
  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.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice shall be included in
  12.  * all copies or substantial portions of the Software.
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20.  * OTHER DEALINGS IN THE SOFTWARE.
  21.  */
  22.  
  23. #include <errno.h>
  24. #include <xf86drm.h>
  25. #include <nouveau_drm.h>
  26. #include "util/u_format.h"
  27. #include "util/u_format_s3tc.h"
  28. #include "pipe/p_screen.h"
  29.  
  30. #include "nv50/nv50_context.h"
  31. #include "nv50/nv50_screen.h"
  32.  
  33. #include "nouveau_vp3_video.h"
  34.  
  35. #include "nv_object.xml.h"
  36.  
  37. /* affected by LOCAL_WARPS_LOG_ALLOC / LOCAL_WARPS_NO_CLAMP */
  38. #define LOCAL_WARPS_ALLOC 32
  39. /* affected by STACK_WARPS_LOG_ALLOC / STACK_WARPS_NO_CLAMP */
  40. #define STACK_WARPS_ALLOC 32
  41.  
  42. #define THREADS_IN_WARP 32
  43.  
  44. #define ONE_TEMP_SIZE (4/*vector*/ * sizeof(float))
  45.  
  46. static boolean
  47. nv50_screen_is_format_supported(struct pipe_screen *pscreen,
  48.                                 enum pipe_format format,
  49.                                 enum pipe_texture_target target,
  50.                                 unsigned sample_count,
  51.                                 unsigned bindings)
  52. {
  53.    if (sample_count > 8)
  54.       return FALSE;
  55.    if (!(0x117 & (1 << sample_count))) /* 0, 1, 2, 4 or 8 */
  56.       return FALSE;
  57.    if (sample_count == 8 && util_format_get_blocksizebits(format) >= 128)
  58.       return FALSE;
  59.  
  60.    if (!util_format_is_supported(format, bindings))
  61.       return FALSE;
  62.  
  63.    switch (format) {
  64.    case PIPE_FORMAT_Z16_UNORM:
  65.       if (nv50_screen(pscreen)->tesla->oclass < NVA0_3D_CLASS)
  66.          return FALSE;
  67.       break;
  68.    default:
  69.       break;
  70.    }
  71.  
  72.    /* transfers & shared are always supported */
  73.    bindings &= ~(PIPE_BIND_TRANSFER_READ |
  74.                  PIPE_BIND_TRANSFER_WRITE |
  75.                  PIPE_BIND_SHARED);
  76.  
  77.    return (nv50_format_table[format].usage & bindings) == bindings;
  78. }
  79.  
  80. static int
  81. nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
  82. {
  83.    const uint16_t class_3d = nouveau_screen(pscreen)->class_3d;
  84.    struct nouveau_device *dev = nouveau_screen(pscreen)->device;
  85.  
  86.    switch (param) {
  87.    /* non-boolean caps */
  88.    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
  89.       return 14;
  90.    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
  91.       return 12;
  92.    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
  93.       return 14;
  94.    case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
  95.       return 512;
  96.    case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
  97.    case PIPE_CAP_MIN_TEXEL_OFFSET:
  98.       return -8;
  99.    case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
  100.    case PIPE_CAP_MAX_TEXEL_OFFSET:
  101.       return 7;
  102.    case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
  103.       return 65536;
  104.    case PIPE_CAP_GLSL_FEATURE_LEVEL:
  105.       return 330;
  106.    case PIPE_CAP_MAX_RENDER_TARGETS:
  107.       return 8;
  108.    case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
  109.       return 1;
  110.    case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
  111.       return 4;
  112.    case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
  113.    case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
  114.       return 64;
  115.    case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
  116.    case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
  117.       return 1024;
  118.    case PIPE_CAP_MAX_VERTEX_STREAMS:
  119.       return 1;
  120.    case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
  121.       return 2048;
  122.    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
  123.       return 256;
  124.    case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
  125.       return 1; /* 256 for binding as RT, but that's not possible in GL */
  126.    case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
  127.       return NOUVEAU_MIN_BUFFER_MAP_ALIGN;
  128.    case PIPE_CAP_MAX_VIEWPORTS:
  129.       return NV50_MAX_VIEWPORTS;
  130.    case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
  131.       return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50;
  132.    case PIPE_CAP_ENDIANNESS:
  133.       return PIPE_ENDIAN_LITTLE;
  134.    case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
  135.       return (class_3d >= NVA3_3D_CLASS) ? 4 : 0;
  136.  
  137.    /* supported caps */
  138.    case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
  139.    case PIPE_CAP_TEXTURE_SWIZZLE:
  140.    case PIPE_CAP_TEXTURE_SHADOW_MAP:
  141.    case PIPE_CAP_NPOT_TEXTURES:
  142.    case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
  143.    case PIPE_CAP_ANISOTROPIC_FILTER:
  144.    case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
  145.    case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
  146.    case PIPE_CAP_TWO_SIDED_STENCIL:
  147.    case PIPE_CAP_DEPTH_CLIP_DISABLE:
  148.    case PIPE_CAP_POINT_SPRITE:
  149.    case PIPE_CAP_SM3:
  150.    case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
  151.    case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
  152.    case PIPE_CAP_VERTEX_COLOR_CLAMPED:
  153.    case PIPE_CAP_QUERY_TIMESTAMP:
  154.    case PIPE_CAP_QUERY_TIME_ELAPSED:
  155.    case PIPE_CAP_OCCLUSION_QUERY:
  156.    case PIPE_CAP_BLEND_EQUATION_SEPARATE:
  157.    case PIPE_CAP_INDEP_BLEND_ENABLE:
  158.    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
  159.    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
  160.    case PIPE_CAP_PRIMITIVE_RESTART:
  161.    case PIPE_CAP_TGSI_INSTANCEID:
  162.    case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
  163.    case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
  164.    case PIPE_CAP_CONDITIONAL_RENDER:
  165.    case PIPE_CAP_TEXTURE_BARRIER:
  166.    case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
  167.    case PIPE_CAP_START_INSTANCE:
  168.    case PIPE_CAP_USER_CONSTANT_BUFFERS:
  169.    case PIPE_CAP_USER_INDEX_BUFFERS:
  170.    case PIPE_CAP_USER_VERTEX_BUFFERS:
  171.    case PIPE_CAP_TEXTURE_MULTISAMPLE:
  172.    case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
  173.    case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
  174.    case PIPE_CAP_SAMPLER_VIEW_TARGET:
  175.    case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
  176.    case PIPE_CAP_CLIP_HALFZ:
  177.    case PIPE_CAP_POLYGON_OFFSET_CLAMP:
  178.    case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
  179.       return 1;
  180.    case PIPE_CAP_SEAMLESS_CUBE_MAP:
  181.       return 1; /* class_3d >= NVA0_3D_CLASS; */
  182.    /* supported on nva0+ */
  183.    case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
  184.       return class_3d >= NVA0_3D_CLASS;
  185.    /* supported on nva3+ */
  186.    case PIPE_CAP_CUBE_MAP_ARRAY:
  187.    case PIPE_CAP_INDEP_BLEND_FUNC:
  188.    case PIPE_CAP_TEXTURE_QUERY_LOD:
  189.    case PIPE_CAP_SAMPLE_SHADING:
  190.       return class_3d >= NVA3_3D_CLASS;
  191.  
  192.    /* unsupported caps */
  193.    case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
  194.    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
  195.    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
  196.    case PIPE_CAP_SHADER_STENCIL_EXPORT:
  197.    case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
  198.    case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
  199.    case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
  200.    case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
  201.    case PIPE_CAP_TGSI_TEXCOORD:
  202.    case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
  203.    case PIPE_CAP_TEXTURE_GATHER_SM5:
  204.    case PIPE_CAP_FAKE_SW_MSAA:
  205.    case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
  206.    case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
  207.    case PIPE_CAP_COMPUTE:
  208.    case PIPE_CAP_DRAW_INDIRECT:
  209.    case PIPE_CAP_VERTEXID_NOBASE:
  210.    case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: /* potentially supported on some hw */
  211.    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
  212.    case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
  213.       return 0;
  214.  
  215.    case PIPE_CAP_VENDOR_ID:
  216.       return 0x10de;
  217.    case PIPE_CAP_DEVICE_ID: {
  218.       uint64_t device_id;
  219.       if (nouveau_getparam(dev, NOUVEAU_GETPARAM_PCI_DEVICE, &device_id)) {
  220.          NOUVEAU_ERR("NOUVEAU_GETPARAM_PCI_DEVICE failed.\n");
  221.          return -1;
  222.       }
  223.       return device_id;
  224.    }
  225.    case PIPE_CAP_ACCELERATED:
  226.       return 1;
  227.    case PIPE_CAP_VIDEO_MEMORY:
  228.       return dev->vram_size >> 20;
  229.    case PIPE_CAP_UMA:
  230.       return 0;
  231.    }
  232.  
  233.    NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
  234.    return 0;
  235. }
  236.  
  237. static int
  238. nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
  239.                              enum pipe_shader_cap param)
  240. {
  241.    switch (shader) {
  242.    case PIPE_SHADER_VERTEX:
  243.    case PIPE_SHADER_GEOMETRY:
  244.    case PIPE_SHADER_FRAGMENT:
  245.       break;
  246.    default:
  247.       return 0;
  248.    }
  249.  
  250.    switch (param) {
  251.    case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
  252.    case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
  253.    case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
  254.    case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
  255.       return 16384;
  256.    case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
  257.       return 4;
  258.    case PIPE_SHADER_CAP_MAX_INPUTS:
  259.       if (shader == PIPE_SHADER_VERTEX)
  260.          return 32;
  261.       return 15;
  262.    case PIPE_SHADER_CAP_MAX_OUTPUTS:
  263.       return 16;
  264.    case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
  265.       return 65536;
  266.    case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
  267.       return NV50_MAX_PIPE_CONSTBUFS;
  268.    case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
  269.    case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
  270.       return shader != PIPE_SHADER_FRAGMENT;
  271.    case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
  272.    case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
  273.       return 1;
  274.    case PIPE_SHADER_CAP_MAX_PREDS:
  275.       return 0;
  276.    case PIPE_SHADER_CAP_MAX_TEMPS:
  277.       return nv50_screen(pscreen)->max_tls_space / ONE_TEMP_SIZE;
  278.    case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
  279.       return 1;
  280.    case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
  281.       return 0;
  282.    case PIPE_SHADER_CAP_SUBROUTINES:
  283.       return 0; /* please inline, or provide function declarations */
  284.    case PIPE_SHADER_CAP_INTEGERS:
  285.       return 1;
  286.    case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
  287.       /* The chip could handle more sampler views than samplers */
  288.    case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
  289.       return MIN2(32, PIPE_MAX_SAMPLERS);
  290.    case PIPE_SHADER_CAP_DOUBLES:
  291.    case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
  292.    case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
  293.    case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
  294.       return 0;
  295.    default:
  296.       NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param);
  297.       return 0;
  298.    }
  299. }
  300.  
  301. static float
  302. nv50_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
  303. {
  304.    switch (param) {
  305.    case PIPE_CAPF_MAX_LINE_WIDTH:
  306.    case PIPE_CAPF_MAX_LINE_WIDTH_AA:
  307.       return 10.0f;
  308.    case PIPE_CAPF_MAX_POINT_WIDTH:
  309.    case PIPE_CAPF_MAX_POINT_WIDTH_AA:
  310.       return 64.0f;
  311.    case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
  312.       return 16.0f;
  313.    case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
  314.       return 4.0f;
  315.    case PIPE_CAPF_GUARD_BAND_LEFT:
  316.    case PIPE_CAPF_GUARD_BAND_TOP:
  317.       return 0.0f;
  318.    case PIPE_CAPF_GUARD_BAND_RIGHT:
  319.    case PIPE_CAPF_GUARD_BAND_BOTTOM:
  320.       return 0.0f; /* that or infinity */
  321.    }
  322.  
  323.    NOUVEAU_ERR("unknown PIPE_CAPF %d\n", param);
  324.    return 0.0f;
  325. }
  326.  
  327. static void
  328. nv50_screen_destroy(struct pipe_screen *pscreen)
  329. {
  330.    struct nv50_screen *screen = nv50_screen(pscreen);
  331.  
  332.    if (!nouveau_drm_screen_unref(&screen->base))
  333.       return;
  334.  
  335.    if (screen->base.fence.current) {
  336.       struct nouveau_fence *current = NULL;
  337.  
  338.       /* nouveau_fence_wait will create a new current fence, so wait on the
  339.        * _current_ one, and remove both.
  340.        */
  341.       nouveau_fence_ref(screen->base.fence.current, &current);
  342.       nouveau_fence_wait(current);
  343.       nouveau_fence_ref(NULL, &current);
  344.       nouveau_fence_ref(NULL, &screen->base.fence.current);
  345.    }
  346.    if (screen->base.pushbuf)
  347.       screen->base.pushbuf->user_priv = NULL;
  348.  
  349.    if (screen->blitter)
  350.       nv50_blitter_destroy(screen);
  351.  
  352.    nouveau_bo_ref(NULL, &screen->code);
  353.    nouveau_bo_ref(NULL, &screen->tls_bo);
  354.    nouveau_bo_ref(NULL, &screen->stack_bo);
  355.    nouveau_bo_ref(NULL, &screen->txc);
  356.    nouveau_bo_ref(NULL, &screen->uniforms);
  357.    nouveau_bo_ref(NULL, &screen->fence.bo);
  358.  
  359.    nouveau_heap_destroy(&screen->vp_code_heap);
  360.    nouveau_heap_destroy(&screen->gp_code_heap);
  361.    nouveau_heap_destroy(&screen->fp_code_heap);
  362.  
  363.    FREE(screen->tic.entries);
  364.  
  365.    nouveau_object_del(&screen->tesla);
  366.    nouveau_object_del(&screen->eng2d);
  367.    nouveau_object_del(&screen->m2mf);
  368.    nouveau_object_del(&screen->sync);
  369.  
  370.    nouveau_screen_fini(&screen->base);
  371.  
  372.    FREE(screen);
  373. }
  374.  
  375. static void
  376. nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
  377. {
  378.    struct nv50_screen *screen = nv50_screen(pscreen);
  379.    struct nouveau_pushbuf *push = screen->base.pushbuf;
  380.  
  381.    /* we need to do it after possible flush in MARK_RING */
  382.    *sequence = ++screen->base.fence.sequence;
  383.  
  384.    PUSH_DATA (push, NV50_FIFO_PKHDR(NV50_3D(QUERY_ADDRESS_HIGH), 4));
  385.    PUSH_DATAh(push, screen->fence.bo->offset);
  386.    PUSH_DATA (push, screen->fence.bo->offset);
  387.    PUSH_DATA (push, *sequence);
  388.    PUSH_DATA (push, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 |
  389.                     NV50_3D_QUERY_GET_UNK4 |
  390.                     NV50_3D_QUERY_GET_UNIT_CROP |
  391.                     NV50_3D_QUERY_GET_TYPE_QUERY |
  392.                     NV50_3D_QUERY_GET_QUERY_SELECT_ZERO |
  393.                     NV50_3D_QUERY_GET_SHORT);
  394. }
  395.  
  396. static u32
  397. nv50_screen_fence_update(struct pipe_screen *pscreen)
  398. {
  399.    return nv50_screen(pscreen)->fence.map[0];
  400. }
  401.  
  402. static void
  403. nv50_screen_init_hwctx(struct nv50_screen *screen)
  404. {
  405.    struct nouveau_pushbuf *push = screen->base.pushbuf;
  406.    struct nv04_fifo *fifo;
  407.    unsigned i;
  408.  
  409.    fifo = (struct nv04_fifo *)screen->base.channel->data;
  410.  
  411.    BEGIN_NV04(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1);
  412.    PUSH_DATA (push, screen->m2mf->handle);
  413.    BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_DMA_NOTIFY), 3);
  414.    PUSH_DATA (push, screen->sync->handle);
  415.    PUSH_DATA (push, fifo->vram);
  416.    PUSH_DATA (push, fifo->vram);
  417.  
  418.    BEGIN_NV04(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1);
  419.    PUSH_DATA (push, screen->eng2d->handle);
  420.    BEGIN_NV04(push, NV50_2D(DMA_NOTIFY), 4);
  421.    PUSH_DATA (push, screen->sync->handle);
  422.    PUSH_DATA (push, fifo->vram);
  423.    PUSH_DATA (push, fifo->vram);
  424.    PUSH_DATA (push, fifo->vram);
  425.    BEGIN_NV04(push, NV50_2D(OPERATION), 1);
  426.    PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY);
  427.    BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1);
  428.    PUSH_DATA (push, 0);
  429.    BEGIN_NV04(push, NV50_2D(COLOR_KEY_ENABLE), 1);
  430.    PUSH_DATA (push, 0);
  431.    BEGIN_NV04(push, SUBC_2D(0x0888), 1);
  432.    PUSH_DATA (push, 1);
  433.    BEGIN_NV04(push, NV50_2D(COND_MODE), 1);
  434.    PUSH_DATA (push, NV50_2D_COND_MODE_ALWAYS);
  435.  
  436.    BEGIN_NV04(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1);
  437.    PUSH_DATA (push, screen->tesla->handle);
  438.  
  439.    BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
  440.    PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);
  441.  
  442.    BEGIN_NV04(push, NV50_3D(DMA_NOTIFY), 1);
  443.    PUSH_DATA (push, screen->sync->handle);
  444.    BEGIN_NV04(push, NV50_3D(DMA_ZETA), 11);
  445.    for (i = 0; i < 11; ++i)
  446.       PUSH_DATA(push, fifo->vram);
  447.    BEGIN_NV04(push, NV50_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN);
  448.    for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i)
  449.       PUSH_DATA(push, fifo->vram);
  450.  
  451.    BEGIN_NV04(push, NV50_3D(REG_MODE), 1);
  452.    PUSH_DATA (push, NV50_3D_REG_MODE_STRIPED);
  453.    BEGIN_NV04(push, NV50_3D(UNK1400_LANES), 1);
  454.    PUSH_DATA (push, 0xf);
  455.  
  456.    if (debug_get_bool_option("NOUVEAU_SHADER_WATCHDOG", TRUE)) {
  457.       BEGIN_NV04(push, NV50_3D(WATCHDOG_TIMER), 1);
  458.       PUSH_DATA (push, 0x18);
  459.    }
  460.  
  461.    BEGIN_NV04(push, NV50_3D(ZETA_COMP_ENABLE), 1);
  462.    PUSH_DATA(push, screen->base.device->drm_version >= 0x01000101);
  463.  
  464.    BEGIN_NV04(push, NV50_3D(RT_COMP_ENABLE(0)), 8);
  465.    for (i = 0; i < 8; ++i)
  466.       PUSH_DATA(push, screen->base.device->drm_version >= 0x01000101);
  467.  
  468.    BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
  469.    PUSH_DATA (push, 1);
  470.  
  471.    BEGIN_NV04(push, NV50_3D(CSAA_ENABLE), 1);
  472.    PUSH_DATA (push, 0);
  473.    BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1);
  474.    PUSH_DATA (push, 0);
  475.    BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);
  476.    PUSH_DATA (push, NV50_3D_MULTISAMPLE_MODE_MS1);
  477.    BEGIN_NV04(push, NV50_3D(MULTISAMPLE_CTRL), 1);
  478.    PUSH_DATA (push, 0);
  479.    BEGIN_NV04(push, NV50_3D(PRIM_RESTART_WITH_DRAW_ARRAYS), 1);
  480.    PUSH_DATA (push, 1);
  481.    BEGIN_NV04(push, NV50_3D(BLEND_SEPARATE_ALPHA), 1);
  482.    PUSH_DATA (push, 1);
  483.  
  484.    if (screen->tesla->oclass >= NVA0_3D_CLASS) {
  485.       BEGIN_NV04(push, SUBC_3D(NVA0_3D_TEX_MISC), 1);
  486.       PUSH_DATA (push, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
  487.    }
  488.  
  489.    BEGIN_NV04(push, NV50_3D(SCREEN_Y_CONTROL), 1);
  490.    PUSH_DATA (push, 0);
  491.    BEGIN_NV04(push, NV50_3D(WINDOW_OFFSET_X), 2);
  492.    PUSH_DATA (push, 0);
  493.    PUSH_DATA (push, 0);
  494.    BEGIN_NV04(push, NV50_3D(ZCULL_REGION), 1);
  495.    PUSH_DATA (push, 0x3f);
  496.  
  497.    BEGIN_NV04(push, NV50_3D(VP_ADDRESS_HIGH), 2);
  498.    PUSH_DATAh(push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2));
  499.    PUSH_DATA (push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2));
  500.  
  501.    BEGIN_NV04(push, NV50_3D(FP_ADDRESS_HIGH), 2);
  502.    PUSH_DATAh(push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2));
  503.    PUSH_DATA (push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2));
  504.  
  505.    BEGIN_NV04(push, NV50_3D(GP_ADDRESS_HIGH), 2);
  506.    PUSH_DATAh(push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2));
  507.    PUSH_DATA (push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2));
  508.  
  509.    BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3);
  510.    PUSH_DATAh(push, screen->tls_bo->offset);
  511.    PUSH_DATA (push, screen->tls_bo->offset);
  512.    PUSH_DATA (push, util_logbase2(screen->cur_tls_space / 8));
  513.  
  514.    BEGIN_NV04(push, NV50_3D(STACK_ADDRESS_HIGH), 3);
  515.    PUSH_DATAh(push, screen->stack_bo->offset);
  516.    PUSH_DATA (push, screen->stack_bo->offset);
  517.    PUSH_DATA (push, 4);
  518.  
  519.    BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
  520.    PUSH_DATAh(push, screen->uniforms->offset + (0 << 16));
  521.    PUSH_DATA (push, screen->uniforms->offset + (0 << 16));
  522.    PUSH_DATA (push, (NV50_CB_PVP << 16) | 0x0000);
  523.  
  524.    BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
  525.    PUSH_DATAh(push, screen->uniforms->offset + (1 << 16));
  526.    PUSH_DATA (push, screen->uniforms->offset + (1 << 16));
  527.    PUSH_DATA (push, (NV50_CB_PGP << 16) | 0x0000);
  528.  
  529.    BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
  530.    PUSH_DATAh(push, screen->uniforms->offset + (2 << 16));
  531.    PUSH_DATA (push, screen->uniforms->offset + (2 << 16));
  532.    PUSH_DATA (push, (NV50_CB_PFP << 16) | 0x0000);
  533.  
  534.    BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
  535.    PUSH_DATAh(push, screen->uniforms->offset + (3 << 16));
  536.    PUSH_DATA (push, screen->uniforms->offset + (3 << 16));
  537.    PUSH_DATA (push, (NV50_CB_AUX << 16) | (NV50_CB_AUX_SIZE & 0xffff));
  538.  
  539.    BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 3);
  540.    PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01);
  541.    PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21);
  542.    PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31);
  543.  
  544.    /* return { 0.0, 0.0, 0.0, 0.0 } on out-of-bounds vtxbuf access */
  545.    BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
  546.    PUSH_DATA (push, (NV50_CB_AUX_RUNOUT_OFFSET << (8 - 2)) | NV50_CB_AUX);
  547.    BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 4);
  548.    PUSH_DATAf(push, 0.0f);
  549.    PUSH_DATAf(push, 0.0f);
  550.    PUSH_DATAf(push, 0.0f);
  551.    PUSH_DATAf(push, 0.0f);
  552.    BEGIN_NV04(push, NV50_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2);
  553.    PUSH_DATAh(push, screen->uniforms->offset + (3 << 16) + NV50_CB_AUX_RUNOUT_OFFSET);
  554.    PUSH_DATA (push, screen->uniforms->offset + (3 << 16) + NV50_CB_AUX_RUNOUT_OFFSET);
  555.  
  556.    nv50_upload_ms_info(push);
  557.  
  558.    /* max TIC (bits 4:8) & TSC bindings, per program type */
  559.    for (i = 0; i < 3; ++i) {
  560.       BEGIN_NV04(push, NV50_3D(TEX_LIMITS(i)), 1);
  561.       PUSH_DATA (push, 0x54);
  562.    }
  563.  
  564.    BEGIN_NV04(push, NV50_3D(TIC_ADDRESS_HIGH), 3);
  565.    PUSH_DATAh(push, screen->txc->offset);
  566.    PUSH_DATA (push, screen->txc->offset);
  567.    PUSH_DATA (push, NV50_TIC_MAX_ENTRIES - 1);
  568.  
  569.    BEGIN_NV04(push, NV50_3D(TSC_ADDRESS_HIGH), 3);
  570.    PUSH_DATAh(push, screen->txc->offset + 65536);
  571.    PUSH_DATA (push, screen->txc->offset + 65536);
  572.    PUSH_DATA (push, NV50_TSC_MAX_ENTRIES - 1);
  573.  
  574.    BEGIN_NV04(push, NV50_3D(LINKED_TSC), 1);
  575.    PUSH_DATA (push, 0);
  576.  
  577.    BEGIN_NV04(push, NV50_3D(CLIP_RECTS_EN), 1);
  578.    PUSH_DATA (push, 0);
  579.    BEGIN_NV04(push, NV50_3D(CLIP_RECTS_MODE), 1);
  580.    PUSH_DATA (push, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY);
  581.    BEGIN_NV04(push, NV50_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
  582.    for (i = 0; i < 8 * 2; ++i)
  583.       PUSH_DATA(push, 0);
  584.    BEGIN_NV04(push, NV50_3D(CLIPID_ENABLE), 1);
  585.    PUSH_DATA (push, 0);
  586.  
  587.    BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
  588.    PUSH_DATA (push, 1);
  589.    for (i = 0; i < NV50_MAX_VIEWPORTS; i++) {
  590.       BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(i)), 2);
  591.       PUSH_DATAf(push, 0.0f);
  592.       PUSH_DATAf(push, 1.0f);
  593.       BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(i)), 2);
  594.       PUSH_DATA (push, 8192 << 16);
  595.       PUSH_DATA (push, 8192 << 16);
  596.    }
  597.  
  598.    BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1);
  599. #ifdef NV50_SCISSORS_CLIPPING
  600.    PUSH_DATA (push, 0x0000);
  601. #else
  602.    PUSH_DATA (push, 0x1080);
  603. #endif
  604.  
  605.    BEGIN_NV04(push, NV50_3D(CLEAR_FLAGS), 1);
  606.    PUSH_DATA (push, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT);
  607.  
  608.    /* We use scissors instead of exact view volume clipping,
  609.     * so they're always enabled.
  610.     */
  611.    for (i = 0; i < NV50_MAX_VIEWPORTS; i++) {
  612.       BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(i)), 3);
  613.       PUSH_DATA (push, 1);
  614.       PUSH_DATA (push, 8192 << 16);
  615.       PUSH_DATA (push, 8192 << 16);
  616.    }
  617.  
  618.    BEGIN_NV04(push, NV50_3D(RASTERIZE_ENABLE), 1);
  619.    PUSH_DATA (push, 1);
  620.    BEGIN_NV04(push, NV50_3D(POINT_RASTER_RULES), 1);
  621.    PUSH_DATA (push, NV50_3D_POINT_RASTER_RULES_OGL);
  622.    BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1);
  623.    PUSH_DATA (push, 0x11111111);
  624.    BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1);
  625.    PUSH_DATA (push, 1);
  626.  
  627.    BEGIN_NV04(push, NV50_3D(VB_ELEMENT_BASE), 1);
  628.    PUSH_DATA (push, 0);
  629.    if (screen->base.class_3d >= NV84_3D_CLASS) {
  630.       BEGIN_NV04(push, SUBC_3D(NV84_3D_VERTEX_ID_BASE), 1);
  631.       PUSH_DATA (push, 0);
  632.    }
  633.  
  634.    PUSH_KICK (push);
  635. }
  636.  
  637. static int nv50_tls_alloc(struct nv50_screen *screen, unsigned tls_space,
  638.       uint64_t *tls_size)
  639. {
  640.    struct nouveau_device *dev = screen->base.device;
  641.    int ret;
  642.  
  643.    screen->cur_tls_space = util_next_power_of_two(tls_space / ONE_TEMP_SIZE) *
  644.          ONE_TEMP_SIZE;
  645.    if (nouveau_mesa_debug)
  646.       debug_printf("allocating space for %u temps\n",
  647.             util_next_power_of_two(tls_space / ONE_TEMP_SIZE));
  648.    *tls_size = screen->cur_tls_space * util_next_power_of_two(screen->TPs) *
  649.          screen->MPsInTP * LOCAL_WARPS_ALLOC * THREADS_IN_WARP;
  650.  
  651.    ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
  652.                         *tls_size, NULL, &screen->tls_bo);
  653.    if (ret) {
  654.       NOUVEAU_ERR("Failed to allocate local bo: %d\n", ret);
  655.       return ret;
  656.    }
  657.  
  658.    return 0;
  659. }
  660.  
  661. int nv50_tls_realloc(struct nv50_screen *screen, unsigned tls_space)
  662. {
  663.    struct nouveau_pushbuf *push = screen->base.pushbuf;
  664.    int ret;
  665.    uint64_t tls_size;
  666.  
  667.    if (tls_space < screen->cur_tls_space)
  668.       return 0;
  669.    if (tls_space > screen->max_tls_space) {
  670.       /* fixable by limiting number of warps (LOCAL_WARPS_LOG_ALLOC /
  671.        * LOCAL_WARPS_NO_CLAMP) */
  672.       NOUVEAU_ERR("Unsupported number of temporaries (%u > %u). Fixable if someone cares.\n",
  673.             (unsigned)(tls_space / ONE_TEMP_SIZE),
  674.             (unsigned)(screen->max_tls_space / ONE_TEMP_SIZE));
  675.       return -ENOMEM;
  676.    }
  677.  
  678.    nouveau_bo_ref(NULL, &screen->tls_bo);
  679.    ret = nv50_tls_alloc(screen, tls_space, &tls_size);
  680.    if (ret)
  681.       return ret;
  682.  
  683.    BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3);
  684.    PUSH_DATAh(push, screen->tls_bo->offset);
  685.    PUSH_DATA (push, screen->tls_bo->offset);
  686.    PUSH_DATA (push, util_logbase2(screen->cur_tls_space / 8));
  687.  
  688.    return 1;
  689. }
  690.  
  691. struct pipe_screen *
  692. nv50_screen_create(struct nouveau_device *dev)
  693. {
  694.    struct nv50_screen *screen;
  695.    struct pipe_screen *pscreen;
  696.    struct nouveau_object *chan;
  697.    uint64_t value;
  698.    uint32_t tesla_class;
  699.    unsigned stack_size;
  700.    int ret;
  701.  
  702.    screen = CALLOC_STRUCT(nv50_screen);
  703.    if (!screen)
  704.       return NULL;
  705.    pscreen = &screen->base.base;
  706.  
  707.    ret = nouveau_screen_init(&screen->base, dev);
  708.    if (ret) {
  709.       NOUVEAU_ERR("nouveau_screen_init failed: %d\n", ret);
  710.       goto fail;
  711.    }
  712.  
  713.    /* TODO: Prevent FIFO prefetch before transfer of index buffers and
  714.     *  admit them to VRAM.
  715.     */
  716.    screen->base.vidmem_bindings |= PIPE_BIND_CONSTANT_BUFFER |
  717.       PIPE_BIND_VERTEX_BUFFER;
  718.    screen->base.sysmem_bindings |=
  719.       PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER;
  720.  
  721.    screen->base.pushbuf->user_priv = screen;
  722.    screen->base.pushbuf->rsvd_kick = 5;
  723.  
  724.    chan = screen->base.channel;
  725.  
  726.    pscreen->destroy = nv50_screen_destroy;
  727.    pscreen->context_create = nv50_create;
  728.    pscreen->is_format_supported = nv50_screen_is_format_supported;
  729.    pscreen->get_param = nv50_screen_get_param;
  730.    pscreen->get_shader_param = nv50_screen_get_shader_param;
  731.    pscreen->get_paramf = nv50_screen_get_paramf;
  732.  
  733.    nv50_screen_init_resource_functions(pscreen);
  734.  
  735.    if (screen->base.device->chipset < 0x84 ||
  736.        debug_get_bool_option("NOUVEAU_PMPEG", FALSE)) {
  737.       /* PMPEG */
  738.       nouveau_screen_init_vdec(&screen->base);
  739.    } else if (screen->base.device->chipset < 0x98 ||
  740.               screen->base.device->chipset == 0xa0) {
  741.       /* VP2 */
  742.       screen->base.base.get_video_param = nv84_screen_get_video_param;
  743.       screen->base.base.is_video_format_supported = nv84_screen_video_supported;
  744.    } else {
  745.       /* VP3/4 */
  746.       screen->base.base.get_video_param = nouveau_vp3_screen_get_video_param;
  747.       screen->base.base.is_video_format_supported = nouveau_vp3_screen_video_supported;
  748.    }
  749.  
  750.    ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096,
  751.                         NULL, &screen->fence.bo);
  752.    if (ret) {
  753.       NOUVEAU_ERR("Failed to allocate fence bo: %d\n", ret);
  754.       goto fail;
  755.    }
  756.  
  757.    nouveau_bo_map(screen->fence.bo, 0, NULL);
  758.    screen->fence.map = screen->fence.bo->map;
  759.    screen->base.fence.emit = nv50_screen_fence_emit;
  760.    screen->base.fence.update = nv50_screen_fence_update;
  761.  
  762.    ret = nouveau_object_new(chan, 0xbeef0301, NOUVEAU_NOTIFIER_CLASS,
  763.                             &(struct nv04_notify){ .length = 32 },
  764.                             sizeof(struct nv04_notify), &screen->sync);
  765.    if (ret) {
  766.       NOUVEAU_ERR("Failed to allocate notifier: %d\n", ret);
  767.       goto fail;
  768.    }
  769.  
  770.    ret = nouveau_object_new(chan, 0xbeef5039, NV50_M2MF_CLASS,
  771.                             NULL, 0, &screen->m2mf);
  772.    if (ret) {
  773.       NOUVEAU_ERR("Failed to allocate PGRAPH context for M2MF: %d\n", ret);
  774.       goto fail;
  775.    }
  776.  
  777.    ret = nouveau_object_new(chan, 0xbeef502d, NV50_2D_CLASS,
  778.                             NULL, 0, &screen->eng2d);
  779.    if (ret) {
  780.       NOUVEAU_ERR("Failed to allocate PGRAPH context for 2D: %d\n", ret);
  781.       goto fail;
  782.    }
  783.  
  784.    switch (dev->chipset & 0xf0) {
  785.    case 0x50:
  786.       tesla_class = NV50_3D_CLASS;
  787.       break;
  788.    case 0x80:
  789.    case 0x90:
  790.       tesla_class = NV84_3D_CLASS;
  791.       break;
  792.    case 0xa0:
  793.       switch (dev->chipset) {
  794.       case 0xa0:
  795.       case 0xaa:
  796.       case 0xac:
  797.          tesla_class = NVA0_3D_CLASS;
  798.          break;
  799.       case 0xaf:
  800.          tesla_class = NVAF_3D_CLASS;
  801.          break;
  802.       default:
  803.          tesla_class = NVA3_3D_CLASS;
  804.          break;
  805.       }
  806.       break;
  807.    default:
  808.       NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", dev->chipset);
  809.       goto fail;
  810.    }
  811.    screen->base.class_3d = tesla_class;
  812.  
  813.    ret = nouveau_object_new(chan, 0xbeef5097, tesla_class,
  814.                             NULL, 0, &screen->tesla);
  815.    if (ret) {
  816.       NOUVEAU_ERR("Failed to allocate PGRAPH context for 3D: %d\n", ret);
  817.       goto fail;
  818.    }
  819.  
  820.    /* This over-allocates by a page. The GP, which would execute at the end of
  821.     * the last page, would trigger faults. The going theory is that it
  822.     * prefetches up to a certain amount.
  823.     */
  824.    ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
  825.                         (3 << NV50_CODE_BO_SIZE_LOG2) + 0x1000,
  826.                         NULL, &screen->code);
  827.    if (ret) {
  828.       NOUVEAU_ERR("Failed to allocate code bo: %d\n", ret);
  829.       goto fail;
  830.    }
  831.  
  832.    nouveau_heap_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
  833.    nouveau_heap_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
  834.    nouveau_heap_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
  835.  
  836.    nouveau_getparam(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
  837.  
  838.    screen->TPs = util_bitcount(value & 0xffff);
  839.    screen->MPsInTP = util_bitcount((value >> 24) & 0xf);
  840.  
  841.    stack_size = util_next_power_of_two(screen->TPs) * screen->MPsInTP *
  842.          STACK_WARPS_ALLOC * 64 * 8;
  843.  
  844.    ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size, NULL,
  845.                         &screen->stack_bo);
  846.    if (ret) {
  847.       NOUVEAU_ERR("Failed to allocate stack bo: %d\n", ret);
  848.       goto fail;
  849.    }
  850.  
  851.    uint64_t size_of_one_temp = util_next_power_of_two(screen->TPs) *
  852.          screen->MPsInTP * LOCAL_WARPS_ALLOC *  THREADS_IN_WARP *
  853.          ONE_TEMP_SIZE;
  854.    screen->max_tls_space = dev->vram_size / size_of_one_temp * ONE_TEMP_SIZE;
  855.    screen->max_tls_space /= 2; /* half of vram */
  856.  
  857.    /* hw can address max 64 KiB */
  858.    screen->max_tls_space = MIN2(screen->max_tls_space, 64 << 10);
  859.  
  860.    uint64_t tls_size;
  861.    unsigned tls_space = 4/*temps*/ * ONE_TEMP_SIZE;
  862.    ret = nv50_tls_alloc(screen, tls_space, &tls_size);
  863.    if (ret)
  864.       goto fail;
  865.  
  866.    if (nouveau_mesa_debug)
  867.       debug_printf("TPs = %u, MPsInTP = %u, VRAM = %"PRIu64" MiB, tls_size = %"PRIu64" KiB\n",
  868.             screen->TPs, screen->MPsInTP, dev->vram_size >> 20, tls_size >> 10);
  869.  
  870.    ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16, NULL,
  871.                         &screen->uniforms);
  872.    if (ret) {
  873.       NOUVEAU_ERR("Failed to allocate uniforms bo: %d\n", ret);
  874.       goto fail;
  875.    }
  876.  
  877.    ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16, NULL,
  878.                         &screen->txc);
  879.    if (ret) {
  880.       NOUVEAU_ERR("Failed to allocate TIC/TSC bo: %d\n", ret);
  881.       goto fail;
  882.    }
  883.  
  884.    screen->tic.entries = CALLOC(4096, sizeof(void *));
  885.    screen->tsc.entries = screen->tic.entries + 2048;
  886.  
  887.    if (!nv50_blitter_create(screen))
  888.       goto fail;
  889.  
  890.    nv50_screen_init_hwctx(screen);
  891.  
  892.    nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
  893.  
  894.    return pscreen;
  895.  
  896. fail:
  897.    nv50_screen_destroy(pscreen);
  898.    return NULL;
  899. }
  900.  
  901. int
  902. nv50_screen_tic_alloc(struct nv50_screen *screen, void *entry)
  903. {
  904.    int i = screen->tic.next;
  905.  
  906.    while (screen->tic.lock[i / 32] & (1 << (i % 32)))
  907.       i = (i + 1) & (NV50_TIC_MAX_ENTRIES - 1);
  908.  
  909.    screen->tic.next = (i + 1) & (NV50_TIC_MAX_ENTRIES - 1);
  910.  
  911.    if (screen->tic.entries[i])
  912.       nv50_tic_entry(screen->tic.entries[i])->id = -1;
  913.  
  914.    screen->tic.entries[i] = entry;
  915.    return i;
  916. }
  917.  
  918. int
  919. nv50_screen_tsc_alloc(struct nv50_screen *screen, void *entry)
  920. {
  921.    int i = screen->tsc.next;
  922.  
  923.    while (screen->tsc.lock[i / 32] & (1 << (i % 32)))
  924.       i = (i + 1) & (NV50_TSC_MAX_ENTRIES - 1);
  925.  
  926.    screen->tsc.next = (i + 1) & (NV50_TSC_MAX_ENTRIES - 1);
  927.  
  928.    if (screen->tsc.entries[i])
  929.       nv50_tsc_entry(screen->tsc.entries[i])->id = -1;
  930.  
  931.    screen->tsc.entries[i] = entry;
  932.    return i;
  933. }
  934.