/**************************************************************************
*
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "draw/draw_vs.h"
#include "draw/draw_gs.h"
#include "tgsi/tgsi_dump.h"
-#include "tgsi/tgsi_exec.h"
#include "tgsi/tgsi_scan.h"
#include "tgsi/tgsi_parse.h"
const struct sp_fragment_shader_variant_key *key)
{
struct sp_fragment_shader_variant *var;
- struct pipe_shader_state *stipple_fs = NULL, *curfs = &fs->shader;
- unsigned unit = 0;
-
-#if DO_PSTIPPLE_IN_HELPER_MODULE
- if (key->polygon_stipple) {
- /* get new shader that implements polygon stippling */
- stipple_fs = util_pstipple_create_fragment_shader(&softpipe->pipe,
- curfs, &unit);
- curfs = stipple_fs;
- }
-#endif
+ struct pipe_shader_state *curfs = &fs->shader;
/* codegen, create variant object */
- var = softpipe_create_fs_variant_exec(softpipe, curfs);
+ var = softpipe_create_fs_variant_exec(softpipe);
if (var) {
var->key = *key;
- var->tokens = tgsi_dup_tokens(curfs->tokens);
- var->stipple_sampler_unit = unit;
+
+#if DO_PSTIPPLE_IN_HELPER_MODULE
+ if (key->polygon_stipple) {
+ /* get new shader that implements polygon stippling */
+ var->tokens =
+ util_pstipple_create_fragment_shader(curfs->tokens,
+ &var->stipple_sampler_unit, 0,
+ TGSI_FILE_INPUT);
+ }
+ else
+#endif
+ {
+ var->tokens = tgsi_dup_tokens(curfs->tokens);
+ var->stipple_sampler_unit = 0;
+ }
tgsi_scan_shader(var->tokens, &var->info);
fs->variants = var;
}
- if (stipple_fs) {
- FREE((void *) stipple_fs->tokens);
- FREE(stipple_fs);
- }
-
return var;
}
state->draw_shader = draw_create_fragment_shader(softpipe->draw,
&state->shader);
if (!state->draw_shader) {
- FREE((void *) state->shader.tokens);
+ tgsi_free_tokens(state->shader.tokens);
FREE(state);
return NULL;
}
assert(fs != softpipe->fs);
- if (softpipe->fs_machine->Tokens == state->shader.tokens) {
- /* unbind the shader from the tgsi executor if we're
- * deleting it.
- */
- tgsi_exec_machine_bind_shader(softpipe->fs_machine, NULL, 0, NULL);
- }
-
/* delete variants */
for (var = state->variants; var; var = next_var) {
next_var = var->next;
draw_delete_fragment_shader(softpipe->draw, var->draw_shader);
#endif
- var->delete(var);
+ var->delete(var, softpipe->fs_machine);
}
draw_delete_fragment_shader(softpipe->draw, state->draw_shader);
- FREE((void *) state->shader.tokens);
+ tgsi_free_tokens(state->shader.tokens);
FREE(state);
}
struct sp_vertex_shader *state;
state = CALLOC_STRUCT(sp_vertex_shader);
- if (state == NULL )
+ if (!state)
goto fail;
/* copy shader tokens, the ones passed in will go away.
fail:
if (state) {
- FREE( (void *)state->shader.tokens );
+ tgsi_free_tokens(state->shader.tokens);
FREE( state->draw_data );
FREE( state );
}
struct sp_vertex_shader *state = (struct sp_vertex_shader *) vs;
draw_delete_vertex_shader(softpipe->draw, state->draw_data);
- FREE( (void *)state->shader.tokens );
+ tgsi_free_tokens(state->shader.tokens);
FREE( state );
}
struct sp_geometry_shader *state;
state = CALLOC_STRUCT(sp_geometry_shader);
- if (state == NULL )
+ if (!state)
goto fail;
- /* debug */
- if (softpipe->dump_gs)
- tgsi_dump(templ->tokens, 0);
+ state->shader = *templ;
- /* copy shader tokens, the ones passed in will go away.
- */
- state->shader.tokens = tgsi_dup_tokens(templ->tokens);
- if (state->shader.tokens == NULL)
- goto fail;
+ if (templ->tokens) {
+ /* debug */
+ if (softpipe->dump_gs)
+ tgsi_dump(templ->tokens, 0);
- state->draw_data = draw_create_geometry_shader(softpipe->draw, templ);
- if (state->draw_data == NULL)
- goto fail;
+ /* copy shader tokens, the ones passed in will go away.
+ */
+ state->shader.tokens = tgsi_dup_tokens(templ->tokens);
+ if (state->shader.tokens == NULL)
+ goto fail;
- state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
+ state->draw_data = draw_create_geometry_shader(softpipe->draw, templ);
+ if (state->draw_data == NULL)
+ goto fail;
+
+ state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
+ }
return state;
fail:
if (state) {
- FREE( (void *)state->shader.tokens );
+ tgsi_free_tokens(state->shader.tokens);
FREE( state->draw_data );
FREE( state );
}
draw_delete_geometry_shader(softpipe->draw,
(state) ? state->draw_data : 0);
- FREE((void *) state->shader.tokens);
+ tgsi_free_tokens(state->shader.tokens);
FREE(state);
}
static void
softpipe_set_constant_buffer(struct pipe_context *pipe,
- uint shader, uint index,
- struct pipe_constant_buffer *cb)
+ enum pipe_shader_type shader, uint index,
+ const struct pipe_constant_buffer *cb)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
struct pipe_resource *constants = cb ? cb->buffer : NULL;
unsigned size;
const void *data;
+ assert(shader < PIPE_SHADER_TYPES);
+
if (cb && cb->user_buffer) {
constants = softpipe_user_buffer_create(pipe->screen,
(void *) cb->user_buffer,
PIPE_BIND_CONSTANT_BUFFER);
}
- size = constants ? constants->width0 : 0;
- data = constants ? softpipe_resource(constants)->data : NULL;
-
- assert(shader < PIPE_SHADER_TYPES);
+ size = cb ? cb->buffer_size : 0;
+ data = constants ? softpipe_resource_data(constants) : NULL;
+ if (data)
+ data = (const char *) data + cb->buffer_offset;
draw_flush(softpipe->draw);
}
}
+static void *
+softpipe_create_compute_state(struct pipe_context *pipe,
+ const struct pipe_compute_state *templ)
+{
+ struct softpipe_context *softpipe = softpipe_context(pipe);
+ const struct tgsi_token *tokens;
+ struct sp_compute_shader *state;
+ if (templ->ir_type != PIPE_SHADER_IR_TGSI)
+ return NULL;
+
+ tokens = templ->prog;
+ /* debug */
+ if (softpipe->dump_cs)
+ tgsi_dump(tokens, 0);
+
+ state = CALLOC_STRUCT(sp_compute_shader);
+
+ state->shader = *templ;
+ state->tokens = tgsi_dup_tokens(tokens);
+ tgsi_scan_shader(state->tokens, &state->info);
+
+ state->max_sampler = state->info.file_max[TGSI_FILE_SAMPLER];
+
+ return state;
+}
+
+static void
+softpipe_bind_compute_state(struct pipe_context *pipe,
+ void *cs)
+{
+ struct softpipe_context *softpipe = softpipe_context(pipe);
+ struct sp_compute_shader *state = (struct sp_compute_shader *)cs;
+ if (softpipe->cs == state)
+ return;
+
+ softpipe->cs = state;
+}
+
+static void
+softpipe_delete_compute_state(struct pipe_context *pipe,
+ void *cs)
+{
+ MAYBE_UNUSED struct softpipe_context *softpipe = softpipe_context(pipe);
+ struct sp_compute_shader *state = (struct sp_compute_shader *)cs;
+
+ assert(softpipe->cs != state);
+ tgsi_free_tokens(state->tokens);
+ FREE(state);
+}
void
softpipe_init_shader_funcs(struct pipe_context *pipe)
pipe->delete_gs_state = softpipe_delete_gs_state;
pipe->set_constant_buffer = softpipe_set_constant_buffer;
+
+ pipe->create_compute_state = softpipe_create_compute_state;
+ pipe->bind_compute_state = softpipe_bind_compute_state;
+ pipe->delete_compute_state = softpipe_delete_compute_state;
}