summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/svga/svga_context.c4
-rw-r--r--src/gallium/drivers/svga/svga_context.h2
-rw-r--r--src/gallium/drivers/svga/svga_draw.c14
-rw-r--r--src/gallium/drivers/svga/svga_shader.c21
-rw-r--r--src/gallium/drivers/svga/svga_state.h4
-rw-r--r--src/gallium/drivers/svga/svga_state_fs.c58
-rw-r--r--src/gallium/drivers/svga/svga_state_vs.c56
-rw-r--r--src/gallium/drivers/svga/svga_tgsi.h3
8 files changed, 142 insertions, 20 deletions
diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index de769cac95f..4da9a6551f6 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -197,6 +197,10 @@ void svga_context_flush( struct svga_context *svga,
*/
svga->rebind.rendertargets = TRUE;
svga->rebind.texture_samplers = TRUE;
+ if (svga_have_gb_objects(svga)) {
+ svga->rebind.vs = TRUE;
+ svga->rebind.fs = TRUE;
+ }
if (SVGA_DEBUG & DEBUG_SYNC) {
if (fence)
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 71a8eea3fe1..0daab0b3229 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -374,6 +374,8 @@ struct svga_context
struct {
unsigned rendertargets:1;
unsigned texture_samplers:1;
+ unsigned vs:1;
+ unsigned fs:1;
} rebind;
struct svga_hwtnl *hwtnl;
diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c
index 80dbc359a62..fa0cac4a8c4 100644
--- a/src/gallium/drivers/svga/svga_draw.c
+++ b/src/gallium/drivers/svga/svga_draw.c
@@ -213,6 +213,20 @@ svga_hwtnl_flush(struct svga_hwtnl *hwtnl)
}
}
+ if (svga->rebind.vs) {
+ ret = svga_reemit_vs_bindings(svga);
+ if (ret != PIPE_OK) {
+ return ret;
+ }
+ }
+
+ if (svga->rebind.fs) {
+ ret = svga_reemit_fs_bindings(svga);
+ if (ret != PIPE_OK) {
+ return ret;
+ }
+ }
+
SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n",
svga->curr.framebuffer.cbufs[0] ?
svga_surface(svga->curr.framebuffer.cbufs[0])->handle : NULL,
diff --git a/src/gallium/drivers/svga/svga_shader.c b/src/gallium/drivers/svga/svga_shader.c
index 88877b27e98..6b6b441cb82 100644
--- a/src/gallium/drivers/svga/svga_shader.c
+++ b/src/gallium/drivers/svga/svga_shader.c
@@ -43,7 +43,17 @@ svga_define_shader(struct svga_context *svga,
{
unsigned codeLen = variant->nr_tokens * sizeof(variant->tokens[0]);
- {
+ if (svga_have_gb_objects(svga)) {
+ struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
+
+ variant->gb_shader = sws->shader_create(sws, type,
+ variant->tokens, codeLen);
+ if (!variant->gb_shader)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ return PIPE_OK;
+ }
+ else {
enum pipe_error ret;
/* Allocate an integer ID for the shader */
@@ -79,6 +89,14 @@ svga_destroy_shader_variant(struct svga_context *svga,
{
enum pipe_error ret = PIPE_OK;
+ if (svga_have_gb_objects(svga)) {
+ struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
+
+ sws->shader_destroy(sws, variant->gb_shader);
+ variant->gb_shader = NULL;
+ goto end;
+ }
+
/* first try */
if (variant->id != UTIL_BITMASK_INVALID_INDEX) {
ret = SVGA3D_DestroyShader(svga->swc, variant->id, type);
@@ -94,6 +112,7 @@ svga_destroy_shader_variant(struct svga_context *svga,
util_bitmask_clear(svga->shader_id_bm, variant->id);
}
+end:
FREE((unsigned *)variant->tokens);
FREE(variant);
diff --git a/src/gallium/drivers/svga/svga_state.h b/src/gallium/drivers/svga/svga_state.h
index 7051263daf0..3325626a4d1 100644
--- a/src/gallium/drivers/svga/svga_state.h
+++ b/src/gallium/drivers/svga/svga_state.h
@@ -95,4 +95,8 @@ enum pipe_error svga_reemit_framebuffer_bindings( struct svga_context *svga );
enum pipe_error svga_reemit_tss_bindings( struct svga_context *svga );
+enum pipe_error svga_reemit_vs_bindings(struct svga_context *svga);
+
+enum pipe_error svga_reemit_fs_bindings(struct svga_context *svga);
+
#endif
diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c
index 7119a19f0a8..dde739c121d 100644
--- a/src/gallium/drivers/svga/svga_state_fs.c
+++ b/src/gallium/drivers/svga/svga_state_fs.c
@@ -321,13 +321,36 @@ make_fs_key(const struct svga_context *svga,
}
+/**
+ * svga_reemit_fs_bindings - Reemit the fragment shader bindings
+ */
+enum pipe_error
+svga_reemit_fs_bindings(struct svga_context *svga)
+{
+ enum pipe_error ret;
+
+ assert(svga->rebind.fs);
+ assert(svga_have_gb_objects(svga));
+
+ if (!svga->state.hw_draw.fs)
+ return PIPE_OK;
+
+ ret = SVGA3D_SetGBShader(svga->swc, SVGA3D_SHADERTYPE_PS,
+ svga->state.hw_draw.fs->gb_shader);
+ if (ret != PIPE_OK)
+ return ret;
+
+ svga->rebind.fs = FALSE;
+ return PIPE_OK;
+}
+
+
+
static enum pipe_error
emit_hw_fs(struct svga_context *svga, unsigned dirty)
{
struct svga_shader_variant *variant = NULL;
- unsigned id = SVGA3D_INVALID_ID;
enum pipe_error ret = PIPE_OK;
-
struct svga_fragment_shader *fs = svga->curr.fs;
struct svga_fs_compile_key key;
@@ -349,17 +372,30 @@ emit_hw_fs(struct svga_context *svga, unsigned dirty)
return ret;
}
- assert (variant);
- id = variant->id;
-
- assert(id != SVGA3D_INVALID_ID);
+ assert(variant);
if (variant != svga->state.hw_draw.fs) {
- ret = SVGA3D_SetShader(svga->swc,
- SVGA3D_SHADERTYPE_PS,
- id );
- if (ret != PIPE_OK)
- return ret;
+ if (svga_have_gb_objects(svga)) {
+ /*
+ * Bind is necessary here only because pipebuffer_fenced may move
+ * the shader contents around....
+ */
+ ret = SVGA3D_BindGBShader(svga->swc, variant->gb_shader);
+ if (ret != PIPE_OK)
+ return ret;
+
+ ret = SVGA3D_SetGBShader(svga->swc, SVGA3D_SHADERTYPE_PS,
+ variant->gb_shader);
+ if (ret != PIPE_OK)
+ return ret;
+
+ svga->rebind.fs = FALSE;
+ }
+ else {
+ ret = SVGA3D_SetShader(svga->swc, SVGA3D_SHADERTYPE_PS, variant->id);
+ if (ret != PIPE_OK)
+ return ret;
+ }
svga->dirty |= SVGA_NEW_FS_VARIANT;
svga->state.hw_draw.fs = variant;
diff --git a/src/gallium/drivers/svga/svga_state_vs.c b/src/gallium/drivers/svga/svga_state_vs.c
index aaef17ef35f..2f130aec5b4 100644
--- a/src/gallium/drivers/svga/svga_state_vs.c
+++ b/src/gallium/drivers/svga/svga_state_vs.c
@@ -162,12 +162,32 @@ make_vs_key(struct svga_context *svga, struct svga_vs_compile_key *key)
}
+/**
+ * svga_reemit_vs_bindings - Reemit the vertex shader bindings
+ */
+enum pipe_error
+svga_reemit_vs_bindings(struct svga_context *svga)
+{
+ enum pipe_error ret;
+ struct svga_winsys_gb_shader *gbshader =
+ svga->state.hw_draw.vs ? svga->state.hw_draw.vs->gb_shader : NULL;
+
+ assert(svga->rebind.vs);
+ assert(svga_have_gb_objects(svga));
+
+ ret = SVGA3D_SetGBShader(svga->swc, SVGA3D_SHADERTYPE_VS, gbshader);
+ if (ret != PIPE_OK)
+ return ret;
+
+ svga->rebind.vs = FALSE;
+ return PIPE_OK;
+}
+
static enum pipe_error
emit_hw_vs(struct svga_context *svga, unsigned dirty)
{
struct svga_shader_variant *variant = NULL;
- unsigned id = SVGA3D_INVALID_ID;
enum pipe_error ret = PIPE_OK;
/* SVGA_NEW_NEED_SWTNL */
@@ -184,16 +204,36 @@ emit_hw_vs(struct svga_context *svga, unsigned dirty)
return ret;
}
- assert (variant);
- id = variant->id;
+ assert(variant);
}
if (variant != svga->state.hw_draw.vs) {
- ret = SVGA3D_SetShader(svga->swc,
- SVGA3D_SHADERTYPE_VS,
- id );
- if (ret != PIPE_OK)
- return ret;
+ if (svga_have_gb_objects(svga)) {
+ struct svga_winsys_gb_shader *gbshader =
+ variant ? variant->gb_shader : NULL;
+
+ /*
+ * Bind is necessary here only because pipebuffer_fenced may move
+ * the shader contents around....
+ */
+ if (gbshader) {
+ ret = SVGA3D_BindGBShader(svga->swc, gbshader);
+ if (ret != PIPE_OK)
+ return ret;
+ }
+
+ ret = SVGA3D_SetGBShader(svga->swc, SVGA3D_SHADERTYPE_VS, gbshader);
+ if (ret != PIPE_OK)
+ return ret;
+
+ svga->rebind.vs = FALSE;
+ }
+ else {
+ unsigned id = variant ? variant->id : SVGA_ID_INVALID;
+ ret = SVGA3D_SetShader(svga->swc, SVGA3D_SHADERTYPE_VS, id);
+ if (ret != PIPE_OK)
+ return ret;
+ }
svga->dirty |= SVGA_NEW_VS_VARIANT;
svga->state.hw_draw.vs = variant;
diff --git a/src/gallium/drivers/svga/svga_tgsi.h b/src/gallium/drivers/svga/svga_tgsi.h
index 9a0c7b8f41e..4fe88b3b70d 100644
--- a/src/gallium/drivers/svga/svga_tgsi.h
+++ b/src/gallium/drivers/svga/svga_tgsi.h
@@ -106,6 +106,9 @@ struct svga_shader_variant
*/
unsigned id;
+ /* GB object buffer containing the bytecode */
+ struct svga_winsys_gb_shader *gb_shader;
+
/** Next variant */
struct svga_shader_variant *next;
};