Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2012 Red Hat Inc.
  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.  * Authors: Ben Skeggs
  23.  *
  24.  */
  25.  
  26. #include <xf86drm.h>
  27. #include <nouveau_drm.h>
  28. #include "util/u_format.h"
  29. #include "util/u_format_s3tc.h"
  30.  
  31. #include "nv_object.xml.h"
  32. #include "nv_m2mf.xml.h"
  33. #include "nv30/nv30-40_3d.xml.h"
  34. #include "nv30/nv01_2d.xml.h"
  35.  
  36. #include "nouveau_fence.h"
  37. #include "nv30/nv30_screen.h"
  38. #include "nv30/nv30_context.h"
  39. #include "nv30/nv30_resource.h"
  40. #include "nv30/nv30_format.h"
  41.  
  42. #define RANKINE_0397_CHIPSET 0x00000003
  43. #define RANKINE_0497_CHIPSET 0x000001e0
  44. #define RANKINE_0697_CHIPSET 0x00000010
  45. #define CURIE_4097_CHIPSET   0x00000baf
  46. #define CURIE_4497_CHIPSET   0x00005450
  47. #define CURIE_4497_CHIPSET6X 0x00000088
  48.  
  49. static int
  50. nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
  51. {
  52.    struct nv30_screen *screen = nv30_screen(pscreen);
  53.    struct nouveau_object *eng3d = screen->eng3d;
  54.    struct nouveau_device *dev = nouveau_screen(pscreen)->device;
  55.  
  56.    switch (param) {
  57.    /* non-boolean capabilities */
  58.    case PIPE_CAP_MAX_RENDER_TARGETS:
  59.       return (eng3d->oclass >= NV40_3D_CLASS) ? 4 : 1;
  60.    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
  61.       return 13;
  62.    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
  63.       return 10;
  64.    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
  65.       return 13;
  66.    case PIPE_CAP_GLSL_FEATURE_LEVEL:
  67.       return 120;
  68.    case PIPE_CAP_ENDIANNESS:
  69.       return PIPE_ENDIAN_LITTLE;
  70.    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
  71.       return 16;
  72.    case PIPE_CAP_MAX_VIEWPORTS:
  73.       return 1;
  74.    case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
  75.       return 2048;
  76.    /* supported capabilities */
  77.    case PIPE_CAP_TWO_SIDED_STENCIL:
  78.    case PIPE_CAP_ANISOTROPIC_FILTER:
  79.    case PIPE_CAP_POINT_SPRITE:
  80.    case PIPE_CAP_OCCLUSION_QUERY:
  81.    case PIPE_CAP_QUERY_TIME_ELAPSED:
  82.    case PIPE_CAP_QUERY_TIMESTAMP:
  83.    case PIPE_CAP_TEXTURE_SHADOW_MAP:
  84.    case PIPE_CAP_TEXTURE_SWIZZLE:
  85.    case PIPE_CAP_DEPTH_CLIP_DISABLE:
  86.    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
  87.    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
  88.    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
  89.    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
  90.    case PIPE_CAP_TGSI_TEXCOORD:
  91.    case PIPE_CAP_USER_CONSTANT_BUFFERS:
  92.    case PIPE_CAP_USER_INDEX_BUFFERS:
  93.    case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
  94.    case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
  95.    case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
  96.    case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
  97.    case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
  98.       return 1;
  99.    /* nv4x capabilities */
  100.    case PIPE_CAP_BLEND_EQUATION_SEPARATE:
  101.    case PIPE_CAP_NPOT_TEXTURES:
  102.    case PIPE_CAP_CONDITIONAL_RENDER:
  103.    case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
  104.    case PIPE_CAP_PRIMITIVE_RESTART:
  105.       return (eng3d->oclass >= NV40_3D_CLASS) ? 1 : 0;
  106.    /* unsupported */
  107.    case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
  108.    case PIPE_CAP_SM3:
  109.    case PIPE_CAP_INDEP_BLEND_ENABLE:
  110.    case PIPE_CAP_INDEP_BLEND_FUNC:
  111.    case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
  112.    case PIPE_CAP_SHADER_STENCIL_EXPORT:
  113.    case PIPE_CAP_TGSI_INSTANCEID:
  114.    case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: /* XXX: yes? */
  115.    case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
  116.    case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
  117.    case PIPE_CAP_MIN_TEXEL_OFFSET:
  118.    case PIPE_CAP_MAX_TEXEL_OFFSET:
  119.    case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
  120.    case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
  121.    case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
  122.    case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
  123.    case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
  124.    case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
  125.    case PIPE_CAP_MAX_VERTEX_STREAMS:
  126.    case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
  127.    case PIPE_CAP_TEXTURE_BARRIER:
  128.    case PIPE_CAP_SEAMLESS_CUBE_MAP:
  129.    case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
  130.    case PIPE_CAP_CUBE_MAP_ARRAY:
  131.    case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
  132.    case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
  133.    case PIPE_CAP_VERTEX_COLOR_CLAMPED:
  134.    case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
  135.    case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
  136.    case PIPE_CAP_START_INSTANCE:
  137.    case PIPE_CAP_TEXTURE_MULTISAMPLE:
  138.    case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
  139.    case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
  140.    case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
  141.    case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
  142.    case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
  143.    case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
  144.    case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
  145.    case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
  146.    case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
  147.    case PIPE_CAP_TEXTURE_GATHER_SM5:
  148.    case PIPE_CAP_FAKE_SW_MSAA:
  149.    case PIPE_CAP_TEXTURE_QUERY_LOD:
  150.    case PIPE_CAP_SAMPLE_SHADING:
  151.    case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
  152.    case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
  153.    case PIPE_CAP_USER_VERTEX_BUFFERS:
  154.    case PIPE_CAP_COMPUTE:
  155.    case PIPE_CAP_DRAW_INDIRECT:
  156.    case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
  157.    case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
  158.    case PIPE_CAP_SAMPLER_VIEW_TARGET:
  159.    case PIPE_CAP_CLIP_HALFZ:
  160.    case PIPE_CAP_VERTEXID_NOBASE:
  161.    case PIPE_CAP_POLYGON_OFFSET_CLAMP:
  162.    case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
  163.    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
  164.    case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
  165.       return 0;
  166.  
  167.    case PIPE_CAP_VENDOR_ID:
  168.       return 0x10de;
  169.    case PIPE_CAP_DEVICE_ID: {
  170.       uint64_t device_id;
  171.       if (nouveau_getparam(dev, NOUVEAU_GETPARAM_PCI_DEVICE, &device_id)) {
  172.          NOUVEAU_ERR("NOUVEAU_GETPARAM_PCI_DEVICE failed.\n");
  173.          return -1;
  174.       }
  175.       return device_id;
  176.    }
  177.    case PIPE_CAP_ACCELERATED:
  178.       return 1;
  179.    case PIPE_CAP_VIDEO_MEMORY:
  180.       return dev->vram_size >> 20;
  181.    case PIPE_CAP_UMA:
  182.       return 0;
  183.    }
  184.  
  185.    debug_printf("unknown param %d\n", param);
  186.    return 0;
  187. }
  188.  
  189. static float
  190. nv30_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
  191. {
  192.    struct nv30_screen *screen = nv30_screen(pscreen);
  193.    struct nouveau_object *eng3d = screen->eng3d;
  194.  
  195.    switch (param) {
  196.    case PIPE_CAPF_MAX_LINE_WIDTH:
  197.    case PIPE_CAPF_MAX_LINE_WIDTH_AA:
  198.       return 10.0;
  199.    case PIPE_CAPF_MAX_POINT_WIDTH:
  200.    case PIPE_CAPF_MAX_POINT_WIDTH_AA:
  201.       return 64.0;
  202.    case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
  203.       return (eng3d->oclass >= NV40_3D_CLASS) ? 16.0 : 8.0;
  204.    case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
  205.       return 15.0;
  206.    default:
  207.       debug_printf("unknown paramf %d\n", param);
  208.       return 0;
  209.    }
  210. }
  211.  
  212. static int
  213. nv30_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
  214.                              enum pipe_shader_cap param)
  215. {
  216.    struct nv30_screen *screen = nv30_screen(pscreen);
  217.    struct nouveau_object *eng3d = screen->eng3d;
  218.  
  219.    switch (shader) {
  220.    case PIPE_SHADER_VERTEX:
  221.       switch (param) {
  222.       case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
  223.       case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
  224.          return (eng3d->oclass >= NV40_3D_CLASS) ? 512 : 256;
  225.       case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
  226.       case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
  227.          return (eng3d->oclass >= NV40_3D_CLASS) ? 512 : 0;
  228.       case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
  229.          return 0;
  230.       case PIPE_SHADER_CAP_MAX_INPUTS:
  231.       case PIPE_SHADER_CAP_MAX_OUTPUTS:
  232.          return 16;
  233.       case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
  234.          return ((eng3d->oclass >= NV40_3D_CLASS) ? (468 - 6): (256 - 6)) * sizeof(float[4]);
  235.       case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
  236.          return 1;
  237.       case PIPE_SHADER_CAP_MAX_TEMPS:
  238.          return (eng3d->oclass >= NV40_3D_CLASS) ? 32 : 13;
  239.       case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
  240.       case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
  241.          return 0;
  242.       case PIPE_SHADER_CAP_MAX_PREDS:
  243.       case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
  244.       case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
  245.       case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
  246.       case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
  247.       case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
  248.       case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
  249.       case PIPE_SHADER_CAP_SUBROUTINES:
  250.       case PIPE_SHADER_CAP_INTEGERS:
  251.       case PIPE_SHADER_CAP_DOUBLES:
  252.       case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
  253.       case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
  254.       case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
  255.          return 0;
  256.       default:
  257.          debug_printf("unknown vertex shader param %d\n", param);
  258.          return 0;
  259.       }
  260.       break;
  261.    case PIPE_SHADER_FRAGMENT:
  262.       switch (param) {
  263.       case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
  264.       case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
  265.       case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
  266.       case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
  267.          return 4096;
  268.       case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
  269.          return 0;
  270.       case PIPE_SHADER_CAP_MAX_INPUTS:
  271.          return 8; /* should be possible to do 10 with nv4x */
  272.       case PIPE_SHADER_CAP_MAX_OUTPUTS:
  273.          return 4;
  274.       case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
  275.          return ((eng3d->oclass >= NV40_3D_CLASS) ? 224 : 32) * sizeof(float[4]);
  276.       case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
  277.          return 1;
  278.       case PIPE_SHADER_CAP_MAX_TEMPS:
  279.          return 32;
  280.       case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
  281.       case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
  282.          return 16;
  283.       case PIPE_SHADER_CAP_MAX_PREDS:
  284.       case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
  285.       case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
  286.       case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
  287.       case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
  288.       case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
  289.       case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
  290.       case PIPE_SHADER_CAP_SUBROUTINES:
  291.       case PIPE_SHADER_CAP_DOUBLES:
  292.       case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
  293.       case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
  294.       case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
  295.          return 0;
  296.       default:
  297.          debug_printf("unknown fragment shader param %d\n", param);
  298.          return 0;
  299.       }
  300.       break;
  301.    default:
  302.       return 0;
  303.    }
  304. }
  305.  
  306. static boolean
  307. nv30_screen_is_format_supported(struct pipe_screen *pscreen,
  308.                                 enum pipe_format format,
  309.                                 enum pipe_texture_target target,
  310.                                 unsigned sample_count,
  311.                                 unsigned bindings)
  312. {
  313.    if (sample_count > 4)
  314.       return FALSE;
  315.    if (!(0x00000017 & (1 << sample_count)))
  316.       return FALSE;
  317.  
  318.    if (!util_format_is_supported(format, bindings)) {
  319.       return FALSE;
  320.    }
  321.  
  322.    /* transfers & shared are always supported */
  323.    bindings &= ~(PIPE_BIND_TRANSFER_READ |
  324.                  PIPE_BIND_TRANSFER_WRITE |
  325.                  PIPE_BIND_SHARED);
  326.  
  327.    return (nv30_format_info(pscreen, format)->bindings & bindings) == bindings;
  328. }
  329.  
  330. static void
  331. nv30_screen_fence_emit(struct pipe_screen *pscreen, uint32_t *sequence)
  332. {
  333.    struct nv30_screen *screen = nv30_screen(pscreen);
  334.    struct nouveau_pushbuf *push = screen->base.pushbuf;
  335.  
  336.    *sequence = ++screen->base.fence.sequence;
  337.  
  338.    BEGIN_NV04(push, NV30_3D(FENCE_OFFSET), 2);
  339.    PUSH_DATA (push, 0);
  340.    PUSH_DATA (push, *sequence);
  341. }
  342.  
  343. static uint32_t
  344. nv30_screen_fence_update(struct pipe_screen *pscreen)
  345. {
  346.    struct nv30_screen *screen = nv30_screen(pscreen);
  347.    struct nv04_notify *fence = screen->fence->data;
  348.    return *(uint32_t *)((char *)screen->notify->map + fence->offset);
  349. }
  350.  
  351. static void
  352. nv30_screen_destroy(struct pipe_screen *pscreen)
  353. {
  354.    struct nv30_screen *screen = nv30_screen(pscreen);
  355.  
  356.    if (!nouveau_drm_screen_unref(&screen->base))
  357.       return;
  358.  
  359.    if (screen->base.fence.current) {
  360.       struct nouveau_fence *current = NULL;
  361.  
  362.       /* nouveau_fence_wait will create a new current fence, so wait on the
  363.        * _current_ one, and remove both.
  364.        */
  365.       nouveau_fence_ref(screen->base.fence.current, &current);
  366.       nouveau_fence_wait(current);
  367.       nouveau_fence_ref(NULL, &current);
  368.       nouveau_fence_ref(NULL, &screen->base.fence.current);
  369.    }
  370.  
  371.    nouveau_bo_ref(NULL, &screen->notify);
  372.  
  373.    nouveau_heap_destroy(&screen->query_heap);
  374.    nouveau_heap_destroy(&screen->vp_exec_heap);
  375.    nouveau_heap_destroy(&screen->vp_data_heap);
  376.  
  377.    nouveau_object_del(&screen->query);
  378.    nouveau_object_del(&screen->fence);
  379.    nouveau_object_del(&screen->ntfy);
  380.  
  381.    nouveau_object_del(&screen->sifm);
  382.    nouveau_object_del(&screen->swzsurf);
  383.    nouveau_object_del(&screen->surf2d);
  384.    nouveau_object_del(&screen->m2mf);
  385.    nouveau_object_del(&screen->eng3d);
  386.    nouveau_object_del(&screen->null);
  387.  
  388.    nouveau_screen_fini(&screen->base);
  389.    FREE(screen);
  390. }
  391.  
  392. #define FAIL_SCREEN_INIT(str, err)                    \
  393.    do {                                               \
  394.       NOUVEAU_ERR(str, err);                          \
  395.       nv30_screen_destroy(pscreen);                   \
  396.       return NULL;                                    \
  397.    } while(0)
  398.  
  399. struct pipe_screen *
  400. nv30_screen_create(struct nouveau_device *dev)
  401. {
  402.    struct nv30_screen *screen = CALLOC_STRUCT(nv30_screen);
  403.    struct pipe_screen *pscreen;
  404.    struct nouveau_pushbuf *push;
  405.    struct nv04_fifo *fifo;
  406.    unsigned oclass = 0;
  407.    int ret, i;
  408.  
  409.    if (!screen)
  410.       return NULL;
  411.  
  412.    switch (dev->chipset & 0xf0) {
  413.    case 0x30:
  414.       if (RANKINE_0397_CHIPSET & (1 << (dev->chipset & 0x0f)))
  415.          oclass = NV30_3D_CLASS;
  416.       else
  417.       if (RANKINE_0697_CHIPSET & (1 << (dev->chipset & 0x0f)))
  418.          oclass = NV34_3D_CLASS;
  419.       else
  420.       if (RANKINE_0497_CHIPSET & (1 << (dev->chipset & 0x0f)))
  421.          oclass = NV35_3D_CLASS;
  422.       break;
  423.    case 0x40:
  424.       if (CURIE_4097_CHIPSET & (1 << (dev->chipset & 0x0f)))
  425.          oclass = NV40_3D_CLASS;
  426.       else
  427.       if (CURIE_4497_CHIPSET & (1 << (dev->chipset & 0x0f)))
  428.          oclass = NV44_3D_CLASS;
  429.       break;
  430.    case 0x60:
  431.       if (CURIE_4497_CHIPSET6X & (1 << (dev->chipset & 0x0f)))
  432.          oclass = NV44_3D_CLASS;
  433.       break;
  434.    default:
  435.       break;
  436.    }
  437.  
  438.    if (!oclass) {
  439.       NOUVEAU_ERR("unknown 3d class for 0x%02x\n", dev->chipset);
  440.       FREE(screen);
  441.       return NULL;
  442.    }
  443.  
  444.    pscreen = &screen->base.base;
  445.    pscreen->destroy = nv30_screen_destroy;
  446.    pscreen->get_param = nv30_screen_get_param;
  447.    pscreen->get_paramf = nv30_screen_get_paramf;
  448.    pscreen->get_shader_param = nv30_screen_get_shader_param;
  449.    pscreen->context_create = nv30_context_create;
  450.    pscreen->is_format_supported = nv30_screen_is_format_supported;
  451.    nv30_resource_screen_init(pscreen);
  452.    nouveau_screen_init_vdec(&screen->base);
  453.  
  454.    screen->base.fence.emit = nv30_screen_fence_emit;
  455.    screen->base.fence.update = nv30_screen_fence_update;
  456.  
  457.    ret = nouveau_screen_init(&screen->base, dev);
  458.    if (ret)
  459.       FAIL_SCREEN_INIT("nv30_screen_init failed: %d\n", ret);
  460.  
  461.    screen->base.vidmem_bindings |= PIPE_BIND_VERTEX_BUFFER;
  462.    screen->base.sysmem_bindings |= PIPE_BIND_VERTEX_BUFFER;
  463.    if (oclass == NV40_3D_CLASS) {
  464.       screen->base.vidmem_bindings |= PIPE_BIND_INDEX_BUFFER;
  465.       screen->base.sysmem_bindings |= PIPE_BIND_INDEX_BUFFER;
  466.    }
  467.  
  468.    fifo = screen->base.channel->data;
  469.    push = screen->base.pushbuf;
  470.    push->rsvd_kick = 16;
  471.  
  472.    ret = nouveau_object_new(screen->base.channel, 0x00000000, NV01_NULL_CLASS,
  473.                             NULL, 0, &screen->null);
  474.    if (ret)
  475.       FAIL_SCREEN_INIT("error allocating null object: %d\n", ret);
  476.  
  477.    /* DMA_FENCE refuses to accept DMA objects with "adjust" filled in,
  478.     * this means that the address pointed at by the DMA object must
  479.     * be 4KiB aligned, which means this object needs to be the first
  480.     * one allocated on the channel.
  481.     */
  482.    ret = nouveau_object_new(screen->base.channel, 0xbeef1e00,
  483.                             NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {
  484.                             .length = 32 }, sizeof(struct nv04_notify),
  485.                             &screen->fence);
  486.    if (ret)
  487.       FAIL_SCREEN_INIT("error allocating fence notifier: %d\n", ret);
  488.  
  489.    /* DMA_NOTIFY object, we don't actually use this but M2MF fails without */
  490.    ret = nouveau_object_new(screen->base.channel, 0xbeef0301,
  491.                             NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {
  492.                             .length = 32 }, sizeof(struct nv04_notify),
  493.                             &screen->ntfy);
  494.    if (ret)
  495.       FAIL_SCREEN_INIT("error allocating sync notifier: %d\n", ret);
  496.  
  497.    /* DMA_QUERY, used to implement occlusion queries, we attempt to allocate
  498.     * the remainder of the "notifier block" assigned by the kernel for
  499.     * use as query objects
  500.     */
  501.    ret = nouveau_object_new(screen->base.channel, 0xbeef0351,
  502.                             NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {
  503.                             .length = 4096 - 128 }, sizeof(struct nv04_notify),
  504.                             &screen->query);
  505.    if (ret)
  506.       FAIL_SCREEN_INIT("error allocating query notifier: %d\n", ret);
  507.  
  508.    ret = nouveau_heap_init(&screen->query_heap, 0, 4096 - 128);
  509.    if (ret)
  510.       FAIL_SCREEN_INIT("error creating query heap: %d\n", ret);
  511.  
  512.    LIST_INITHEAD(&screen->queries);
  513.  
  514.    /* Vertex program resources (code/data), currently 6 of the constant
  515.     * slots are reserved to implement user clipping planes
  516.     */
  517.    if (oclass < NV40_3D_CLASS) {
  518.       nouveau_heap_init(&screen->vp_exec_heap, 0, 256);
  519.       nouveau_heap_init(&screen->vp_data_heap, 6, 256 - 6);
  520.    } else {
  521.       nouveau_heap_init(&screen->vp_exec_heap, 0, 512);
  522.       nouveau_heap_init(&screen->vp_data_heap, 6, 468 - 6);
  523.    }
  524.  
  525.    ret = nouveau_bo_wrap(screen->base.device, fifo->notify, &screen->notify);
  526.    if (ret == 0)
  527.       nouveau_bo_map(screen->notify, 0, screen->base.client);
  528.    if (ret)
  529.       FAIL_SCREEN_INIT("error mapping notifier memory: %d\n", ret);
  530.  
  531.    ret = nouveau_object_new(screen->base.channel, 0xbeef3097, oclass,
  532.                             NULL, 0, &screen->eng3d);
  533.    if (ret)
  534.       FAIL_SCREEN_INIT("error allocating 3d object: %d\n", ret);
  535.  
  536.    BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
  537.    PUSH_DATA (push, screen->eng3d->handle);
  538.    BEGIN_NV04(push, NV30_3D(DMA_NOTIFY), 13);
  539.    PUSH_DATA (push, screen->ntfy->handle);
  540.    PUSH_DATA (push, fifo->vram);     /* TEXTURE0 */
  541.    PUSH_DATA (push, fifo->gart);     /* TEXTURE1 */
  542.    PUSH_DATA (push, fifo->vram);     /* COLOR1 */
  543.    PUSH_DATA (push, screen->null->handle);  /* UNK190 */
  544.    PUSH_DATA (push, fifo->vram);     /* COLOR0 */
  545.    PUSH_DATA (push, fifo->vram);     /* ZETA */
  546.    PUSH_DATA (push, fifo->vram);     /* VTXBUF0 */
  547.    PUSH_DATA (push, fifo->gart);     /* VTXBUF1 */
  548.    PUSH_DATA (push, screen->fence->handle);  /* FENCE */
  549.    PUSH_DATA (push, screen->query->handle);  /* QUERY - intr 0x80 if nullobj */
  550.    PUSH_DATA (push, screen->null->handle);  /* UNK1AC */
  551.    PUSH_DATA (push, screen->null->handle);  /* UNK1B0 */
  552.    if (screen->eng3d->oclass < NV40_3D_CLASS) {
  553.       BEGIN_NV04(push, SUBC_3D(0x03b0), 1);
  554.       PUSH_DATA (push, 0x00100000);
  555.       BEGIN_NV04(push, SUBC_3D(0x1d80), 1);
  556.       PUSH_DATA (push, 3);
  557.  
  558.       BEGIN_NV04(push, SUBC_3D(0x1e98), 1);
  559.       PUSH_DATA (push, 0);
  560.       BEGIN_NV04(push, SUBC_3D(0x17e0), 3);
  561.       PUSH_DATA (push, fui(0.0));
  562.       PUSH_DATA (push, fui(0.0));
  563.       PUSH_DATA (push, fui(1.0));
  564.       BEGIN_NV04(push, SUBC_3D(0x1f80), 16);
  565.       for (i = 0; i < 16; i++)
  566.          PUSH_DATA (push, (i == 8) ? 0x0000ffff : 0);
  567.  
  568.       BEGIN_NV04(push, NV30_3D(RC_ENABLE), 1);
  569.       PUSH_DATA (push, 0);
  570.    } else {
  571.       BEGIN_NV04(push, NV40_3D(DMA_COLOR2), 2);
  572.       PUSH_DATA (push, fifo->vram);
  573.       PUSH_DATA (push, fifo->vram);  /* COLOR3 */
  574.  
  575.       BEGIN_NV04(push, SUBC_3D(0x1450), 1);
  576.       PUSH_DATA (push, 0x00000004);
  577.  
  578.       BEGIN_NV04(push, SUBC_3D(0x1ea4), 3); /* ZCULL */
  579.       PUSH_DATA (push, 0x00000010);
  580.       PUSH_DATA (push, 0x01000100);
  581.       PUSH_DATA (push, 0xff800006);
  582.  
  583.       /* vtxprog output routing */
  584.       BEGIN_NV04(push, SUBC_3D(0x1fc4), 1);
  585.       PUSH_DATA (push, 0x06144321);
  586.       BEGIN_NV04(push, SUBC_3D(0x1fc8), 2);
  587.       PUSH_DATA (push, 0xedcba987);
  588.       PUSH_DATA (push, 0x0000006f);
  589.       BEGIN_NV04(push, SUBC_3D(0x1fd0), 1);
  590.       PUSH_DATA (push, 0x00171615);
  591.       BEGIN_NV04(push, SUBC_3D(0x1fd4), 1);
  592.       PUSH_DATA (push, 0x001b1a19);
  593.  
  594.       BEGIN_NV04(push, SUBC_3D(0x1ef8), 1);
  595.       PUSH_DATA (push, 0x0020ffff);
  596.       BEGIN_NV04(push, SUBC_3D(0x1d64), 1);
  597.       PUSH_DATA (push, 0x01d300d4);
  598.  
  599.       BEGIN_NV04(push, NV40_3D(MIPMAP_ROUNDING), 1);
  600.       PUSH_DATA (push, NV40_3D_MIPMAP_ROUNDING_MODE_DOWN);
  601.    }
  602.  
  603.    ret = nouveau_object_new(screen->base.channel, 0xbeef3901, NV03_M2MF_CLASS,
  604.                             NULL, 0, &screen->m2mf);
  605.    if (ret)
  606.       FAIL_SCREEN_INIT("error allocating m2mf object: %d\n", ret);
  607.  
  608.    BEGIN_NV04(push, NV01_SUBC(M2MF, OBJECT), 1);
  609.    PUSH_DATA (push, screen->m2mf->handle);
  610.    BEGIN_NV04(push, NV03_M2MF(DMA_NOTIFY), 1);
  611.    PUSH_DATA (push, screen->ntfy->handle);
  612.  
  613.    ret = nouveau_object_new(screen->base.channel, 0xbeef6201,
  614.                             NV10_SURFACE_2D_CLASS, NULL, 0, &screen->surf2d);
  615.    if (ret)
  616.       FAIL_SCREEN_INIT("error allocating surf2d object: %d\n", ret);
  617.  
  618.    BEGIN_NV04(push, NV01_SUBC(SF2D, OBJECT), 1);
  619.    PUSH_DATA (push, screen->surf2d->handle);
  620.    BEGIN_NV04(push, NV04_SF2D(DMA_NOTIFY), 1);
  621.    PUSH_DATA (push, screen->ntfy->handle);
  622.  
  623.    if (dev->chipset < 0x40)
  624.       oclass = NV30_SURFACE_SWZ_CLASS;
  625.    else
  626.       oclass = NV40_SURFACE_SWZ_CLASS;
  627.  
  628.    ret = nouveau_object_new(screen->base.channel, 0xbeef5201, oclass,
  629.                             NULL, 0, &screen->swzsurf);
  630.    if (ret)
  631.       FAIL_SCREEN_INIT("error allocating swizzled surface object: %d\n", ret);
  632.  
  633.    BEGIN_NV04(push, NV01_SUBC(SSWZ, OBJECT), 1);
  634.    PUSH_DATA (push, screen->swzsurf->handle);
  635.    BEGIN_NV04(push, NV04_SSWZ(DMA_NOTIFY), 1);
  636.    PUSH_DATA (push, screen->ntfy->handle);
  637.  
  638.    if (dev->chipset < 0x40)
  639.       oclass = NV30_SIFM_CLASS;
  640.    else
  641.       oclass = NV40_SIFM_CLASS;
  642.  
  643.    ret = nouveau_object_new(screen->base.channel, 0xbeef7701, oclass,
  644.                             NULL, 0, &screen->sifm);
  645.    if (ret)
  646.       FAIL_SCREEN_INIT("error allocating scaled image object: %d\n", ret);
  647.  
  648.    BEGIN_NV04(push, NV01_SUBC(SIFM, OBJECT), 1);
  649.    PUSH_DATA (push, screen->sifm->handle);
  650.    BEGIN_NV04(push, NV03_SIFM(DMA_NOTIFY), 1);
  651.    PUSH_DATA (push, screen->ntfy->handle);
  652.    BEGIN_NV04(push, NV05_SIFM(COLOR_CONVERSION), 1);
  653.    PUSH_DATA (push, NV05_SIFM_COLOR_CONVERSION_TRUNCATE);
  654.  
  655.    nouveau_pushbuf_kick(push, push->channel);
  656.  
  657.    nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
  658.    return pscreen;
  659. }
  660.