Subversion Repositories Kolibri OS

Rev

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