*/
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)
struct {
unsigned rendertargets:1;
unsigned texture_samplers:1;
+ unsigned vs:1;
+ unsigned fs:1;
} rebind;
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,
{
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 */
{
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);
util_bitmask_clear(svga->shader_id_bm, variant->id);
}
+end:
FREE((unsigned *)variant->tokens);
FREE(variant);
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
}
+/**
+ * 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;
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;
}
+/**
+ * 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 */
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;
*/
unsigned id;
+ /* GB object buffer containing the bytecode */
+ struct svga_winsys_gb_shader *gb_shader;
+
/** Next variant */
struct svga_shader_variant *next;
};