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 "util/u_format.h"
  27. #include "util/u_helpers.h"
  28. #include "util/u_inlines.h"
  29.  
  30. #include "nouveau_gldefs.h"
  31. #include "nv_object.xml.h"
  32. #include "nv30/nv30-40_3d.xml.h"
  33. #include "nv30/nv30_context.h"
  34. #include "nv30/nv30_winsys.h"
  35.  
  36. #define NV40_3D_MRT_BLEND_ENABLE 0x0000036c
  37.  
  38. static void *
  39. nv30_blend_state_create(struct pipe_context *pipe,
  40.                         const struct pipe_blend_state *cso)
  41. {
  42.    struct nouveau_object *eng3d = nv30_context(pipe)->screen->eng3d;
  43.    struct nv30_blend_stateobj *so;
  44.    uint32_t blend[2], cmask[2];
  45.    int i;
  46.  
  47.    so = CALLOC_STRUCT(nv30_blend_stateobj);
  48.    if (!so)
  49.       return NULL;
  50.    so->pipe = *cso;
  51.  
  52.    if (cso->logicop_enable) {
  53.       SB_MTHD30(so, COLOR_LOGIC_OP_ENABLE, 2);
  54.       SB_DATA  (so, 1);
  55.       SB_DATA  (so, nvgl_logicop_func(cso->logicop_func));
  56.    } else {
  57.       SB_MTHD30(so, COLOR_LOGIC_OP_ENABLE, 1);
  58.       SB_DATA  (so, 0);
  59.    }
  60.  
  61.    SB_MTHD30(so, DITHER_ENABLE, 1);
  62.    SB_DATA  (so, cso->dither);
  63.  
  64.    blend[0] = cso->rt[0].blend_enable;
  65.    cmask[0] = !!(cso->rt[0].colormask & PIPE_MASK_A) << 24 |
  66.               !!(cso->rt[0].colormask & PIPE_MASK_R) << 16 |
  67.               !!(cso->rt[0].colormask & PIPE_MASK_G) <<  8 |
  68.               !!(cso->rt[0].colormask & PIPE_MASK_B);
  69.    if (cso->independent_blend_enable) {
  70.       blend[1] = 0;
  71.       cmask[1] = 0;
  72.       for (i = 1; i < 4; i++) {
  73.          blend[1] |= cso->rt[i].blend_enable << i;
  74.          cmask[1] |= !!(cso->rt[i].colormask & PIPE_MASK_A) << (0 + (i * 4)) |
  75.                      !!(cso->rt[i].colormask & PIPE_MASK_R) << (1 + (i * 4)) |
  76.                      !!(cso->rt[i].colormask & PIPE_MASK_G) << (2 + (i * 4)) |
  77.                      !!(cso->rt[i].colormask & PIPE_MASK_B) << (3 + (i * 4));
  78.       }
  79.    } else {
  80.       blend[1]  = 0x0000000e *   (blend[0] & 0x00000001);
  81.       cmask[1]  = 0x00001110 * !!(cmask[0] & 0x01000000);
  82.       cmask[1] |= 0x00002220 * !!(cmask[0] & 0x00010000);
  83.       cmask[1] |= 0x00004440 * !!(cmask[0] & 0x00000100);
  84.       cmask[1] |= 0x00008880 * !!(cmask[0] & 0x00000001);
  85.    }
  86.  
  87.    if (eng3d->oclass >= NV40_3D_CLASS) {
  88.       SB_MTHD40(so, MRT_BLEND_ENABLE, 2);
  89.       SB_DATA  (so, blend[1]);
  90.       SB_DATA  (so, cmask[1]);
  91.    }
  92.  
  93.    if (blend[0] || blend[1]) {
  94.       SB_MTHD30(so, BLEND_FUNC_ENABLE, 3);
  95.       SB_DATA  (so, blend[0]);
  96.       SB_DATA  (so, (nvgl_blend_func(cso->rt[0].alpha_src_factor) << 16) |
  97.                      nvgl_blend_func(cso->rt[0].rgb_src_factor));
  98.       SB_DATA  (so, (nvgl_blend_func(cso->rt[0].alpha_dst_factor) << 16) |
  99.                      nvgl_blend_func(cso->rt[0].rgb_dst_factor));
  100.       if (eng3d->oclass < NV40_3D_CLASS) {
  101.          SB_MTHD30(so, BLEND_EQUATION, 1);
  102.          SB_DATA  (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
  103.       } else {
  104.          SB_MTHD40(so, BLEND_EQUATION, 1);
  105.          SB_DATA  (so, (nvgl_blend_eqn(cso->rt[0].alpha_func) << 16) |
  106.                         nvgl_blend_eqn(cso->rt[0].rgb_func));
  107.       }
  108.    } else {
  109.       SB_MTHD30(so, BLEND_FUNC_ENABLE, 1);
  110.       SB_DATA  (so, blend[0]);
  111.    }
  112.  
  113.    SB_MTHD30(so, COLOR_MASK, 1);
  114.    SB_DATA  (so, cmask[0]);
  115.    return so;
  116. }
  117.  
  118. static void
  119. nv30_blend_state_bind(struct pipe_context *pipe, void *hwcso)
  120. {
  121.    struct nv30_context *nv30 = nv30_context(pipe);
  122.  
  123.    nv30->blend = hwcso;
  124.    nv30->dirty |= NV30_NEW_BLEND;
  125. }
  126.  
  127. static void
  128. nv30_blend_state_delete(struct pipe_context *pipe, void *hwcso)
  129. {
  130.    FREE(hwcso);
  131. }
  132.  
  133. static void *
  134. nv30_rasterizer_state_create(struct pipe_context *pipe,
  135.                              const struct pipe_rasterizer_state *cso)
  136. {
  137.    struct nv30_rasterizer_stateobj *so;
  138.  
  139.    so = CALLOC_STRUCT(nv30_rasterizer_stateobj);
  140.    if (!so)
  141.       return NULL;
  142.    so->pipe = *cso;
  143.  
  144.    SB_MTHD30(so, SHADE_MODEL, 1);
  145.    SB_DATA  (so, cso->flatshade ? NV30_3D_SHADE_MODEL_FLAT :
  146.                                   NV30_3D_SHADE_MODEL_SMOOTH);
  147.  
  148.    SB_MTHD30(so, POLYGON_MODE_FRONT, 6);
  149.    SB_DATA  (so, nvgl_polygon_mode(cso->fill_front));
  150.    SB_DATA  (so, nvgl_polygon_mode(cso->fill_back));
  151.    if (cso->cull_face == PIPE_FACE_FRONT_AND_BACK)
  152.       SB_DATA  (so, NV30_3D_CULL_FACE_FRONT_AND_BACK);
  153.    else
  154.    if (cso->cull_face == PIPE_FACE_FRONT)
  155.       SB_DATA  (so, NV30_3D_CULL_FACE_FRONT);
  156.    else
  157.       SB_DATA  (so, NV30_3D_CULL_FACE_BACK);
  158.    SB_DATA  (so, cso->front_ccw ? NV30_3D_FRONT_FACE_CCW :
  159.                                   NV30_3D_FRONT_FACE_CW);
  160.    SB_DATA  (so, cso->poly_smooth);
  161.    SB_DATA  (so, cso->cull_face != PIPE_FACE_NONE);
  162.  
  163.    SB_MTHD30(so, POLYGON_OFFSET_POINT_ENABLE, 3);
  164.    SB_DATA  (so, cso->offset_point);
  165.    SB_DATA  (so, cso->offset_line);
  166.    SB_DATA  (so, cso->offset_tri);
  167.    if (cso->offset_point || cso->offset_line || cso->offset_tri) {
  168.       SB_MTHD30(so, POLYGON_OFFSET_FACTOR, 2);
  169.       SB_DATA  (so, fui(cso->offset_scale));
  170.       SB_DATA  (so, fui(cso->offset_units * 2.0));
  171.    }
  172.  
  173.    SB_MTHD30(so, LINE_WIDTH, 2);
  174.    SB_DATA  (so, (unsigned char)(cso->line_width * 8.0) & 0xff);
  175.    SB_DATA  (so, cso->line_smooth);
  176.    SB_MTHD30(so, LINE_STIPPLE_ENABLE, 2);
  177.    SB_DATA  (so, cso->line_stipple_enable);
  178.    SB_DATA  (so, (cso->line_stipple_pattern << 16) |
  179.                   cso->line_stipple_factor);
  180.  
  181.    SB_MTHD30(so, VERTEX_TWO_SIDE_ENABLE, 1);
  182.    SB_DATA  (so, cso->light_twoside);
  183.    SB_MTHD30(so, POLYGON_STIPPLE_ENABLE, 1);
  184.    SB_DATA  (so, cso->poly_stipple_enable);
  185.    SB_MTHD30(so, POINT_SIZE, 1);
  186.    SB_DATA  (so, fui(cso->point_size));
  187.    SB_MTHD30(so, FLATSHADE_FIRST, 1);
  188.    SB_DATA  (so, cso->flatshade_first);
  189.  
  190.    SB_MTHD30(so, DEPTH_CONTROL, 1);
  191.    SB_DATA  (so, cso->depth_clip ? 0x00000001 : 0x00000010);
  192.    return so;
  193. }
  194.  
  195. static void
  196. nv30_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
  197. {
  198.    struct nv30_context *nv30 = nv30_context(pipe);
  199.  
  200.    nv30->rast = hwcso;
  201.    nv30->dirty |= NV30_NEW_RASTERIZER;
  202. }
  203.  
  204. static void
  205. nv30_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
  206. {
  207.    FREE(hwcso);
  208. }
  209.  
  210. static void *
  211. nv30_zsa_state_create(struct pipe_context *pipe,
  212.                       const struct pipe_depth_stencil_alpha_state *cso)
  213. {
  214.    struct nv30_zsa_stateobj *so;
  215.  
  216.    so = CALLOC_STRUCT(nv30_zsa_stateobj);
  217.    if (!so)
  218.       return NULL;
  219.    so->pipe = *cso;
  220.  
  221.    SB_MTHD30(so, DEPTH_FUNC, 3);
  222.    SB_DATA  (so, nvgl_comparison_op(cso->depth.func));
  223.    SB_DATA  (so, cso->depth.writemask);
  224.    SB_DATA  (so, cso->depth.enabled);
  225.  
  226.    if (cso->stencil[0].enabled) {
  227.       SB_MTHD30(so, STENCIL_ENABLE(0), 3);
  228.       SB_DATA  (so, 1);
  229.       SB_DATA  (so, cso->stencil[0].writemask);
  230.       SB_DATA  (so, nvgl_comparison_op(cso->stencil[0].func));
  231.       SB_MTHD30(so, STENCIL_FUNC_MASK(0), 4);
  232.       SB_DATA  (so, cso->stencil[0].valuemask);
  233.       SB_DATA  (so, nvgl_stencil_op(cso->stencil[0].fail_op));
  234.       SB_DATA  (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
  235.       SB_DATA  (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
  236.    } else {
  237.       SB_MTHD30(so, STENCIL_ENABLE(0), 2);
  238.       SB_DATA  (so, 0);
  239.       SB_DATA  (so, 0x000000ff);
  240.    }
  241.  
  242.    if (cso->stencil[1].enabled) {
  243.       SB_MTHD30(so, STENCIL_ENABLE(1), 3);
  244.       SB_DATA  (so, 1);
  245.       SB_DATA  (so, cso->stencil[1].writemask);
  246.       SB_DATA  (so, nvgl_comparison_op(cso->stencil[1].func));
  247.       SB_MTHD30(so, STENCIL_FUNC_MASK(1), 4);
  248.       SB_DATA  (so, cso->stencil[1].valuemask);
  249.       SB_DATA  (so, nvgl_stencil_op(cso->stencil[1].fail_op));
  250.       SB_DATA  (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
  251.       SB_DATA  (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
  252.    } else {
  253.       SB_MTHD30(so, STENCIL_ENABLE(1), 1);
  254.       SB_DATA  (so, 0);
  255.    }
  256.  
  257.    SB_MTHD30(so, ALPHA_FUNC_ENABLE, 3);
  258.    SB_DATA  (so, cso->alpha.enabled ? 1 : 0);
  259.    SB_DATA  (so, nvgl_comparison_op(cso->alpha.func));
  260.    SB_DATA  (so, float_to_ubyte(cso->alpha.ref_value));
  261.  
  262.    return so;
  263. }
  264.  
  265. static void
  266. nv30_zsa_state_bind(struct pipe_context *pipe, void *hwcso)
  267. {
  268.    struct nv30_context *nv30 = nv30_context(pipe);
  269.  
  270.    nv30->zsa = hwcso;
  271.    nv30->dirty |= NV30_NEW_ZSA;
  272. }
  273.  
  274. static void
  275. nv30_zsa_state_delete(struct pipe_context *pipe, void *hwcso)
  276. {
  277.    FREE(hwcso);
  278. }
  279.  
  280. static void
  281. nv30_set_blend_color(struct pipe_context *pipe,
  282.                      const struct pipe_blend_color *bcol)
  283. {
  284.     struct nv30_context *nv30 = nv30_context(pipe);
  285.  
  286.     nv30->blend_colour = *bcol;
  287.     nv30->dirty |= NV30_NEW_BLEND_COLOUR;
  288. }
  289.  
  290. static void
  291. nv30_set_stencil_ref(struct pipe_context *pipe,
  292.                      const struct pipe_stencil_ref *sr)
  293. {
  294.     struct nv30_context *nv30 = nv30_context(pipe);
  295.  
  296.     nv30->stencil_ref = *sr;
  297.     nv30->dirty |= NV30_NEW_STENCIL_REF;
  298. }
  299.  
  300. static void
  301. nv30_set_clip_state(struct pipe_context *pipe,
  302.                     const struct pipe_clip_state *clip)
  303. {
  304.     struct nv30_context *nv30 = nv30_context(pipe);
  305.  
  306.     memcpy(nv30->clip.ucp, clip->ucp, sizeof(clip->ucp));
  307.  
  308.     nv30->dirty |= NV30_NEW_CLIP;
  309. }
  310.  
  311. static void
  312. nv30_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
  313. {
  314.     struct nv30_context *nv30 = nv30_context(pipe);
  315.  
  316.     nv30->sample_mask = sample_mask;
  317.     nv30->dirty |= NV30_NEW_SAMPLE_MASK;
  318. }
  319.  
  320. static void
  321. nv30_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
  322.                          struct pipe_constant_buffer *cb)
  323. {
  324.    struct nv30_context *nv30 = nv30_context(pipe);
  325.    struct pipe_resource *buf = cb ? cb->buffer : NULL;
  326.    unsigned size;
  327.  
  328.    if (cb && cb->user_buffer) {
  329.       buf = nouveau_user_buffer_create(pipe->screen, (void*)cb->user_buffer,
  330.                                        cb->buffer_size,
  331.                                        PIPE_BIND_CONSTANT_BUFFER);
  332.    }
  333.  
  334.    size = 0;
  335.    if (buf)
  336.       size = buf->width0 / (4 * sizeof(float));
  337.  
  338.    if (shader == PIPE_SHADER_VERTEX) {
  339.       pipe_resource_reference(&nv30->vertprog.constbuf, buf);
  340.       nv30->vertprog.constbuf_nr = size;
  341.       nv30->dirty |= NV30_NEW_VERTCONST;
  342.    } else
  343.    if (shader == PIPE_SHADER_FRAGMENT) {
  344.       pipe_resource_reference(&nv30->fragprog.constbuf, buf);
  345.       nv30->fragprog.constbuf_nr = size;
  346.       nv30->dirty |= NV30_NEW_FRAGCONST;
  347.    }
  348.  
  349.    if (cb && cb->user_buffer) {
  350.       pipe_resource_reference(&buf, NULL);
  351.    }
  352. }
  353.  
  354. static void
  355. nv30_set_framebuffer_state(struct pipe_context *pipe,
  356.                            const struct pipe_framebuffer_state *fb)
  357. {
  358.     struct nv30_context *nv30 = nv30_context(pipe);
  359.  
  360.     nouveau_bufctx_reset(nv30->bufctx, BUFCTX_FB);
  361.  
  362.     nv30->framebuffer = *fb;
  363.     nv30->dirty |= NV30_NEW_FRAMEBUFFER;
  364.  
  365.    /* Hardware can't handle different swizzled-ness or different blocksizes
  366.     * for zs and cbufs. If both are supplied and something doesn't match,
  367.     * blank out the zs for now so that at least *some* rendering can occur.
  368.     */
  369.     if (fb->nr_cbufs > 0 && fb->zsbuf) {
  370.        struct nv30_miptree *color_mt = nv30_miptree(fb->cbufs[0]->texture);
  371.        struct nv30_miptree *zeta_mt = nv30_miptree(fb->zsbuf->texture);
  372.  
  373.        if (color_mt->swizzled != zeta_mt->swizzled ||
  374.            (util_format_get_blocksize(fb->zsbuf->format) > 2) !=
  375.            (util_format_get_blocksize(fb->cbufs[0]->format) > 2)) {
  376.           nv30->framebuffer.zsbuf = NULL;
  377.           debug_printf("Mismatched color and zeta formats, ignoring zeta.\n");
  378.        }
  379.     }
  380. }
  381.  
  382. static void
  383. nv30_set_polygon_stipple(struct pipe_context *pipe,
  384.                          const struct pipe_poly_stipple *stipple)
  385. {
  386.     struct nv30_context *nv30 = nv30_context(pipe);
  387.  
  388.     nv30->stipple = *stipple;
  389.     nv30->dirty |= NV30_NEW_STIPPLE;
  390. }
  391.  
  392. static void
  393. nv30_set_scissor_states(struct pipe_context *pipe,
  394.                         unsigned start_slot,
  395.                         unsigned num_viewports,
  396.                         const struct pipe_scissor_state *scissor)
  397. {
  398.     struct nv30_context *nv30 = nv30_context(pipe);
  399.  
  400.     nv30->scissor = *scissor;
  401.     nv30->dirty |= NV30_NEW_SCISSOR;
  402. }
  403.  
  404. static void
  405. nv30_set_viewport_states(struct pipe_context *pipe,
  406.                          unsigned start_slot,
  407.                          unsigned num_viewports,
  408.                          const struct pipe_viewport_state *vpt)
  409. {
  410.     struct nv30_context *nv30 = nv30_context(pipe);
  411.  
  412.     nv30->viewport = *vpt;
  413.     nv30->dirty |= NV30_NEW_VIEWPORT;
  414. }
  415.  
  416. static void
  417. nv30_set_vertex_buffers(struct pipe_context *pipe,
  418.                         unsigned start_slot, unsigned count,
  419.                         const struct pipe_vertex_buffer *vb)
  420. {
  421.     struct nv30_context *nv30 = nv30_context(pipe);
  422.  
  423.     nouveau_bufctx_reset(nv30->bufctx, BUFCTX_VTXBUF);
  424.  
  425.     util_set_vertex_buffers_count(nv30->vtxbuf, &nv30->num_vtxbufs,
  426.                                   vb, start_slot, count);
  427.  
  428.     nv30->dirty |= NV30_NEW_ARRAYS;
  429. }
  430.  
  431. static void
  432. nv30_set_index_buffer(struct pipe_context *pipe,
  433.                       const struct pipe_index_buffer *ib)
  434. {
  435.     struct nv30_context *nv30 = nv30_context(pipe);
  436.  
  437.     if (ib) {
  438.        pipe_resource_reference(&nv30->idxbuf.buffer, ib->buffer);
  439.        nv30->idxbuf.index_size = ib->index_size;
  440.        nv30->idxbuf.offset = ib->offset;
  441.        nv30->idxbuf.user_buffer = ib->user_buffer;
  442.     } else {
  443.        pipe_resource_reference(&nv30->idxbuf.buffer, NULL);
  444.        nv30->idxbuf.user_buffer = NULL;
  445.     }
  446. }
  447.  
  448. void
  449. nv30_state_init(struct pipe_context *pipe)
  450. {
  451.    pipe->create_blend_state = nv30_blend_state_create;
  452.    pipe->bind_blend_state = nv30_blend_state_bind;
  453.    pipe->delete_blend_state = nv30_blend_state_delete;
  454.  
  455.    pipe->create_rasterizer_state = nv30_rasterizer_state_create;
  456.    pipe->bind_rasterizer_state = nv30_rasterizer_state_bind;
  457.    pipe->delete_rasterizer_state = nv30_rasterizer_state_delete;
  458.  
  459.    pipe->create_depth_stencil_alpha_state = nv30_zsa_state_create;
  460.    pipe->bind_depth_stencil_alpha_state = nv30_zsa_state_bind;
  461.    pipe->delete_depth_stencil_alpha_state = nv30_zsa_state_delete;
  462.  
  463.    pipe->set_blend_color = nv30_set_blend_color;
  464.    pipe->set_stencil_ref = nv30_set_stencil_ref;
  465.    pipe->set_clip_state = nv30_set_clip_state;
  466.    pipe->set_sample_mask = nv30_set_sample_mask;
  467.    pipe->set_constant_buffer = nv30_set_constant_buffer;
  468.    pipe->set_framebuffer_state = nv30_set_framebuffer_state;
  469.    pipe->set_polygon_stipple = nv30_set_polygon_stipple;
  470.    pipe->set_scissor_states = nv30_set_scissor_states;
  471.    pipe->set_viewport_states = nv30_set_viewport_states;
  472.  
  473.    pipe->set_vertex_buffers = nv30_set_vertex_buffers;
  474.    pipe->set_index_buffer = nv30_set_index_buffer;
  475. }
  476.