#include "draw/draw_context.h"
#include "svga_context.h"
-#include "svga_tgsi.h"
#include "svga_hw_reg.h"
#include "svga_cmd.h"
#include "svga_debug.h"
+#include "svga_shader.h"
-static void *
+void *
svga_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
if (!fs)
return NULL;
+ SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATEFS);
+
fs->base.tokens = tgsi_dup_tokens(templ->tokens);
/* Collect basic info that we'll need later:
fs->draw_shader = draw_create_fragment_shader(svga->swtnl.draw, templ);
- if (SVGA_DEBUG & DEBUG_TGSI || 0) {
- debug_printf("%s id: %u, inputs: %u, outputs: %u\n",
- __FUNCTION__, fs->base.id,
- fs->base.info.num_inputs, fs->base.info.num_outputs);
- }
-
+ SVGA_STATS_TIME_POP(svga_sws(svga));
return fs;
}
-static void
+void
svga_bind_fs_state(struct pipe_context *pipe, void *shader)
{
struct svga_fragment_shader *fs = (struct svga_fragment_shader *) shader;
{
struct svga_context *svga = svga_context(pipe);
struct svga_fragment_shader *fs = (struct svga_fragment_shader *) shader;
- struct svga_shader_result *result, *tmp;
- enum pipe_error ret;
+ struct svga_fragment_shader *next_fs;
+ struct svga_shader_variant *variant, *tmp;
svga_hwtnl_flush_retry(svga);
- draw_delete_fragment_shader(svga->swtnl.draw, fs->draw_shader);
+ assert(fs->base.parent == NULL);
- for (result = fs->base.results; result; result = tmp) {
- tmp = result->next;
+ while (fs) {
+ next_fs = (struct svga_fragment_shader *) fs->base.next;
- ret = SVGA3D_DestroyShader(svga->swc, result->id, SVGA3D_SHADERTYPE_PS);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_DestroyShader(svga->swc, result->id,
- SVGA3D_SHADERTYPE_PS);
- assert(ret == PIPE_OK);
- }
+ draw_delete_fragment_shader(svga->swtnl.draw, fs->draw_shader);
- util_bitmask_clear(svga->fs_bm, result->id);
+ for (variant = fs->base.variants; variant; variant = tmp) {
+ tmp = variant->next;
- svga_destroy_shader_result(result);
+ /* Check if deleting currently bound shader */
+ if (variant == svga->state.hw_draw.fs) {
+ SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_PS, NULL));
+ svga->state.hw_draw.fs = NULL;
+ }
- /*
- * Remove stale references to this result to ensure a new result on the
- * same address will be detected as a change.
- */
- if (result == svga->state.hw_draw.fs)
- svga->state.hw_draw.fs = NULL;
- }
+ svga_destroy_shader_variant(svga, variant);
+ }
- FREE((void *)fs->base.tokens);
- FREE(fs);
+ FREE((void *)fs->base.tokens);
+ FREE(fs);
+ fs = next_fs;
+ }
}