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