Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. #include "sp_context.h"
  29. #include "sp_state.h"
  30. #include "sp_fs.h"
  31. #include "sp_texture.h"
  32.  
  33. #include "pipe/p_defines.h"
  34. #include "util/u_memory.h"
  35. #include "util/u_inlines.h"
  36. #include "util/u_pstipple.h"
  37. #include "draw/draw_context.h"
  38. #include "draw/draw_vs.h"
  39. #include "draw/draw_gs.h"
  40. #include "tgsi/tgsi_dump.h"
  41. #include "tgsi/tgsi_scan.h"
  42. #include "tgsi/tgsi_parse.h"
  43.  
  44.  
  45. /**
  46.  * Create a new fragment shader variant.
  47.  */
  48. static struct sp_fragment_shader_variant *
  49. create_fs_variant(struct softpipe_context *softpipe,
  50.                   struct sp_fragment_shader *fs,
  51.                   const struct sp_fragment_shader_variant_key *key)
  52. {
  53.    struct sp_fragment_shader_variant *var;
  54.    struct pipe_shader_state *stipple_fs = NULL, *curfs = &fs->shader;
  55.    unsigned unit = 0;
  56.  
  57. #if DO_PSTIPPLE_IN_HELPER_MODULE
  58.    if (key->polygon_stipple) {
  59.       /* get new shader that implements polygon stippling */
  60.       stipple_fs = util_pstipple_create_fragment_shader(&softpipe->pipe,
  61.                                                         curfs, &unit);
  62.       curfs = stipple_fs;
  63.    }
  64. #endif
  65.  
  66.    /* codegen, create variant object */
  67.    var = softpipe_create_fs_variant_exec(softpipe, curfs);
  68.  
  69.    if (var) {
  70.       var->key = *key;
  71.       var->tokens = tgsi_dup_tokens(curfs->tokens);
  72.       var->stipple_sampler_unit = unit;
  73.  
  74.       tgsi_scan_shader(var->tokens, &var->info);
  75.  
  76.       /* See comments elsewhere about draw fragment shaders */
  77. #if 0
  78.       /* draw's fs state */
  79.       var->draw_shader = draw_create_fragment_shader(softpipe->draw,
  80.                                                      &fs->shader);
  81.       if (!var->draw_shader) {
  82.          var->delete(var);
  83.          FREE((void *) var->tokens);
  84.          return NULL;
  85.       }
  86. #endif
  87.  
  88.       /* insert variant into linked list */
  89.       var->next = fs->variants;
  90.       fs->variants = var;
  91.    }
  92.  
  93.    if (stipple_fs) {
  94.       FREE((void *) stipple_fs->tokens);
  95.       FREE(stipple_fs);
  96.    }
  97.  
  98.    return var;
  99. }
  100.  
  101.  
  102. struct sp_fragment_shader_variant *
  103. softpipe_find_fs_variant(struct softpipe_context *sp,
  104.                          struct sp_fragment_shader *fs,
  105.                          const struct sp_fragment_shader_variant_key *key)
  106. {
  107.    struct sp_fragment_shader_variant *var;
  108.  
  109.    for (var = fs->variants; var; var = var->next) {
  110.       if (memcmp(&var->key, key, sizeof(*key)) == 0) {
  111.          /* found it */
  112.          return var;
  113.       }
  114.    }
  115.  
  116.    return create_fs_variant(sp, fs, key);
  117. }
  118.  
  119.  
  120. static void *
  121. softpipe_create_fs_state(struct pipe_context *pipe,
  122.                          const struct pipe_shader_state *templ)
  123. {
  124.    struct softpipe_context *softpipe = softpipe_context(pipe);
  125.    struct sp_fragment_shader *state = CALLOC_STRUCT(sp_fragment_shader);
  126.  
  127.    /* debug */
  128.    if (softpipe->dump_fs)
  129.       tgsi_dump(templ->tokens, 0);
  130.  
  131.    /* we need to keep a local copy of the tokens */
  132.    state->shader.tokens = tgsi_dup_tokens(templ->tokens);
  133.  
  134.    /* draw's fs state */
  135.    state->draw_shader = draw_create_fragment_shader(softpipe->draw,
  136.                                                     &state->shader);
  137.    if (!state->draw_shader) {
  138.       FREE((void *) state->shader.tokens);
  139.       FREE(state);
  140.       return NULL;
  141.    }
  142.  
  143.    return state;
  144. }
  145.  
  146.  
  147. static void
  148. softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
  149. {
  150.    struct softpipe_context *softpipe = softpipe_context(pipe);
  151.    struct sp_fragment_shader *state = (struct sp_fragment_shader *) fs;
  152.  
  153.    if (softpipe->fs == fs)
  154.       return;
  155.  
  156.    draw_flush(softpipe->draw);
  157.  
  158.    softpipe->fs = fs;
  159.  
  160.    /* This depends on the current fragment shader and must always be
  161.     * re-validated before use.
  162.     */
  163.    softpipe->fs_variant = NULL;
  164.  
  165.    if (state)
  166.       draw_bind_fragment_shader(softpipe->draw,
  167.                                 state->draw_shader);
  168.    else
  169.       draw_bind_fragment_shader(softpipe->draw, NULL);
  170.  
  171.    softpipe->dirty |= SP_NEW_FS;
  172. }
  173.  
  174.  
  175. static void
  176. softpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
  177. {
  178.    struct softpipe_context *softpipe = softpipe_context(pipe);
  179.    struct sp_fragment_shader *state = fs;
  180.    struct sp_fragment_shader_variant *var, *next_var;
  181.  
  182.    assert(fs != softpipe->fs);
  183.  
  184.    /* delete variants */
  185.    for (var = state->variants; var; var = next_var) {
  186.       next_var = var->next;
  187.  
  188.       assert(var != softpipe->fs_variant);
  189.  
  190.       /* See comments elsewhere about draw fragment shaders */
  191. #if 0
  192.       draw_delete_fragment_shader(softpipe->draw, var->draw_shader);
  193. #endif
  194.  
  195.       var->delete(var, softpipe->fs_machine);
  196.    }
  197.  
  198.    draw_delete_fragment_shader(softpipe->draw, state->draw_shader);
  199.  
  200.    FREE((void *) state->shader.tokens);
  201.    FREE(state);
  202. }
  203.  
  204.  
  205. static void *
  206. softpipe_create_vs_state(struct pipe_context *pipe,
  207.                          const struct pipe_shader_state *templ)
  208. {
  209.    struct softpipe_context *softpipe = softpipe_context(pipe);
  210.    struct sp_vertex_shader *state;
  211.  
  212.    state = CALLOC_STRUCT(sp_vertex_shader);
  213.    if (state == NULL )
  214.       goto fail;
  215.  
  216.    /* copy shader tokens, the ones passed in will go away.
  217.     */
  218.    state->shader.tokens = tgsi_dup_tokens(templ->tokens);
  219.    if (state->shader.tokens == NULL)
  220.       goto fail;
  221.  
  222.    state->draw_data = draw_create_vertex_shader(softpipe->draw, templ);
  223.    if (state->draw_data == NULL)
  224.       goto fail;
  225.  
  226.    state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
  227.  
  228.    return state;
  229.  
  230. fail:
  231.    if (state) {
  232.       FREE( (void *)state->shader.tokens );
  233.       FREE( state->draw_data );
  234.       FREE( state );
  235.    }
  236.    return NULL;
  237. }
  238.  
  239.  
  240. static void
  241. softpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
  242. {
  243.    struct softpipe_context *softpipe = softpipe_context(pipe);
  244.  
  245.    softpipe->vs = (struct sp_vertex_shader *) vs;
  246.  
  247.    draw_bind_vertex_shader(softpipe->draw,
  248.                            (softpipe->vs ? softpipe->vs->draw_data : NULL));
  249.  
  250.    softpipe->dirty |= SP_NEW_VS;
  251. }
  252.  
  253.  
  254. static void
  255. softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
  256. {
  257.    struct softpipe_context *softpipe = softpipe_context(pipe);
  258.  
  259.    struct sp_vertex_shader *state = (struct sp_vertex_shader *) vs;
  260.  
  261.    draw_delete_vertex_shader(softpipe->draw, state->draw_data);
  262.    FREE( (void *)state->shader.tokens );
  263.    FREE( state );
  264. }
  265.  
  266.  
  267. static void *
  268. softpipe_create_gs_state(struct pipe_context *pipe,
  269.                          const struct pipe_shader_state *templ)
  270. {
  271.    struct softpipe_context *softpipe = softpipe_context(pipe);
  272.    struct sp_geometry_shader *state;
  273.  
  274.    state = CALLOC_STRUCT(sp_geometry_shader);
  275.    if (state == NULL )
  276.       goto fail;
  277.  
  278.    state->shader = *templ;
  279.  
  280.    if (templ->tokens) {
  281.       /* debug */
  282.       if (softpipe->dump_gs)
  283.          tgsi_dump(templ->tokens, 0);
  284.  
  285.       /* copy shader tokens, the ones passed in will go away.
  286.        */
  287.       state->shader.tokens = tgsi_dup_tokens(templ->tokens);
  288.       if (state->shader.tokens == NULL)
  289.          goto fail;
  290.  
  291.       state->draw_data = draw_create_geometry_shader(softpipe->draw, templ);
  292.       if (state->draw_data == NULL)
  293.          goto fail;
  294.  
  295.       state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
  296.    }
  297.  
  298.    return state;
  299.  
  300. fail:
  301.    if (state) {
  302.       FREE( (void *)state->shader.tokens );
  303.       FREE( state->draw_data );
  304.       FREE( state );
  305.    }
  306.    return NULL;
  307. }
  308.  
  309.  
  310. static void
  311. softpipe_bind_gs_state(struct pipe_context *pipe, void *gs)
  312. {
  313.    struct softpipe_context *softpipe = softpipe_context(pipe);
  314.  
  315.    softpipe->gs = (struct sp_geometry_shader *)gs;
  316.  
  317.    draw_bind_geometry_shader(softpipe->draw,
  318.                              (softpipe->gs ? softpipe->gs->draw_data : NULL));
  319.  
  320.    softpipe->dirty |= SP_NEW_GS;
  321. }
  322.  
  323.  
  324. static void
  325. softpipe_delete_gs_state(struct pipe_context *pipe, void *gs)
  326. {
  327.    struct softpipe_context *softpipe = softpipe_context(pipe);
  328.  
  329.    struct sp_geometry_shader *state =
  330.       (struct sp_geometry_shader *)gs;
  331.  
  332.    draw_delete_geometry_shader(softpipe->draw,
  333.                                (state) ? state->draw_data : 0);
  334.  
  335.    FREE((void *) state->shader.tokens);
  336.    FREE(state);
  337. }
  338.  
  339.  
  340. static void
  341. softpipe_set_constant_buffer(struct pipe_context *pipe,
  342.                              uint shader, uint index,
  343.                              struct pipe_constant_buffer *cb)
  344. {
  345.    struct softpipe_context *softpipe = softpipe_context(pipe);
  346.    struct pipe_resource *constants = cb ? cb->buffer : NULL;
  347.    unsigned size;
  348.    const void *data;
  349.  
  350.    if (cb && cb->user_buffer) {
  351.       constants = softpipe_user_buffer_create(pipe->screen,
  352.                                               (void *) cb->user_buffer,
  353.                                               cb->buffer_size,
  354.                                               PIPE_BIND_CONSTANT_BUFFER);
  355.    }
  356.  
  357.    size = constants ? constants->width0 : 0;
  358.    data = constants ? softpipe_resource(constants)->data : NULL;
  359.  
  360.    assert(shader < PIPE_SHADER_TYPES);
  361.  
  362.    draw_flush(softpipe->draw);
  363.  
  364.    /* note: reference counting */
  365.    pipe_resource_reference(&softpipe->constants[shader][index], constants);
  366.  
  367.    if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {
  368.       draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size);
  369.    }
  370.  
  371.    softpipe->mapped_constants[shader][index] = data;
  372.    softpipe->const_buffer_size[shader][index] = size;
  373.  
  374.    softpipe->dirty |= SP_NEW_CONSTANTS;
  375.  
  376.    if (cb && cb->user_buffer) {
  377.       pipe_resource_reference(&constants, NULL);
  378.    }
  379. }
  380.  
  381.  
  382. void
  383. softpipe_init_shader_funcs(struct pipe_context *pipe)
  384. {
  385.    pipe->create_fs_state = softpipe_create_fs_state;
  386.    pipe->bind_fs_state   = softpipe_bind_fs_state;
  387.    pipe->delete_fs_state = softpipe_delete_fs_state;
  388.  
  389.    pipe->create_vs_state = softpipe_create_vs_state;
  390.    pipe->bind_vs_state   = softpipe_bind_vs_state;
  391.    pipe->delete_vs_state = softpipe_delete_vs_state;
  392.  
  393.    pipe->create_gs_state = softpipe_create_gs_state;
  394.    pipe->bind_gs_state   = softpipe_bind_gs_state;
  395.    pipe->delete_gs_state = softpipe_delete_gs_state;
  396.  
  397.    pipe->set_constant_buffer = softpipe_set_constant_buffer;
  398. }
  399.