struct draw_vertex_shader;
struct draw_fragment_shader;
-struct svga_shader_result;
+struct svga_shader_variant;
struct SVGACmdMemory;
struct util_bitmask;
struct tgsi_shader_info info;
- struct svga_shader_result *results;
+ /** Head of linked list of variants */
+ struct svga_shader_variant *variants;
unsigned id; /**< for debugging only */
};
+
struct svga_fragment_shader
{
struct svga_shader base;
int8_t generic_remap_table[MAX_GENERIC_VARYING];
};
+
struct svga_vertex_shader
{
struct svga_shader base;
unsigned ts[SVGA3D_PIXEL_SAMPLERREG_MAX][SVGA3D_TS_MAX];
float cb[PIPE_SHADER_TYPES][SVGA3D_CONSTREG_MAX][4];
- struct svga_shader_result *fs;
- struct svga_shader_result *vs;
+ struct svga_shader_variant *fs;
+ struct svga_shader_variant *vs;
struct svga_hw_view_state views[PIPE_MAX_SAMPLERS];
unsigned num_views;
#define SVGA_NEW_NEED_PIPELINE 0x100000
#define SVGA_NEW_NEED_SWVFETCH 0x200000
#define SVGA_NEW_NEED_SWTNL 0x400000
-#define SVGA_NEW_FS_RESULT 0x800000
-#define SVGA_NEW_VS_RESULT 0x1000000
+#define SVGA_NEW_FS_VARIANT 0x800000
+#define SVGA_NEW_VS_VARIANT 0x1000000
#define SVGA_NEW_TEXTURE_FLAGS 0x4000000
#define SVGA_NEW_STENCIL_REF 0x8000000
{
struct svga_context *svga = svga_context(pipe);
struct svga_fragment_shader *fs = (struct svga_fragment_shader *) shader;
- struct svga_shader_result *result, *tmp;
+ struct svga_shader_variant *variant, *tmp;
enum pipe_error ret;
svga_hwtnl_flush_retry(svga);
draw_delete_fragment_shader(svga->swtnl.draw, fs->draw_shader);
- for (result = fs->base.results; result; result = tmp) {
- tmp = result->next;
+ for (variant = fs->base.variants; variant; variant = tmp) {
+ tmp = variant->next;
- ret = SVGA3D_DestroyShader(svga->swc, result->id, SVGA3D_SHADERTYPE_PS);
+ ret = SVGA3D_DestroyShader(svga->swc, variant->id, SVGA3D_SHADERTYPE_PS);
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
- ret = SVGA3D_DestroyShader(svga->swc, result->id,
+ ret = SVGA3D_DestroyShader(svga->swc, variant->id,
SVGA3D_SHADERTYPE_PS);
assert(ret == PIPE_OK);
}
- util_bitmask_clear(svga->fs_bm, result->id);
+ util_bitmask_clear(svga->fs_bm, variant->id);
- svga_destroy_shader_result(result);
+ svga_destroy_shader_variant(variant);
/*
- * Remove stale references to this result to ensure a new result on the
+ * Remove stale references to this variant to ensure a new variant on the
* same address will be detected as a change.
*/
- if (result == svga->state.hw_draw.fs)
+ if (variant == svga->state.hw_draw.fs)
svga->state.hw_draw.fs = NULL;
}
{
struct svga_context *svga = svga_context(pipe);
struct svga_vertex_shader *vs = (struct svga_vertex_shader *)shader;
- struct svga_shader_result *result, *tmp;
+ struct svga_shader_variant *variant, *tmp;
enum pipe_error ret;
svga_hwtnl_flush_retry(svga);
draw_delete_vertex_shader(svga->swtnl.draw, vs->draw_shader);
- for (result = vs->base.results; result; result = tmp) {
- tmp = result->next;
+ for (variant = vs->base.variants; variant; variant = tmp) {
+ tmp = variant->next;
- ret = SVGA3D_DestroyShader(svga->swc, result->id, SVGA3D_SHADERTYPE_VS);
+ ret = SVGA3D_DestroyShader(svga->swc, variant->id, SVGA3D_SHADERTYPE_VS);
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
- ret = SVGA3D_DestroyShader(svga->swc, result->id,
+ ret = SVGA3D_DestroyShader(svga->swc, variant->id,
SVGA3D_SHADERTYPE_VS);
assert(ret == PIPE_OK);
}
- util_bitmask_clear(svga->vs_bm, result->id);
+ util_bitmask_clear(svga->vs_bm, variant->id);
- svga_destroy_shader_result(result);
+ svga_destroy_shader_variant(variant);
/*
- * Remove stale references to this result to ensure a new result on the
+ * Remove stale references to this variant to ensure a new variant on the
* same address will be detected as a change.
*/
- if (result == svga->state.hw_draw.vs)
+ if (variant == svga->state.hw_draw.vs)
svga->state.hw_draw.vs = NULL;
}
static enum pipe_error
emit_fs_consts(struct svga_context *svga, unsigned dirty)
{
- const struct svga_shader_result *result = svga->state.hw_draw.fs;
+ const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
enum pipe_error ret = PIPE_OK;
ret = emit_consts( svga, PIPE_SHADER_FRAGMENT );
return ret;
/* The internally generated fragment shader for xor blending
- * doesn't have a 'result' struct. It should be fixed to avoid
+ * doesn't have a 'variant' struct. It should be fixed to avoid
* this special case, but work around it with a NULL check:
*/
- if (result) {
- const struct svga_fs_compile_key *key = &result->key.fkey;
+ if (variant) {
+ const struct svga_fs_compile_key *key = &variant->key.fkey;
if (key->num_unnormalized_coords) {
const unsigned offset =
- result->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
+ variant->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
unsigned i;
for (i = 0; i < key->num_textures; i++) {
{
"hw fs params",
(SVGA_NEW_FS_CONST_BUFFER |
- SVGA_NEW_FS_RESULT |
+ SVGA_NEW_FS_VARIANT |
SVGA_NEW_TEXTURE_BINDING),
emit_fs_consts
};
static enum pipe_error
emit_vs_consts(struct svga_context *svga, unsigned dirty)
{
- const struct svga_shader_result *result = svga->state.hw_draw.vs;
+ const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
const struct svga_vs_compile_key *key;
enum pipe_error ret = PIPE_OK;
unsigned offset;
- /* SVGA_NEW_VS_RESULT
+ /* SVGA_NEW_VS_VARIANT
*/
- if (result == NULL)
+ if (variant == NULL)
return PIPE_OK;
- key = &result->key.vkey;
+ key = &variant->key.vkey;
/* SVGA_NEW_VS_CONST_BUFFER
*/
return ret;
/* offset = number of constants in the VS const buffer */
- offset = result->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
+ offset = variant->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
/* SVGA_NEW_VS_PRESCALE
* Put the viewport pre-scale/translate values into the const buffer.
"hw vs params",
(SVGA_NEW_PRESCALE |
SVGA_NEW_VS_CONST_BUFFER |
- SVGA_NEW_VS_RESULT),
+ SVGA_NEW_VS_VARIANT),
emit_vs_consts
};
-static INLINE int compare_fs_keys( const struct svga_fs_compile_key *a,
- const struct svga_fs_compile_key *b )
+static INLINE int
+compare_fs_keys(const struct svga_fs_compile_key *a,
+ const struct svga_fs_compile_key *b)
{
unsigned keysize_a = svga_fs_key_size( a );
unsigned keysize_b = svga_fs_key_size( b );
}
-static struct svga_shader_result *search_fs_key( struct svga_fragment_shader *fs,
- const struct svga_fs_compile_key *key )
+/** Search for a fragment shader variant */
+static struct svga_shader_variant *
+search_fs_key(const struct svga_fragment_shader *fs,
+ const struct svga_fs_compile_key *key)
{
- struct svga_shader_result *result = fs->base.results;
+ struct svga_shader_variant *variant = fs->base.variants;
assert(key);
- for ( ; result; result = result->next) {
- if (compare_fs_keys( key, &result->key.fkey ) == 0)
- return result;
+ for ( ; variant; variant = variant->next) {
+ if (compare_fs_keys( key, &variant->key.fkey ) == 0)
+ return variant;
}
return NULL;
}
-static enum pipe_error compile_fs( struct svga_context *svga,
- struct svga_fragment_shader *fs,
- const struct svga_fs_compile_key *key,
- struct svga_shader_result **out_result )
+/**
+ * Translate TGSI shader into an svga shader variant.
+ */
+static enum pipe_error
+compile_fs(struct svga_context *svga,
+ struct svga_fragment_shader *fs,
+ const struct svga_fs_compile_key *key,
+ struct svga_shader_variant **out_variant)
{
- struct svga_shader_result *result;
+ struct svga_shader_variant *variant;
enum pipe_error ret = PIPE_ERROR;
- result = svga_translate_fragment_program( fs, key );
- if (result == NULL) {
+ variant = svga_translate_fragment_program( fs, key );
+ if (variant == NULL) {
/* some problem during translation, try the dummy shader */
const struct tgsi_token *dummy = get_dummy_fragment_shader();
if (!dummy) {
debug_printf("Failed to compile fragment shader, using dummy shader instead.\n");
FREE((void *) fs->base.tokens);
fs->base.tokens = dummy;
- result = svga_translate_fragment_program(fs, key);
- if (result == NULL) {
+ variant = svga_translate_fragment_program(fs, key);
+ if (variant == NULL) {
ret = PIPE_ERROR;
goto fail;
}
}
- result->id = util_bitmask_add(svga->fs_bm);
- if(result->id == UTIL_BITMASK_INVALID_INDEX) {
+ variant->id = util_bitmask_add(svga->fs_bm);
+ if(variant->id == UTIL_BITMASK_INVALID_INDEX) {
ret = PIPE_ERROR_OUT_OF_MEMORY;
goto fail;
}
ret = SVGA3D_DefineShader(svga->swc,
- result->id,
+ variant->id,
SVGA3D_SHADERTYPE_PS,
- result->tokens,
- result->nr_tokens * sizeof result->tokens[0]);
+ variant->tokens,
+ variant->nr_tokens * sizeof variant->tokens[0]);
if (ret != PIPE_OK)
goto fail;
- *out_result = result;
- result->next = fs->base.results;
- fs->base.results = result;
+ *out_variant = variant;
+ variant->next = fs->base.variants;
+ fs->base.variants = variant;
return PIPE_OK;
fail:
- if (result) {
- if (result->id != UTIL_BITMASK_INVALID_INDEX)
- util_bitmask_clear( svga->fs_bm, result->id );
- svga_destroy_shader_result( result );
+ if (variant) {
+ if (variant->id != UTIL_BITMASK_INVALID_INDEX)
+ util_bitmask_clear( svga->fs_bm, variant->id );
+ svga_destroy_shader_variant( variant );
}
return ret;
}
static enum pipe_error
emit_hw_fs(struct svga_context *svga, unsigned dirty)
{
- struct svga_shader_result *result = NULL;
+ struct svga_shader_variant *variant = NULL;
unsigned id = SVGA3D_INVALID_ID;
enum pipe_error ret = PIPE_OK;
if (ret != PIPE_OK)
return ret;
- result = search_fs_key( fs, &key );
- if (!result) {
- ret = compile_fs( svga, fs, &key, &result );
+ variant = search_fs_key( fs, &key );
+ if (!variant) {
+ ret = compile_fs( svga, fs, &key, &variant );
if (ret != PIPE_OK)
return ret;
}
- assert (result);
- id = result->id;
+ assert (variant);
+ id = variant->id;
assert(id != SVGA3D_INVALID_ID);
- if (result != svga->state.hw_draw.fs) {
+ if (variant != svga->state.hw_draw.fs) {
ret = SVGA3D_SetShader(svga->swc,
SVGA3D_SHADERTYPE_PS,
id );
if (ret != PIPE_OK)
return ret;
- svga->dirty |= SVGA_NEW_FS_RESULT;
- svga->state.hw_draw.fs = result;
+ svga->dirty |= SVGA_NEW_FS_VARIANT;
+ svga->state.hw_draw.fs = variant;
}
return PIPE_OK;
#include "svga_hw_reg.h"
-/***********************************************************************
- */
-
-static INLINE int compare_vs_keys( const struct svga_vs_compile_key *a,
- const struct svga_vs_compile_key *b )
+static INLINE int
+compare_vs_keys(const struct svga_vs_compile_key *a,
+ const struct svga_vs_compile_key *b)
{
unsigned keysize = svga_vs_key_size( a );
return memcmp( a, b, keysize );
}
-static struct svga_shader_result *search_vs_key( struct svga_vertex_shader *vs,
- const struct svga_vs_compile_key *key )
+/** Search for a vertex shader variant */
+static struct svga_shader_variant *
+search_vs_key(const struct svga_vertex_shader *vs,
+ const struct svga_vs_compile_key *key)
{
- struct svga_shader_result *result = vs->base.results;
+ struct svga_shader_variant *variant = vs->base.variants;
assert(key);
- for ( ; result; result = result->next) {
- if (compare_vs_keys( key, &result->key.vkey ) == 0)
- return result;
+ for ( ; variant; variant = variant->next) {
+ if (compare_vs_keys( key, &variant->key.vkey ) == 0)
+ return variant;
}
return NULL;
}
-static enum pipe_error compile_vs( struct svga_context *svga,
- struct svga_vertex_shader *vs,
- const struct svga_vs_compile_key *key,
- struct svga_shader_result **out_result )
+/**
+ * Translate TGSI shader into an svga shader variant.
+ */
+static enum pipe_error
+compile_vs(struct svga_context *svga,
+ struct svga_vertex_shader *vs,
+ const struct svga_vs_compile_key *key,
+ struct svga_shader_variant **out_variant)
{
- struct svga_shader_result *result;
+ struct svga_shader_variant *variant;
enum pipe_error ret = PIPE_ERROR;
- result = svga_translate_vertex_program( vs, key );
- if (result == NULL) {
+ variant = svga_translate_vertex_program( vs, key );
+ if (variant == NULL) {
/* some problem during translation, try the dummy shader */
const struct tgsi_token *dummy = get_dummy_vertex_shader();
if (!dummy) {
debug_printf("Failed to compile vertex shader, using dummy shader instead.\n");
FREE((void *) vs->base.tokens);
vs->base.tokens = dummy;
- result = svga_translate_vertex_program(vs, key);
- if (result == NULL) {
+ variant = svga_translate_vertex_program(vs, key);
+ if (variant == NULL) {
ret = PIPE_ERROR;
goto fail;
}
}
- result->id = util_bitmask_add(svga->vs_bm);
- if(result->id == UTIL_BITMASK_INVALID_INDEX) {
+ variant->id = util_bitmask_add(svga->vs_bm);
+ if(variant->id == UTIL_BITMASK_INVALID_INDEX) {
ret = PIPE_ERROR_OUT_OF_MEMORY;
goto fail;
}
ret = SVGA3D_DefineShader(svga->swc,
- result->id,
+ variant->id,
SVGA3D_SHADERTYPE_VS,
- result->tokens,
- result->nr_tokens * sizeof result->tokens[0]);
+ variant->tokens,
+ variant->nr_tokens * sizeof variant->tokens[0]);
if (ret != PIPE_OK)
goto fail;
- *out_result = result;
- result->next = vs->base.results;
- vs->base.results = result;
+ *out_variant = variant;
+ variant->next = vs->base.variants;
+ vs->base.variants = variant;
return PIPE_OK;
fail:
- if (result) {
- if (result->id != UTIL_BITMASK_INVALID_INDEX)
- util_bitmask_clear( svga->vs_bm, result->id );
- svga_destroy_shader_result( result );
+ if (variant) {
+ if (variant->id != UTIL_BITMASK_INVALID_INDEX)
+ util_bitmask_clear( svga->vs_bm, variant->id );
+ svga_destroy_shader_variant( variant );
}
return ret;
}
static enum pipe_error
emit_hw_vs(struct svga_context *svga, unsigned dirty)
{
- struct svga_shader_result *result = NULL;
+ struct svga_shader_variant *variant = NULL;
unsigned id = SVGA3D_INVALID_ID;
enum pipe_error ret = PIPE_OK;
make_vs_key( svga, &key );
- result = search_vs_key( vs, &key );
- if (!result) {
- ret = compile_vs( svga, vs, &key, &result );
+ variant = search_vs_key( vs, &key );
+ if (!variant) {
+ ret = compile_vs( svga, vs, &key, &variant );
if (ret != PIPE_OK)
return ret;
}
- assert (result);
- id = result->id;
+ assert (variant);
+ id = variant->id;
}
- if (result != svga->state.hw_draw.vs) {
+ if (variant != svga->state.hw_draw.vs) {
ret = SVGA3D_SetShader(svga->swc,
SVGA3D_SHADERTYPE_VS,
id );
if (ret != PIPE_OK)
return ret;
- svga->dirty |= SVGA_NEW_VS_RESULT;
- svga->state.hw_draw.vs = result;
+ svga->dirty |= SVGA_NEW_VS_VARIANT;
+ svga->state.hw_draw.vs = variant;
}
return PIPE_OK;
* can be dynamically grown. Once we've finished and know how large
* it is, it will be copied to a hardware buffer for upload.
*/
-static struct svga_shader_result *
+static struct svga_shader_variant *
svga_tgsi_translate(const struct svga_shader *shader,
const struct svga_compile_key *key, unsigned unit)
{
- struct svga_shader_result *result = NULL;
+ struct svga_shader_variant *variant = NULL;
struct svga_shader_emitter emit;
memset(&emit, 0, sizeof(emit));
goto fail;
}
- result = CALLOC_STRUCT(svga_shader_result);
- if (result == NULL)
+ variant = CALLOC_STRUCT(svga_shader_variant);
+ if (variant == NULL)
goto fail;
- result->shader = shader;
- result->tokens = (const unsigned *) emit.buf;
- result->nr_tokens = (emit.ptr - emit.buf) / sizeof(unsigned);
- memcpy(&result->key, key, sizeof(*key));
- result->id = UTIL_BITMASK_INVALID_INDEX;
+ variant->shader = shader;
+ variant->tokens = (const unsigned *) emit.buf;
+ variant->nr_tokens = (emit.ptr - emit.buf) / sizeof(unsigned);
+ memcpy(&variant->key, key, sizeof(*key));
+ variant->id = UTIL_BITMASK_INVALID_INDEX;
if (SVGA_DEBUG & DEBUG_TGSI) {
debug_printf("#####################################\n");
tgsi_dump(shader->tokens, 0);
if (SVGA_DEBUG & DEBUG_TGSI) {
debug_printf("Shader %u compiled below\n", shader->id);
- svga_shader_dump(result->tokens, result->nr_tokens, FALSE);
+ svga_shader_dump(variant->tokens, variant->nr_tokens, FALSE);
}
debug_printf("#####################################\n");
}
- return result;
+ return variant;
fail:
- FREE(result);
+ FREE(variant);
FREE(emit.buf);
return NULL;
}
-struct svga_shader_result *
+struct svga_shader_variant *
svga_translate_fragment_program(const struct svga_fragment_shader *fs,
const struct svga_fs_compile_key *fkey)
{
}
-struct svga_shader_result *
+struct svga_shader_variant *
svga_translate_vertex_program(const struct svga_vertex_shader *vs,
const struct svga_vs_compile_key *vkey)
{
void
-svga_destroy_shader_result(struct svga_shader_result *result)
+svga_destroy_shader_variant(struct svga_shader_variant *variant)
{
- FREE((unsigned *) result->tokens);
- FREE(result);
+ FREE((unsigned *) variant->tokens);
+ FREE(variant);
}
} tex[PIPE_MAX_SAMPLERS];
};
+/**
+ * Key/index for identifying shader variants.
+ */
struct svga_compile_key {
struct svga_vs_compile_key vkey;
struct svga_fs_compile_key fkey;
/**
* A single TGSI shader may be compiled into different variants of
* SVGA3D shaders depending on the compile key. Each user shader
- * will have a linked list of these results.
+ * will have a linked list of these variants.
*/
-struct svga_shader_result
+struct svga_shader_variant
{
const struct svga_shader *shader;
- /* Parameters used to generate this compilation result:
- */
+ /** Parameters used to generate this variant */
struct svga_compile_key key;
/* Compiled shader tokens:
*/
unsigned id;
- /* Next compilation result:
- */
- struct svga_shader_result *next;
+ /** Next variant */
+ struct svga_shader_variant *next;
};
return (const char *)&key->tex[key->num_textures] - (const char *)key;
}
-struct svga_shader_result *
+struct svga_shader_variant *
svga_translate_fragment_program( const struct svga_fragment_shader *fs,
const struct svga_fs_compile_key *fkey );
-struct svga_shader_result *
+struct svga_shader_variant *
svga_translate_vertex_program( const struct svga_vertex_shader *fs,
const struct svga_vs_compile_key *vkey );
-void svga_destroy_shader_result( struct svga_shader_result *result );
+void
+svga_destroy_shader_variant(struct svga_shader_variant *variant);
unsigned
svga_get_generic_inputs_mask(const struct tgsi_shader_info *info);