summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/ilo/ilo_context.c9
-rw-r--r--src/gallium/drivers/ilo/ilo_context.h71
-rw-r--r--src/gallium/drivers/ilo/ilo_state.c1043
-rw-r--r--src/gallium/drivers/ilo/ilo_state.h86
4 files changed, 1148 insertions, 61 deletions
diff --git a/src/gallium/drivers/ilo/ilo_context.c b/src/gallium/drivers/ilo/ilo_context.c
index 714a9bf72c2..d92b07811ea 100644
--- a/src/gallium/drivers/ilo/ilo_context.c
+++ b/src/gallium/drivers/ilo/ilo_context.c
@@ -34,6 +34,7 @@
#include "ilo_query.h"
#include "ilo_resource.h"
#include "ilo_screen.h"
+#include "ilo_shader.h"
#include "ilo_state.h"
#include "ilo_video.h"
#include "ilo_context.h"
@@ -99,6 +100,8 @@ ilo_context_destroy(struct pipe_context *pipe)
if (ilo->last_cp_bo)
ilo->last_cp_bo->unreference(ilo->last_cp_bo);
+ if (ilo->shader_cache)
+ ilo_shader_cache_destroy(ilo->shader_cache);
if (ilo->cp)
ilo_cp_destroy(ilo->cp);
@@ -170,7 +173,9 @@ ilo_context_create(struct pipe_screen *screen, void *priv)
}
ilo->cp = ilo_cp_create(ilo->winsys, is->has_llc);
- if (!ilo->cp) {
+ ilo->shader_cache = ilo_shader_cache_create(ilo->winsys);
+
+ if (!ilo->cp || !ilo->shader_cache) {
ilo_context_destroy(&ilo->base);
return NULL;
}
@@ -182,6 +187,8 @@ ilo_context_create(struct pipe_screen *screen, void *priv)
ilo_cp_set_hook(ilo->cp, ILO_CP_HOOK_POST_FLUSH,
ilo_context_post_cp_flush, (void *) ilo);
+ ilo->dirty = ILO_DIRTY_ALL;
+
ilo->base.screen = screen;
ilo->base.priv = priv;
diff --git a/src/gallium/drivers/ilo/ilo_context.h b/src/gallium/drivers/ilo/ilo_context.h
index d1632bb1db9..107961d57c6 100644
--- a/src/gallium/drivers/ilo/ilo_context.h
+++ b/src/gallium/drivers/ilo/ilo_context.h
@@ -60,6 +60,11 @@ struct ilo_cp;
struct ilo_screen;
struct ilo_shader_state;
+struct ilo_vertex_element {
+ struct pipe_vertex_element elements[PIPE_MAX_ATTRIBS];
+ unsigned num_elements;
+};
+
struct ilo_context {
struct pipe_context base;
@@ -80,10 +85,32 @@ struct ilo_context {
struct ilo_cp *cp;
struct intel_bo *last_cp_bo;
+ struct ilo_shader_cache *shader_cache;
+
+ uint32_t dirty;
+
+ struct pipe_blend_state *blend;
struct pipe_rasterizer_state *rasterizer;
+ struct pipe_depth_stencil_alpha_state *depth_stencil_alpha;
+ struct ilo_shader_state *fs;
struct ilo_shader_state *vs;
+ struct ilo_shader_state *gs;
+ struct ilo_vertex_element *vertex_elements;
+ struct pipe_blend_color blend_color;
+ struct pipe_stencil_ref stencil_ref;
+ unsigned sample_mask;
+ struct pipe_clip_state clip;
struct pipe_framebuffer_state framebuffer;
+ struct pipe_poly_stipple poly_stipple;
+ struct pipe_scissor_state scissor;
+ struct pipe_viewport_state viewport;
+ struct pipe_index_buffer index_buffer;
+
+ struct {
+ struct pipe_vertex_buffer buffers[PIPE_MAX_ATTRIBS];
+ unsigned num_buffers;
+ } vertex_buffers;
struct {
struct pipe_sampler_state *samplers[ILO_MAX_SAMPLERS];
@@ -95,6 +122,50 @@ struct ilo_context {
unsigned num_views;
} sampler_views[PIPE_SHADER_TYPES];
+ struct {
+ struct pipe_constant_buffer buffers[ILO_MAX_CONST_BUFFERS];
+ unsigned num_buffers;
+ } constant_buffers[PIPE_SHADER_TYPES];
+
+ struct {
+ struct pipe_stream_output_target *targets[ILO_MAX_SO_BUFFERS];
+ unsigned num_targets;
+ unsigned append_bitmask;
+ } stream_output_targets;
+
+ struct {
+ struct pipe_surface *surfaces[PIPE_MAX_SHADER_RESOURCES];
+ unsigned num_surfaces;
+ } shader_resources;
+
+ struct ilo_shader_state *compute;
+
+ struct {
+ struct pipe_surface *surfaces[PIPE_MAX_SHADER_RESOURCES];
+ unsigned num_surfaces;
+ } compute_resources;
+
+ struct {
+ /*
+ * XXX These should not be treated as real resources (and there could be
+ * thousands of them). They should be treated as regions in GLOBAL
+ * resource, which is the only real resource.
+ *
+ * That is, a resource here should instead be
+ *
+ * struct ilo_global_region {
+ * struct pipe_resource base;
+ * int offset;
+ * int size;
+ * };
+ *
+ * and it describes the region [offset, offset + size) in GLOBAL
+ * resource.
+ */
+ struct pipe_resource *resources[PIPE_MAX_SHADER_RESOURCES];
+ uint32_t *handles[PIPE_MAX_SHADER_RESOURCES];
+ unsigned num_resources;
+ } global_binding;
};
static inline struct ilo_context *
diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c
index 0d98cad80b6..8443a2cc9d2 100644
--- a/src/gallium/drivers/ilo/ilo_state.c
+++ b/src/gallium/drivers/ilo/ilo_state.c
@@ -25,73 +25,996 @@
* Chia-I Wu <[email protected]>
*/
+#include "util/u_framebuffer.h"
+#include "util/u_helpers.h"
+
#include "ilo_context.h"
+#include "ilo_shader.h"
#include "ilo_state.h"
+/*
+ * We simply remember the pipe states here and derive HW commands/states from
+ * them later. We could do better by deriving (some of the) HW
+ * commands/states directly.
+ */
+
+static void
+finalize_shader_states(struct ilo_context *ilo)
+{
+ /* this table is ugly and is a burden to maintain.. */
+ const struct {
+ struct ilo_shader_state *state;
+ struct ilo_shader *prev_shader;
+ uint32_t prev_cache_seqno;
+ uint32_t dirty;
+ uint32_t deps;
+ } sh[PIPE_SHADER_TYPES] = {
+ [PIPE_SHADER_VERTEX] = {
+ .state = ilo->vs,
+ .prev_shader = (ilo->vs) ? ilo->vs->shader : NULL,
+ .prev_cache_seqno = (ilo->vs) ? ilo->vs->shader->cache_seqno : 0,
+ .dirty = ILO_DIRTY_VS,
+ .deps = ILO_DIRTY_VERTEX_SAMPLER_VIEWS |
+ ILO_DIRTY_RASTERIZER,
+ },
+ [PIPE_SHADER_FRAGMENT] = {
+ .state = ilo->fs,
+ .prev_shader = (ilo->fs) ? ilo->fs->shader : NULL,
+ .prev_cache_seqno = (ilo->fs) ? ilo->fs->shader->cache_seqno : 0,
+ .dirty = ILO_DIRTY_FS,
+ .deps = ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS |
+ ILO_DIRTY_RASTERIZER |
+ ILO_DIRTY_FRAMEBUFFER,
+ },
+ [PIPE_SHADER_GEOMETRY] = {
+ .state = ilo->gs,
+ .prev_shader = (ilo->gs) ? ilo->gs->shader : NULL,
+ .prev_cache_seqno = (ilo->gs) ? ilo->gs->shader->cache_seqno : 0,
+ .dirty = ILO_DIRTY_GS,
+ .deps = ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS |
+ ILO_DIRTY_VS |
+ ILO_DIRTY_RASTERIZER,
+ },
+ [PIPE_SHADER_COMPUTE] = {
+ .state = NULL,
+ .prev_shader = NULL,
+ .prev_cache_seqno = 0,
+ .dirty = 0,
+ .deps = 0,
+ },
+ };
+ struct ilo_shader *shaders[PIPE_SHADER_TYPES];
+ int num_shaders = 0, i;
+
+ for (i = 0; i < PIPE_SHADER_TYPES; i++) {
+ /* no state bound */
+ if (!sh[i].state)
+ continue;
+
+ /* switch variant if the shader or the states it depends on changed */
+ if (ilo->dirty & (sh[i].dirty | sh[i].deps)) {
+ struct ilo_shader_variant variant;
+
+ ilo_shader_variant_init(&variant, &sh[i].state->info, ilo);
+ ilo_shader_state_use_variant(sh[i].state, &variant);
+ }
+
+ shaders[num_shaders++] = sh[i].state->shader;
+ }
+
+ ilo_shader_cache_set(ilo->shader_cache, shaders, num_shaders);
+
+ for (i = 0; i < PIPE_SHADER_TYPES; i++) {
+ /* no state bound */
+ if (!sh[i].state)
+ continue;
+
+ /*
+ * mark the shader state dirty if
+ *
+ * - a new variant is selected, or
+ * - the kernel is uploaded to a different bo
+ */
+ if (sh[i].state->shader != sh[i].prev_shader ||
+ sh[i].state->shader->cache_seqno != sh[i].prev_cache_seqno)
+ ilo->dirty |= sh[i].dirty;
+ }
+}
+
+static void
+finalize_constant_buffers(struct ilo_context *ilo)
+{
+ int sh;
+
+ if (!(ilo->dirty & ILO_DIRTY_CONSTANT_BUFFER))
+ return;
+
+ for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
+ int last_cbuf = Elements(ilo->constant_buffers[sh].buffers) - 1;
+
+ /* find the last cbuf */
+ while (last_cbuf >= 0 &&
+ !ilo->constant_buffers[sh].buffers[last_cbuf].buffer)
+ last_cbuf--;
+
+ ilo->constant_buffers[sh].num_buffers = last_cbuf + 1;
+ }
+}
+
+/**
+ * Finalize states. Some states depend on other states and are
+ * incomplete/invalid until finalized.
+ */
+void
+ilo_finalize_states(struct ilo_context *ilo)
+{
+ finalize_shader_states(ilo);
+ finalize_constant_buffers(ilo);
+}
+
+static void *
+ilo_create_blend_state(struct pipe_context *pipe,
+ const struct pipe_blend_state *state)
+{
+ struct pipe_blend_state *blend;
+
+ blend = MALLOC_STRUCT(pipe_blend_state);
+ assert(blend);
+
+ *blend = *state;
+
+ return blend;
+}
+
+static void
+ilo_bind_blend_state(struct pipe_context *pipe, void *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->blend = state;
+
+ ilo->dirty |= ILO_DIRTY_BLEND;
+}
+
+static void
+ilo_delete_blend_state(struct pipe_context *pipe, void *state)
+{
+ FREE(state);
+}
+
+static void *
+ilo_create_sampler_state(struct pipe_context *pipe,
+ const struct pipe_sampler_state *state)
+{
+ struct pipe_sampler_state *sampler;
+
+ sampler = MALLOC_STRUCT(pipe_sampler_state);
+ assert(sampler);
+
+ *sampler = *state;
+
+ return sampler;
+}
+
+static void
+bind_samplers(struct ilo_context *ilo,
+ unsigned shader, unsigned start, unsigned count,
+ void **samplers, bool unbind_old)
+{
+ struct pipe_sampler_state **dst = ilo->samplers[shader].samplers;
+ unsigned i;
+
+ assert(start + count <= Elements(ilo->samplers[shader].samplers));
+
+ if (unbind_old) {
+ if (!samplers) {
+ start = 0;
+ count = 0;
+ }
+
+ for (i = 0; i < start; i++)
+ dst[i] = NULL;
+ for (; i < start + count; i++)
+ dst[i] = samplers[i - start];
+ for (; i < ilo->samplers[shader].num_samplers; i++)
+ dst[i] = NULL;
+
+ ilo->samplers[shader].num_samplers = start + count;
+
+ return;
+ }
+
+ dst += start;
+ if (samplers) {
+ for (i = 0; i < count; i++)
+ dst[i] = samplers[i];
+ }
+ else {
+ for (i = 0; i < count; i++)
+ dst[i] = NULL;
+ }
+
+ if (ilo->samplers[shader].num_samplers <= start + count) {
+ count += start;
+
+ while (count > 0 && !ilo->samplers[shader].samplers[count - 1])
+ count--;
+
+ ilo->samplers[shader].num_samplers = count;
+ }
+}
+
+static void
+ilo_bind_fragment_sampler_states(struct pipe_context *pipe,
+ unsigned num_samplers,
+ void **samplers)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ bind_samplers(ilo, PIPE_SHADER_FRAGMENT, 0, num_samplers, samplers, true);
+ ilo->dirty |= ILO_DIRTY_FRAGMENT_SAMPLERS;
+}
+
+static void
+ilo_bind_vertex_sampler_states(struct pipe_context *pipe,
+ unsigned num_samplers,
+ void **samplers)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ bind_samplers(ilo, PIPE_SHADER_VERTEX, 0, num_samplers, samplers, true);
+ ilo->dirty |= ILO_DIRTY_VERTEX_SAMPLERS;
+}
+
+static void
+ilo_bind_geometry_sampler_states(struct pipe_context *pipe,
+ unsigned num_samplers,
+ void **samplers)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ bind_samplers(ilo, PIPE_SHADER_GEOMETRY, 0, num_samplers, samplers, true);
+ ilo->dirty |= ILO_DIRTY_GEOMETRY_SAMPLERS;
+}
+
+static void
+ilo_bind_compute_sampler_states(struct pipe_context *pipe,
+ unsigned start_slot,
+ unsigned num_samplers,
+ void **samplers)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ bind_samplers(ilo, PIPE_SHADER_COMPUTE,
+ start_slot, num_samplers, samplers, false);
+ ilo->dirty |= ILO_DIRTY_COMPUTE_SAMPLERS;
+}
+
+static void
+ilo_delete_sampler_state(struct pipe_context *pipe, void *state)
+{
+ FREE(state);
+}
+
+static void *
+ilo_create_rasterizer_state(struct pipe_context *pipe,
+ const struct pipe_rasterizer_state *state)
+{
+ struct pipe_rasterizer_state *rast;
+
+ rast = MALLOC_STRUCT(pipe_rasterizer_state);
+ assert(rast);
+
+ *rast = *state;
+
+ return rast;
+}
+
+static void
+ilo_bind_rasterizer_state(struct pipe_context *pipe, void *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->rasterizer = state;
+
+ ilo->dirty |= ILO_DIRTY_RASTERIZER;
+}
+
+static void
+ilo_delete_rasterizer_state(struct pipe_context *pipe, void *state)
+{
+ FREE(state);
+}
+
+static void *
+ilo_create_depth_stencil_alpha_state(struct pipe_context *pipe,
+ const struct pipe_depth_stencil_alpha_state *state)
+{
+ struct pipe_depth_stencil_alpha_state *dsa;
+
+ dsa = MALLOC_STRUCT(pipe_depth_stencil_alpha_state);
+ assert(dsa);
+
+ *dsa = *state;
+
+ return dsa;
+}
+
+static void
+ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->depth_stencil_alpha = state;
+
+ ilo->dirty |= ILO_DIRTY_DEPTH_STENCIL_ALPHA;
+}
+
+static void
+ilo_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
+{
+ FREE(state);
+}
+
+static void *
+ilo_create_fs_state(struct pipe_context *pipe,
+ const struct pipe_shader_state *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+ return ilo_shader_state_create(ilo, PIPE_SHADER_FRAGMENT, state);
+}
+
+static void
+ilo_bind_fs_state(struct pipe_context *pipe, void *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->fs = state;
+
+ ilo->dirty |= ILO_DIRTY_FS;
+}
+
+static void
+ilo_delete_fs_state(struct pipe_context *pipe, void *state)
+{
+ struct ilo_shader_state *fs = (struct ilo_shader_state *) state;
+ ilo_shader_state_destroy(fs);
+}
+
+static void *
+ilo_create_vs_state(struct pipe_context *pipe,
+ const struct pipe_shader_state *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+ return ilo_shader_state_create(ilo, PIPE_SHADER_VERTEX, state);
+}
+
+static void
+ilo_bind_vs_state(struct pipe_context *pipe, void *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->vs = state;
+
+ ilo->dirty |= ILO_DIRTY_VS;
+}
+
+static void
+ilo_delete_vs_state(struct pipe_context *pipe, void *state)
+{
+ struct ilo_shader_state *vs = (struct ilo_shader_state *) state;
+ ilo_shader_state_destroy(vs);
+}
+
+static void *
+ilo_create_gs_state(struct pipe_context *pipe,
+ const struct pipe_shader_state *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+ return ilo_shader_state_create(ilo, PIPE_SHADER_GEOMETRY, state);
+}
+
+static void
+ilo_bind_gs_state(struct pipe_context *pipe, void *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->gs = state;
+
+ ilo->dirty |= ILO_DIRTY_GS;
+}
+
+static void
+ilo_delete_gs_state(struct pipe_context *pipe, void *state)
+{
+ struct ilo_shader_state *gs = (struct ilo_shader_state *) state;
+ ilo_shader_state_destroy(gs);
+}
+
+static void *
+ilo_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *elements)
+{
+ struct ilo_vertex_element *velem;
+
+ velem = MALLOC_STRUCT(ilo_vertex_element);
+ assert(velem);
+
+ memcpy(velem->elements, elements, sizeof(*elements) * num_elements);
+ velem->num_elements = num_elements;
+
+ return velem;
+}
+
+static void
+ilo_bind_vertex_elements_state(struct pipe_context *pipe, void *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->vertex_elements = state;
+
+ ilo->dirty |= ILO_DIRTY_VERTEX_ELEMENTS;
+}
+
+static void
+ilo_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
+{
+ FREE(state);
+}
+
+static void
+ilo_set_blend_color(struct pipe_context *pipe,
+ const struct pipe_blend_color *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->blend_color = *state;
+
+ ilo->dirty |= ILO_DIRTY_BLEND_COLOR;
+}
+
+static void
+ilo_set_stencil_ref(struct pipe_context *pipe,
+ const struct pipe_stencil_ref *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->stencil_ref = *state;
+
+ ilo->dirty |= ILO_DIRTY_STENCIL_REF;
+}
+
+static void
+ilo_set_sample_mask(struct pipe_context *pipe,
+ unsigned sample_mask)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->sample_mask = sample_mask;
+
+ ilo->dirty |= ILO_DIRTY_SAMPLE_MASK;
+}
+
+static void
+ilo_set_clip_state(struct pipe_context *pipe,
+ const struct pipe_clip_state *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->clip = *state;
+
+ ilo->dirty |= ILO_DIRTY_CLIP;
+}
+
+static void
+ilo_set_constant_buffer(struct pipe_context *pipe,
+ uint shader, uint index,
+ struct pipe_constant_buffer *buf)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+ struct pipe_constant_buffer *cbuf;
+
+ assert(shader < Elements(ilo->constant_buffers));
+ assert(index < Elements(ilo->constant_buffers[shader].buffers));
+
+ cbuf = &ilo->constant_buffers[shader].buffers[index];
+
+ pipe_resource_reference(&cbuf->buffer, NULL);
+
+ if (buf) {
+ pipe_resource_reference(&cbuf->buffer, buf->buffer);
+ cbuf->buffer_offset = buf->buffer_offset;
+ cbuf->buffer_size = buf->buffer_size;
+ cbuf->user_buffer = buf->user_buffer;
+ }
+ else {
+ cbuf->buffer_offset = 0;
+ cbuf->buffer_size = 0;
+ cbuf->user_buffer = 0;
+ }
+
+ /* the correct value will be set in ilo_finalize_states() */
+ ilo->constant_buffers[shader].num_buffers = 0;
+
+ ilo->dirty |= ILO_DIRTY_CONSTANT_BUFFER;
+}
+
+static void
+ilo_set_framebuffer_state(struct pipe_context *pipe,
+ const struct pipe_framebuffer_state *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ util_copy_framebuffer_state(&ilo->framebuffer, state);
+
+ ilo->dirty |= ILO_DIRTY_FRAMEBUFFER;
+}
+
+static void
+ilo_set_polygon_stipple(struct pipe_context *pipe,
+ const struct pipe_poly_stipple *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->poly_stipple = *state;
+
+ ilo->dirty |= ILO_DIRTY_POLY_STIPPLE;
+}
+
+static void
+ilo_set_scissor_state(struct pipe_context *pipe,
+ const struct pipe_scissor_state *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->scissor = *state;
+
+ ilo->dirty |= ILO_DIRTY_SCISSOR;
+}
+
+static void
+ilo_set_viewport_state(struct pipe_context *pipe,
+ const struct pipe_viewport_state *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->viewport = *state;
+
+ ilo->dirty |= ILO_DIRTY_VIEWPORT;
+}
+
+static void
+set_sampler_views(struct ilo_context *ilo,
+ unsigned shader, unsigned start, unsigned count,
+ struct pipe_sampler_view **views, bool unset_old)
+{
+ struct pipe_sampler_view **dst = ilo->sampler_views[shader].views;
+ unsigned i;
+
+ assert(start + count <= Elements(ilo->sampler_views[shader].views));
+
+ if (unset_old) {
+ if (!views) {
+ start = 0;
+ count = 0;
+ }
+
+ for (i = 0; i < start; i++)
+ pipe_sampler_view_reference(&dst[i], NULL);
+ for (; i < start + count; i++)
+ pipe_sampler_view_reference(&dst[i], views[i - start]);
+ for (; i < ilo->sampler_views[shader].num_views; i++)
+ pipe_sampler_view_reference(&dst[i], NULL);
+
+ ilo->sampler_views[shader].num_views = start + count;
+
+ return;
+ }
+
+ dst += start;
+ if (views) {
+ for (i = 0; i < count; i++)
+ pipe_sampler_view_reference(&dst[i], views[i]);
+ }
+ else {
+ for (i = 0; i < count; i++)
+ pipe_sampler_view_reference(&dst[i], NULL);
+ }
+
+ if (ilo->sampler_views[shader].num_views <= start + count) {
+ count += start;
+
+ while (count > 0 && !ilo->sampler_views[shader].views[count - 1])
+ count--;
+
+ ilo->sampler_views[shader].num_views = count;
+ }
+}
+
+static void
+ilo_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned num_views,
+ struct pipe_sampler_view **views)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ set_sampler_views(ilo, PIPE_SHADER_FRAGMENT, 0, num_views, views, true);
+ ilo->dirty |= ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS;
+}
+
+static void
+ilo_set_vertex_sampler_views(struct pipe_context *pipe,
+ unsigned num_views,
+ struct pipe_sampler_view **views)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ set_sampler_views(ilo, PIPE_SHADER_VERTEX, 0, num_views, views, true);
+ ilo->dirty |= ILO_DIRTY_VERTEX_SAMPLER_VIEWS;
+}
+
+static void
+ilo_set_geometry_sampler_views(struct pipe_context *pipe,
+ unsigned num_views,
+ struct pipe_sampler_view **views)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ set_sampler_views(ilo, PIPE_SHADER_GEOMETRY, 0, num_views, views, true);
+ ilo->dirty |= ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS;
+}
+
+static void
+ilo_set_compute_sampler_views(struct pipe_context *pipe,
+ unsigned start_slot, unsigned num_views,
+ struct pipe_sampler_view **views)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ set_sampler_views(ilo, PIPE_SHADER_COMPUTE,
+ start_slot, num_views, views, false);
+
+ ilo->dirty |= ILO_DIRTY_COMPUTE_SAMPLER_VIEWS;
+}
+
+static void
+ilo_set_shader_resources(struct pipe_context *pipe,
+ unsigned start, unsigned count,
+ struct pipe_surface **surfaces)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+ struct pipe_surface **dst = ilo->shader_resources.surfaces;
+ unsigned i;
+
+ assert(start + count <= Elements(ilo->shader_resources.surfaces));
+
+ dst += start;
+ if (surfaces) {
+ for (i = 0; i < count; i++)
+ pipe_surface_reference(&dst[i], surfaces[i]);
+ }
+ else {
+ for (i = 0; i < count; i++)
+ pipe_surface_reference(&dst[i], NULL);
+ }
+
+ if (ilo->shader_resources.num_surfaces <= start + count) {
+ count += start;
+
+ while (count > 0 && !ilo->shader_resources.surfaces[count - 1])
+ count--;
+
+ ilo->shader_resources.num_surfaces = count;
+ }
+
+ ilo->dirty |= ILO_DIRTY_SHADER_RESOURCES;
+}
+
+static void
+ilo_set_vertex_buffers(struct pipe_context *pipe,
+ unsigned start_slot, unsigned num_buffers,
+ const struct pipe_vertex_buffer *buffers)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ util_set_vertex_buffers_count(ilo->vertex_buffers.buffers,
+ &ilo->vertex_buffers.num_buffers, buffers, start_slot, num_buffers);
+
+ ilo->dirty |= ILO_DIRTY_VERTEX_BUFFERS;
+}
+
+static void
+ilo_set_index_buffer(struct pipe_context *pipe,
+ const struct pipe_index_buffer *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ if (state) {
+ ilo->index_buffer.index_size = state->index_size;
+ ilo->index_buffer.offset = state->offset;
+ pipe_resource_reference(&ilo->index_buffer.buffer, state->buffer);
+ ilo->index_buffer.user_buffer = state->user_buffer;
+ }
+ else {
+ ilo->index_buffer.index_size = 0;
+ ilo->index_buffer.offset = 0;
+ pipe_resource_reference(&ilo->index_buffer.buffer, NULL);
+ ilo->index_buffer.user_buffer = NULL;
+ }
+
+ ilo->dirty |= ILO_DIRTY_INDEX_BUFFER;
+}
+
+static struct pipe_stream_output_target *
+ilo_create_stream_output_target(struct pipe_context *pipe,
+ struct pipe_resource *res,
+ unsigned buffer_offset,
+ unsigned buffer_size)
+{
+ struct pipe_stream_output_target *target;
+
+ target = MALLOC_STRUCT(pipe_stream_output_target);
+ assert(target);
+
+ pipe_reference_init(&target->reference, 1);
+ target->buffer = NULL;
+ pipe_resource_reference(&target->buffer, res);
+ target->context = pipe;
+ target->buffer_offset = buffer_offset;
+ target->buffer_size = buffer_size;
+
+ return target;
+}
+
+static void
+ilo_set_stream_output_targets(struct pipe_context *pipe,
+ unsigned num_targets,
+ struct pipe_stream_output_target **targets,
+ unsigned append_bitmask)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+ unsigned i;
+
+ if (!targets)
+ num_targets = 0;
+
+ for (i = 0; i < num_targets; i++) {
+ pipe_so_target_reference(&ilo->stream_output_targets.targets[i],
+ targets[i]);
+ }
+ for (; i < ilo->stream_output_targets.num_targets; i++)
+ pipe_so_target_reference(&ilo->stream_output_targets.targets[i], NULL);
+
+ ilo->stream_output_targets.num_targets = num_targets;
+ ilo->stream_output_targets.append_bitmask = append_bitmask;
+
+ ilo->dirty |= ILO_DIRTY_STREAM_OUTPUT_TARGETS;
+}
+
+static void
+ilo_stream_output_target_destroy(struct pipe_context *pipe,
+ struct pipe_stream_output_target *target)
+{
+ pipe_resource_reference(&target->buffer, NULL);
+ FREE(target);
+}
+
+static struct pipe_sampler_view *
+ilo_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_resource *res,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view;
+
+ view = MALLOC_STRUCT(pipe_sampler_view);
+ assert(view);
+
+ *view = *templ;
+ pipe_reference_init(&view->reference, 1);
+ view->texture = NULL;
+ pipe_resource_reference(&view->texture, res);
+ view->context = pipe;
+
+ return view;
+}
+
+static void
+ilo_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_resource_reference(&view->texture, NULL);
+ FREE(view);
+}
+
+static struct pipe_surface *
+ilo_create_surface(struct pipe_context *pipe,
+ struct pipe_resource *res,
+ const struct pipe_surface *templ)
+{
+ struct pipe_surface *surface;
+
+ surface = MALLOC_STRUCT(pipe_surface);
+ assert(surface);
+
+ *surface = *templ;
+ pipe_reference_init(&surface->reference, 1);
+ surface->texture = NULL;
+ pipe_resource_reference(&surface->texture, res);
+
+ surface->context = pipe;
+ surface->width = u_minify(res->width0, surface->u.tex.level);
+ surface->height = u_minify(res->height0, surface->u.tex.level);
+
+ return surface;
+}
+
+static void
+ilo_surface_destroy(struct pipe_context *pipe,
+ struct pipe_surface *surface)
+{
+ pipe_resource_reference(&surface->texture, NULL);
+ FREE(surface);
+}
+
+static void *
+ilo_create_compute_state(struct pipe_context *pipe,
+ const struct pipe_compute_state *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+ return ilo_shader_state_create(ilo, PIPE_SHADER_COMPUTE, state);
+}
+
+static void
+ilo_bind_compute_state(struct pipe_context *pipe, void *state)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+
+ ilo->compute = state;
+
+ ilo->dirty |= ILO_DIRTY_COMPUTE;
+}
+
+static void
+ilo_delete_compute_state(struct pipe_context *pipe, void *state)
+{
+ struct ilo_shader_state *cs = (struct ilo_shader_state *) state;
+ ilo_shader_state_destroy(cs);
+}
+
+static void
+ilo_set_compute_resources(struct pipe_context *pipe,
+ unsigned start, unsigned count,
+ struct pipe_surface **surfaces)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+ struct pipe_surface **dst = ilo->compute_resources.surfaces;
+ unsigned i;
+
+ assert(start + count <= Elements(ilo->compute_resources.surfaces));
+
+ dst += start;
+ if (surfaces) {
+ for (i = 0; i < count; i++)
+ pipe_surface_reference(&dst[i], surfaces[i]);
+ }
+ else {
+ for (i = 0; i < count; i++)
+ pipe_surface_reference(&dst[i], NULL);
+ }
+
+ if (ilo->compute_resources.num_surfaces <= start + count) {
+ count += start;
+
+ while (count > 0 && !ilo->compute_resources.surfaces[count - 1])
+ count--;
+
+ ilo->compute_resources.num_surfaces = count;
+ }
+
+ ilo->dirty |= ILO_DIRTY_COMPUTE_RESOURCES;
+}
+
+static void
+ilo_set_global_binding(struct pipe_context *pipe,
+ unsigned start, unsigned count,
+ struct pipe_resource **resources,
+ uint32_t **handles)
+{
+ struct ilo_context *ilo = ilo_context(pipe);
+ struct pipe_resource **dst = ilo->global_binding.resources;
+ unsigned i;
+
+ assert(start + count <= Elements(ilo->global_binding.resources));
+
+ dst += start;
+ if (resources) {
+ for (i = 0; i < count; i++)
+ pipe_resource_reference(&dst[i], resources[i]);
+ }
+ else {
+ for (i = 0; i < count; i++)
+ pipe_resource_reference(&dst[i], NULL);
+ }
+
+ if (ilo->global_binding.num_resources <= start + count) {
+ count += start;
+
+ while (count > 0 && !ilo->global_binding.resources[count - 1])
+ count--;
+
+ ilo->global_binding.num_resources = count;
+ }
+
+ ilo->dirty |= ILO_DIRTY_GLOBAL_BINDING;
+}
+
/**
* Initialize state-related functions.
*/
void
ilo_init_state_functions(struct ilo_context *ilo)
{
- ilo->base.create_blend_state = NULL;
- ilo->base.bind_blend_state = NULL;
- ilo->base.delete_blend_state = NULL;
- ilo->base.create_sampler_state = NULL;
- ilo->base.bind_fragment_sampler_states = NULL;
- ilo->base.bind_vertex_sampler_states = NULL;
- ilo->base.bind_geometry_sampler_states = NULL;
- ilo->base.bind_compute_sampler_states = NULL;
- ilo->base.delete_sampler_state = NULL;
- ilo->base.create_rasterizer_state = NULL;
- ilo->base.bind_rasterizer_state = NULL;
- ilo->base.delete_rasterizer_state = NULL;
- ilo->base.create_depth_stencil_alpha_state = NULL;
- ilo->base.bind_depth_stencil_alpha_state = NULL;
- ilo->base.delete_depth_stencil_alpha_state = NULL;
- ilo->base.create_fs_state = NULL;
- ilo->base.bind_fs_state = NULL;
- ilo->base.delete_fs_state = NULL;
- ilo->base.create_vs_state = NULL;
- ilo->base.bind_vs_state = NULL;
- ilo->base.delete_vs_state = NULL;
- ilo->base.create_gs_state = NULL;
- ilo->base.bind_gs_state = NULL;
- ilo->base.delete_gs_state = NULL;
- ilo->base.create_vertex_elements_state = NULL;
- ilo->base.bind_vertex_elements_state = NULL;
- ilo->base.delete_vertex_elements_state = NULL;
-
- ilo->base.set_blend_color = NULL;
- ilo->base.set_stencil_ref = NULL;
- ilo->base.set_sample_mask = NULL;
- ilo->base.set_clip_state = NULL;
- ilo->base.set_constant_buffer = NULL;
- ilo->base.set_framebuffer_state = NULL;
- ilo->base.set_polygon_stipple = NULL;
- ilo->base.set_scissor_state = NULL;
- ilo->base.set_viewport_state = NULL;
- ilo->base.set_fragment_sampler_views = NULL;
- ilo->base.set_vertex_sampler_views = NULL;
- ilo->base.set_geometry_sampler_views = NULL;
- ilo->base.set_compute_sampler_views = NULL;
- ilo->base.set_shader_resources = NULL;
- ilo->base.set_vertex_buffers = NULL;
- ilo->base.set_index_buffer = NULL;
-
- ilo->base.create_stream_output_target = NULL;
- ilo->base.stream_output_target_destroy = NULL;
- ilo->base.set_stream_output_targets = NULL;
-
- ilo->base.create_sampler_view = NULL;
- ilo->base.sampler_view_destroy = NULL;
-
- ilo->base.create_surface = NULL;
- ilo->base.surface_destroy = NULL;
-
- ilo->base.create_compute_state = NULL;
- ilo->base.bind_compute_state = NULL;
- ilo->base.delete_compute_state = NULL;
- ilo->base.set_compute_resources = NULL;
- ilo->base.set_global_binding = NULL;
+ STATIC_ASSERT(ILO_STATE_COUNT <= 32);
+
+ ilo->base.create_blend_state = ilo_create_blend_state;
+ ilo->base.bind_blend_state = ilo_bind_blend_state;
+ ilo->base.delete_blend_state = ilo_delete_blend_state;
+ ilo->base.create_sampler_state = ilo_create_sampler_state;
+ ilo->base.bind_fragment_sampler_states = ilo_bind_fragment_sampler_states;
+ ilo->base.bind_vertex_sampler_states = ilo_bind_vertex_sampler_states;
+ ilo->base.bind_geometry_sampler_states = ilo_bind_geometry_sampler_states;
+ ilo->base.bind_compute_sampler_states = ilo_bind_compute_sampler_states;
+ ilo->base.delete_sampler_state = ilo_delete_sampler_state;
+ ilo->base.create_rasterizer_state = ilo_create_rasterizer_state;
+ ilo->base.bind_rasterizer_state = ilo_bind_rasterizer_state;
+ ilo->base.delete_rasterizer_state = ilo_delete_rasterizer_state;
+ ilo->base.create_depth_stencil_alpha_state = ilo_create_depth_stencil_alpha_state;
+ ilo->base.bind_depth_stencil_alpha_state = ilo_bind_depth_stencil_alpha_state;
+ ilo->base.delete_depth_stencil_alpha_state = ilo_delete_depth_stencil_alpha_state;
+ ilo->base.create_fs_state = ilo_create_fs_state;
+ ilo->base.bind_fs_state = ilo_bind_fs_state;
+ ilo->base.delete_fs_state = ilo_delete_fs_state;
+ ilo->base.create_vs_state = ilo_create_vs_state;
+ ilo->base.bind_vs_state = ilo_bind_vs_state;
+ ilo->base.delete_vs_state = ilo_delete_vs_state;
+ ilo->base.create_gs_state = ilo_create_gs_state;
+ ilo->base.bind_gs_state = ilo_bind_gs_state;
+ ilo->base.delete_gs_state = ilo_delete_gs_state;
+ ilo->base.create_vertex_elements_state = ilo_create_vertex_elements_state;
+ ilo->base.bind_vertex_elements_state = ilo_bind_vertex_elements_state;
+ ilo->base.delete_vertex_elements_state = ilo_delete_vertex_elements_state;
+
+ ilo->base.set_blend_color = ilo_set_blend_color;
+ ilo->base.set_stencil_ref = ilo_set_stencil_ref;
+ ilo->base.set_sample_mask = ilo_set_sample_mask;
+ ilo->base.set_clip_state = ilo_set_clip_state;
+ ilo->base.set_constant_buffer = ilo_set_constant_buffer;
+ ilo->base.set_framebuffer_state = ilo_set_framebuffer_state;
+ ilo->base.set_polygon_stipple = ilo_set_polygon_stipple;
+ ilo->base.set_scissor_state = ilo_set_scissor_state;
+ ilo->base.set_viewport_state = ilo_set_viewport_state;
+ ilo->base.set_fragment_sampler_views = ilo_set_fragment_sampler_views;
+ ilo->base.set_vertex_sampler_views = ilo_set_vertex_sampler_views;
+ ilo->base.set_geometry_sampler_views = ilo_set_geometry_sampler_views;
+ ilo->base.set_compute_sampler_views = ilo_set_compute_sampler_views;
+ ilo->base.set_shader_resources = ilo_set_shader_resources;
+ ilo->base.set_vertex_buffers = ilo_set_vertex_buffers;
+ ilo->base.set_index_buffer = ilo_set_index_buffer;
+
+ ilo->base.create_stream_output_target = ilo_create_stream_output_target;
+ ilo->base.stream_output_target_destroy = ilo_stream_output_target_destroy;
+ ilo->base.set_stream_output_targets = ilo_set_stream_output_targets;
+
+ ilo->base.create_sampler_view = ilo_create_sampler_view;
+ ilo->base.sampler_view_destroy = ilo_sampler_view_destroy;
+
+ ilo->base.create_surface = ilo_create_surface;
+ ilo->base.surface_destroy = ilo_surface_destroy;
+
+ ilo->base.create_compute_state = ilo_create_compute_state;
+ ilo->base.bind_compute_state = ilo_bind_compute_state;
+ ilo->base.delete_compute_state = ilo_delete_compute_state;
+ ilo->base.set_compute_resources = ilo_set_compute_resources;
+ ilo->base.set_global_binding = ilo_set_global_binding;
}
diff --git a/src/gallium/drivers/ilo/ilo_state.h b/src/gallium/drivers/ilo/ilo_state.h
index cab1a2b926a..e8db6cbc048 100644
--- a/src/gallium/drivers/ilo/ilo_state.h
+++ b/src/gallium/drivers/ilo/ilo_state.h
@@ -30,9 +30,95 @@
#include "ilo_common.h"
+/**
+ * States that we track.
+ *
+ * XXX Do we want to count each sampler or vertex buffer as a state? If that
+ * is the case, there are simply not enough bits.
+ *
+ * XXX We want to treat primitive type and depth clear value as states, but
+ * there are not enough bits.
+ */
+enum ilo_state {
+ ILO_STATE_BLEND,
+ ILO_STATE_FRAGMENT_SAMPLERS,
+ ILO_STATE_VERTEX_SAMPLERS,
+ ILO_STATE_GEOMETRY_SAMPLERS,
+ ILO_STATE_COMPUTE_SAMPLERS,
+ ILO_STATE_RASTERIZER,
+ ILO_STATE_DEPTH_STENCIL_ALPHA,
+ ILO_STATE_FS,
+ ILO_STATE_VS,
+ ILO_STATE_GS,
+ ILO_STATE_VERTEX_ELEMENTS,
+ ILO_STATE_BLEND_COLOR,
+ ILO_STATE_STENCIL_REF,
+ ILO_STATE_SAMPLE_MASK,
+ ILO_STATE_CLIP,
+ ILO_STATE_CONSTANT_BUFFER,
+ ILO_STATE_FRAMEBUFFER,
+ ILO_STATE_POLY_STIPPLE,
+ ILO_STATE_SCISSOR,
+ ILO_STATE_VIEWPORT,
+ ILO_STATE_FRAGMENT_SAMPLER_VIEWS,
+ ILO_STATE_VERTEX_SAMPLER_VIEWS,
+ ILO_STATE_GEOMETRY_SAMPLER_VIEWS,
+ ILO_STATE_COMPUTE_SAMPLER_VIEWS,
+ ILO_STATE_SHADER_RESOURCES,
+ ILO_STATE_VERTEX_BUFFERS,
+ ILO_STATE_INDEX_BUFFER,
+ ILO_STATE_STREAM_OUTPUT_TARGETS,
+ ILO_STATE_COMPUTE,
+ ILO_STATE_COMPUTE_RESOURCES,
+ ILO_STATE_GLOBAL_BINDING,
+
+ ILO_STATE_COUNT,
+};
+
+/**
+ * Dirty flags of the states.
+ */
+enum ilo_dirty_flags {
+ ILO_DIRTY_BLEND = 1 << ILO_STATE_BLEND,
+ ILO_DIRTY_FRAGMENT_SAMPLERS = 1 << ILO_STATE_FRAGMENT_SAMPLERS,
+ ILO_DIRTY_VERTEX_SAMPLERS = 1 << ILO_STATE_VERTEX_SAMPLERS,
+ ILO_DIRTY_GEOMETRY_SAMPLERS = 1 << ILO_STATE_GEOMETRY_SAMPLERS,
+ ILO_DIRTY_COMPUTE_SAMPLERS = 1 << ILO_STATE_COMPUTE_SAMPLERS,
+ ILO_DIRTY_RASTERIZER = 1 << ILO_STATE_RASTERIZER,
+ ILO_DIRTY_DEPTH_STENCIL_ALPHA = 1 << ILO_STATE_DEPTH_STENCIL_ALPHA,
+ ILO_DIRTY_FS = 1 << ILO_STATE_FS,
+ ILO_DIRTY_VS = 1 << ILO_STATE_VS,
+ ILO_DIRTY_GS = 1 << ILO_STATE_GS,
+ ILO_DIRTY_VERTEX_ELEMENTS = 1 << ILO_STATE_VERTEX_ELEMENTS,
+ ILO_DIRTY_BLEND_COLOR = 1 << ILO_STATE_BLEND_COLOR,
+ ILO_DIRTY_STENCIL_REF = 1 << ILO_STATE_STENCIL_REF,
+ ILO_DIRTY_SAMPLE_MASK = 1 << ILO_STATE_SAMPLE_MASK,
+ ILO_DIRTY_CLIP = 1 << ILO_STATE_CLIP,
+ ILO_DIRTY_CONSTANT_BUFFER = 1 << ILO_STATE_CONSTANT_BUFFER,
+ ILO_DIRTY_FRAMEBUFFER = 1 << ILO_STATE_FRAMEBUFFER,
+ ILO_DIRTY_POLY_STIPPLE = 1 << ILO_STATE_POLY_STIPPLE,
+ ILO_DIRTY_SCISSOR = 1 << ILO_STATE_SCISSOR,
+ ILO_DIRTY_VIEWPORT = 1 << ILO_STATE_VIEWPORT,
+ ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS = 1 << ILO_STATE_FRAGMENT_SAMPLER_VIEWS,
+ ILO_DIRTY_VERTEX_SAMPLER_VIEWS = 1 << ILO_STATE_VERTEX_SAMPLER_VIEWS,
+ ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS = 1 << ILO_STATE_GEOMETRY_SAMPLER_VIEWS,
+ ILO_DIRTY_COMPUTE_SAMPLER_VIEWS = 1 << ILO_STATE_COMPUTE_SAMPLER_VIEWS,
+ ILO_DIRTY_SHADER_RESOURCES = 1 << ILO_STATE_SHADER_RESOURCES,
+ ILO_DIRTY_VERTEX_BUFFERS = 1 << ILO_STATE_VERTEX_BUFFERS,
+ ILO_DIRTY_INDEX_BUFFER = 1 << ILO_STATE_INDEX_BUFFER,
+ ILO_DIRTY_STREAM_OUTPUT_TARGETS = 1 << ILO_STATE_STREAM_OUTPUT_TARGETS,
+ ILO_DIRTY_COMPUTE = 1 << ILO_STATE_COMPUTE,
+ ILO_DIRTY_COMPUTE_RESOURCES = 1 << ILO_STATE_COMPUTE_RESOURCES,
+ ILO_DIRTY_GLOBAL_BINDING = 1 << ILO_STATE_GLOBAL_BINDING,
+ ILO_DIRTY_ALL = 0xffffffff,
+};
+
struct ilo_context;
void
ilo_init_state_functions(struct ilo_context *ilo);
+void
+ilo_finalize_states(struct ilo_context *ilo);
+
#endif /* ILO_STATE_H */