Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 VMware, Inc.
  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 VMWARE 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 *curfs = &fs->shader;
  55.  
  56.    /* codegen, create variant object */
  57.    var = softpipe_create_fs_variant_exec(softpipe);
  58.  
  59.    if (var) {
  60.       var->key = *key;
  61.  
  62. #if DO_PSTIPPLE_IN_HELPER_MODULE
  63.       if (key->polygon_stipple) {
  64.          /* get new shader that implements polygon stippling */
  65.          var->tokens =
  66.             util_pstipple_create_fragment_shader(curfs->tokens,
  67.                                                  &var->stipple_sampler_unit, 0);
  68.       }
  69.       else
  70. #endif
  71.       {
  72.          var->tokens = tgsi_dup_tokens(curfs->tokens);
  73.          var->stipple_sampler_unit = 0;
  74.       }
  75.  
  76.       tgsi_scan_shader(var->tokens, &var->info);
  77.  
  78.       /* See comments elsewhere about draw fragment shaders */
  79. #if 0
  80.       /* draw's fs state */
  81.       var->draw_shader = draw_create_fragment_shader(softpipe->draw,
  82.                                                      &fs->shader);
  83.       if (!var->draw_shader) {
  84.          var->delete(var);
  85.          FREE((void *) var->tokens);
  86.          return NULL;
  87.       }
  88. #endif
  89.  
  90.       /* insert variant into linked list */
  91.       var->next = fs->variants;
  92.       fs->variants = var;
  93.    }
  94.  
  95.    return var;
  96. }
  97.  
  98.  
  99. struct sp_fragment_shader_variant *
  100. softpipe_find_fs_variant(struct softpipe_context *sp,
  101.                          struct sp_fragment_shader *fs,
  102.                          const struct sp_fragment_shader_variant_key *key)
  103. {
  104.    struct sp_fragment_shader_variant *var;
  105.  
  106.    for (var = fs->variants; var; var = var->next) {
  107.       if (memcmp(&var->key, key, sizeof(*key)) == 0) {
  108.          /* found it */
  109.          return var;
  110.       }
  111.    }
  112.  
  113.    return create_fs_variant(sp, fs, key);
  114. }
  115.  
  116.  
  117. static void *
  118. softpipe_create_fs_state(struct pipe_context *pipe,
  119.                          const struct pipe_shader_state *templ)
  120. {
  121.    struct softpipe_context *softpipe = softpipe_context(pipe);
  122.    struct sp_fragment_shader *state = CALLOC_STRUCT(sp_fragment_shader);
  123.  
  124.    /* debug */
  125.    if (softpipe->dump_fs)
  126.       tgsi_dump(templ->tokens, 0);
  127.  
  128.    /* we need to keep a local copy of the tokens */
  129.    state->shader.tokens = tgsi_dup_tokens(templ->tokens);
  130.  
  131.    /* draw's fs state */
  132.    state->draw_shader = draw_create_fragment_shader(softpipe->draw,
  133.                                                     &state->shader);
  134.    if (!state->draw_shader) {
  135.       tgsi_free_tokens(state->shader.tokens);
  136.       FREE(state);
  137.       return NULL;
  138.    }
  139.  
  140.    return state;
  141. }
  142.  
  143.  
  144. static void
  145. softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
  146. {
  147.    struct softpipe_context *softpipe = softpipe_context(pipe);
  148.    struct sp_fragment_shader *state = (struct sp_fragment_shader *) fs;
  149.  
  150.    if (softpipe->fs == fs)
  151.       return;
  152.  
  153.    draw_flush(softpipe->draw);
  154.  
  155.    softpipe->fs = fs;
  156.  
  157.    /* This depends on the current fragment shader and must always be
  158.     * re-validated before use.
  159.     */
  160.    softpipe->fs_variant = NULL;
  161.  
  162.    if (state)
  163.       draw_bind_fragment_shader(softpipe->draw,
  164.                                 state->draw_shader);
  165.    else
  166.       draw_bind_fragment_shader(softpipe->draw, NULL);
  167.  
  168.    softpipe->dirty |= SP_NEW_FS;
  169. }
  170.  
  171.  
  172. static void
  173. softpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
  174. {
  175.    struct softpipe_context *softpipe = softpipe_context(pipe);
  176.    struct sp_fragment_shader *state = fs;
  177.    struct sp_fragment_shader_variant *var, *next_var;
  178.  
  179.    assert(fs != softpipe->fs);
  180.  
  181.    /* delete variants */
  182.    for (var = state->variants; var; var = next_var) {
  183.       next_var = var->next;
  184.  
  185.       assert(var != softpipe->fs_variant);
  186.  
  187.       /* See comments elsewhere about draw fragment shaders */
  188. #if 0
  189.       draw_delete_fragment_shader(softpipe->draw, var->draw_shader);
  190. #endif
  191.  
  192.       var->delete(var, softpipe->fs_machine);
  193.    }
  194.  
  195.    draw_delete_fragment_shader(softpipe->draw, state->draw_shader);
  196.  
  197.    tgsi_free_tokens(state->shader.tokens);
  198.    FREE(state);
  199. }
  200.  
  201.  
  202. static void *
  203. softpipe_create_vs_state(struct pipe_context *pipe,
  204.                          const struct pipe_shader_state *templ)
  205. {
  206.    struct softpipe_context *softpipe = softpipe_context(pipe);
  207.    struct sp_vertex_shader *state;
  208.  
  209.    state = CALLOC_STRUCT(sp_vertex_shader);
  210.    if (state == NULL )
  211.       goto fail;
  212.  
  213.    /* copy shader tokens, the ones passed in will go away.
  214.     */
  215.    state->shader.tokens = tgsi_dup_tokens(templ->tokens);
  216.    if (state->shader.tokens == NULL)
  217.       goto fail;
  218.  
  219.    state->draw_data = draw_create_vertex_shader(softpipe->draw, templ);
  220.    if (state->draw_data == NULL)
  221.       goto fail;
  222.  
  223.    state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
  224.  
  225.    return state;
  226.  
  227. fail:
  228.    if (state) {
  229.       tgsi_free_tokens(state->shader.tokens);
  230.       FREE( state->draw_data );
  231.       FREE( state );
  232.    }
  233.    return NULL;
  234. }
  235.  
  236.  
  237. static void
  238. softpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
  239. {
  240.    struct softpipe_context *softpipe = softpipe_context(pipe);
  241.  
  242.    softpipe->vs = (struct sp_vertex_shader *) vs;
  243.  
  244.    draw_bind_vertex_shader(softpipe->draw,
  245.                            (softpipe->vs ? softpipe->vs->draw_data : NULL));
  246.  
  247.    softpipe->dirty |= SP_NEW_VS;
  248. }
  249.  
  250.  
  251. static void
  252. softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
  253. {
  254.    struct softpipe_context *softpipe = softpipe_context(pipe);
  255.  
  256.    struct sp_vertex_shader *state = (struct sp_vertex_shader *) vs;
  257.  
  258.    draw_delete_vertex_shader(softpipe->draw, state->draw_data);
  259.    tgsi_free_tokens(state->shader.tokens);
  260.    FREE( state );
  261. }
  262.  
  263.  
  264. static void *
  265. softpipe_create_gs_state(struct pipe_context *pipe,
  266.                          const struct pipe_shader_state *templ)
  267. {
  268.    struct softpipe_context *softpipe = softpipe_context(pipe);
  269.    struct sp_geometry_shader *state;
  270.  
  271.    state = CALLOC_STRUCT(sp_geometry_shader);
  272.    if (state == NULL )
  273.       goto fail;
  274.  
  275.    state->shader = *templ;
  276.  
  277.    if (templ->tokens) {
  278.       /* debug */
  279.       if (softpipe->dump_gs)
  280.          tgsi_dump(templ->tokens, 0);
  281.  
  282.       /* copy shader tokens, the ones passed in will go away.
  283.        */
  284.       state->shader.tokens = tgsi_dup_tokens(templ->tokens);
  285.       if (state->shader.tokens == NULL)
  286.          goto fail;
  287.  
  288.       state->draw_data = draw_create_geometry_shader(softpipe->draw, templ);
  289.       if (state->draw_data == NULL)
  290.          goto fail;
  291.  
  292.       state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
  293.    }
  294.  
  295.    return state;
  296.  
  297. fail:
  298.    if (state) {
  299.       tgsi_free_tokens(state->shader.tokens);
  300.       FREE( state->draw_data );
  301.       FREE( state );
  302.    }
  303.    return NULL;
  304. }
  305.  
  306.  
  307. static void
  308. softpipe_bind_gs_state(struct pipe_context *pipe, void *gs)
  309. {
  310.    struct softpipe_context *softpipe = softpipe_context(pipe);
  311.  
  312.    softpipe->gs = (struct sp_geometry_shader *)gs;
  313.  
  314.    draw_bind_geometry_shader(softpipe->draw,
  315.                              (softpipe->gs ? softpipe->gs->draw_data : NULL));
  316.  
  317.    softpipe->dirty |= SP_NEW_GS;
  318. }
  319.  
  320.  
  321. static void
  322. softpipe_delete_gs_state(struct pipe_context *pipe, void *gs)
  323. {
  324.    struct softpipe_context *softpipe = softpipe_context(pipe);
  325.  
  326.    struct sp_geometry_shader *state =
  327.       (struct sp_geometry_shader *)gs;
  328.  
  329.    draw_delete_geometry_shader(softpipe->draw,
  330.                                (state) ? state->draw_data : 0);
  331.  
  332.    tgsi_free_tokens(state->shader.tokens);
  333.    FREE(state);
  334. }
  335.  
  336.  
  337. static void
  338. softpipe_set_constant_buffer(struct pipe_context *pipe,
  339.                              uint shader, uint index,
  340.                              struct pipe_constant_buffer *cb)
  341. {
  342.    struct softpipe_context *softpipe = softpipe_context(pipe);
  343.    struct pipe_resource *constants = cb ? cb->buffer : NULL;
  344.    unsigned size;
  345.    const void *data;
  346.  
  347.    assert(shader < PIPE_SHADER_TYPES);
  348.  
  349.    if (cb && cb->user_buffer) {
  350.       constants = softpipe_user_buffer_create(pipe->screen,
  351.                                               (void *) cb->user_buffer,
  352.                                               cb->buffer_size,
  353.                                               PIPE_BIND_CONSTANT_BUFFER);
  354.    }
  355.  
  356.    size = cb ? cb->buffer_size : 0;
  357.    data = constants ? softpipe_resource_data(constants) : NULL;
  358.    if (data)
  359.       data = (const char *) data + cb->buffer_offset;
  360.  
  361.    draw_flush(softpipe->draw);
  362.  
  363.    /* note: reference counting */
  364.    pipe_resource_reference(&softpipe->constants[shader][index], constants);
  365.  
  366.    if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {
  367.       draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size);
  368.    }
  369.  
  370.    softpipe->mapped_constants[shader][index] = data;
  371.    softpipe->const_buffer_size[shader][index] = size;
  372.  
  373.    softpipe->dirty |= SP_NEW_CONSTANTS;
  374.  
  375.    if (cb && cb->user_buffer) {
  376.       pipe_resource_reference(&constants, NULL);
  377.    }
  378. }
  379.  
  380.  
  381. void
  382. softpipe_init_shader_funcs(struct pipe_context *pipe)
  383. {
  384.    pipe->create_fs_state = softpipe_create_fs_state;
  385.    pipe->bind_fs_state   = softpipe_bind_fs_state;
  386.    pipe->delete_fs_state = softpipe_delete_fs_state;
  387.  
  388.    pipe->create_vs_state = softpipe_create_vs_state;
  389.    pipe->bind_vs_state   = softpipe_bind_vs_state;
  390.    pipe->delete_vs_state = softpipe_delete_vs_state;
  391.  
  392.    pipe->create_gs_state = softpipe_create_gs_state;
  393.    pipe->bind_gs_state   = softpipe_bind_gs_state;
  394.    pipe->delete_gs_state = softpipe_delete_gs_state;
  395.  
  396.    pipe->set_constant_buffer = softpipe_set_constant_buffer;
  397. }
  398.