diff options
-rw-r--r-- | src/gallium/drivers/svga/svga_context.c | 4 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_context.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_draw.c | 14 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_shader.c | 21 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_state.h | 4 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_state_fs.c | 58 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_state_vs.c | 56 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_tgsi.h | 3 |
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; }; |