meson: define driver dependencies
[mesa.git] / src / gallium / drivers / r600 / r600_state_common.c
index ead5b86e0c57bc75aa42205750c6231476f67253..fee7a21d27dd039eca461ef43298e27f40c9eceb 100644 (file)
@@ -91,6 +91,29 @@ void r600_emit_alphatest_state(struct r600_context *rctx, struct r600_atom *atom
        radeon_set_context_reg(cs, R_028438_SX_ALPHA_REF, alpha_ref);
 }
 
+static void r600_memory_barrier(struct pipe_context *ctx, unsigned flags)
+{
+       struct r600_context *rctx = (struct r600_context *)ctx;
+       if (flags & PIPE_BARRIER_CONSTANT_BUFFER)
+               rctx->b.flags |= R600_CONTEXT_INV_CONST_CACHE;
+
+       if (flags & (PIPE_BARRIER_VERTEX_BUFFER |
+                    PIPE_BARRIER_SHADER_BUFFER |
+                    PIPE_BARRIER_TEXTURE |
+                    PIPE_BARRIER_IMAGE |
+                    PIPE_BARRIER_STREAMOUT_BUFFER |
+                    PIPE_BARRIER_GLOBAL_BUFFER)) {
+               rctx->b.flags |= R600_CONTEXT_INV_VERTEX_CACHE|
+                       R600_CONTEXT_INV_TEX_CACHE;
+       }
+
+       if (flags & (PIPE_BARRIER_FRAMEBUFFER|
+                    PIPE_BARRIER_IMAGE))
+               rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV;
+
+       rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE;
+}
+
 static void r600_texture_barrier(struct pipe_context *ctx, unsigned flags)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
@@ -730,6 +753,26 @@ static int r600_get_hw_atomic_count(const struct pipe_context *ctx,
        return value;
 }
 
+static void r600_update_compressed_colortex_mask_images(struct r600_image_state *images)
+{
+       uint32_t mask = images->enabled_mask;
+
+       while (mask) {
+               unsigned i = u_bit_scan(&mask);
+               struct pipe_resource *res = images->views[i].base.resource;
+
+               if (res && res->target != PIPE_BUFFER) {
+                       struct r600_texture *rtex = (struct r600_texture *)res;
+
+                       if (rtex->cmask.size) {
+                               images->compressed_colortex_mask |= 1 << i;
+                       } else {
+                               images->compressed_colortex_mask &= ~(1 << i);
+                       }
+               }
+       }
+}
+
 /* Compute the key for the hw shader variant */
 static inline void r600_shader_selector_key(const struct pipe_context *ctx,
                const struct r600_pipe_shader_selector *sel,
@@ -756,6 +799,8 @@ static inline void r600_shader_selector_key(const struct pipe_context *ctx,
                key->gs.tri_strip_adj_fix = rctx->gs_tri_strip_adj_fix;
                break;
        case PIPE_SHADER_FRAGMENT: {
+               if (rctx->ps_shader->info.images_declared)
+                       key->ps.image_size_const_offset = util_last_bit(rctx->samplers[PIPE_SHADER_FRAGMENT].views.enabled_mask);
                key->ps.first_atomic_counter = r600_get_hw_atomic_count(ctx, PIPE_SHADER_FRAGMENT);
                key->ps.color_two_side = rctx->rasterizer && rctx->rasterizer->two_side;
                key->ps.alpha_to_one = rctx->alpha_to_one &&
@@ -1287,29 +1332,68 @@ static void r600_setup_buffer_constants(struct r600_context *rctx, int shader_ty
 static void eg_setup_buffer_constants(struct r600_context *rctx, int shader_type)
 {
        struct r600_textures_info *samplers = &rctx->samplers[shader_type];
-       int bits;
+       struct r600_image_state *images = NULL;
+       struct r600_image_state *buffers = NULL;
+       int bits, sview_bits, img_bits;
        uint32_t array_size;
        int i;
        uint32_t *constants;
        uint32_t base_offset;
-       if (!samplers->views.dirty_buffer_constants)
+
+       if (shader_type == PIPE_SHADER_FRAGMENT) {
+               images = &rctx->fragment_images;
+               buffers = &rctx->fragment_buffers;
+       }
+
+       if (!samplers->views.dirty_buffer_constants &&
+           (images && !images->dirty_buffer_constants) &&
+           (buffers && !buffers->dirty_buffer_constants))
                return;
 
+       if (images)
+               images->dirty_buffer_constants = FALSE;
+       if (buffers)
+               buffers->dirty_buffer_constants = FALSE;
        samplers->views.dirty_buffer_constants = FALSE;
 
-       bits = util_last_bit(samplers->views.enabled_mask);
+       bits = sview_bits = util_last_bit(samplers->views.enabled_mask);
+       if (images)
+               bits += util_last_bit(images->enabled_mask);
+       img_bits = bits;
+       if (buffers)
+               bits += util_last_bit(buffers->enabled_mask);
        array_size = bits * 2 * sizeof(uint32_t) * 4;
 
        constants = r600_alloc_buf_consts(rctx, shader_type, array_size,
                                          &base_offset);
 
-       for (i = 0; i < bits; i++) {
+       for (i = 0; i < sview_bits; i++) {
                if (samplers->views.enabled_mask & (1 << i)) {
                        uint32_t offset = (base_offset / 4) + i * 2;
                        constants[offset] = samplers->views.views[i]->base.texture->width0 / util_format_get_blocksize(samplers->views.views[i]->base.format);
                        constants[offset + 1] = samplers->views.views[i]->base.texture->array_size / 6;
                }
        }
+       if (images) {
+               for (i = sview_bits; i < img_bits; i++) {
+                       int idx = i - sview_bits;
+                       if (images->enabled_mask & (1 << idx)) {
+                               uint32_t offset = (base_offset / 4) + i * 2;
+                               constants[offset] = images->views[i].base.resource->width0 / util_format_get_blocksize(images->views[i].base.format);
+                               constants[offset + 1] = images->views[i].base.resource->array_size / 6;
+                       }
+               }
+       }
+       if (buffers) {
+               for (i = img_bits; i < bits; i++) {
+                       int idx = i - img_bits;
+                       if (buffers->enabled_mask & (1 << idx)) {
+                               uint32_t offset = (base_offset / 4) + i * 2;
+                               constants[offset] = buffers->views[i].base.resource->width0 / util_format_get_blocksize(buffers->views[i].base.format);
+                               constants[offset + 1] = 0;
+                       }
+               }
+       }
 }
 
 /* set sample xy locations as array of fragment shader constants */
@@ -1400,10 +1484,12 @@ static void r600_update_clip_state(struct r600_context *rctx,
 {
        if (current->pa_cl_vs_out_cntl != rctx->clip_misc_state.pa_cl_vs_out_cntl ||
            current->shader.clip_dist_write != rctx->clip_misc_state.clip_dist_write ||
+           current->shader.cull_dist_write != rctx->clip_misc_state.cull_dist_write ||
            current->shader.vs_position_window_space != rctx->clip_misc_state.clip_disable ||
            current->shader.vs_out_viewport != rctx->clip_misc_state.vs_out_viewport) {
                rctx->clip_misc_state.pa_cl_vs_out_cntl = current->pa_cl_vs_out_cntl;
                rctx->clip_misc_state.clip_dist_write = current->shader.clip_dist_write;
+               rctx->clip_misc_state.cull_dist_write = current->shader.cull_dist_write;
                rctx->clip_misc_state.clip_disable = current->shader.vs_position_window_space;
                rctx->clip_misc_state.vs_out_viewport = current->shader.vs_out_viewport;
                r600_mark_atom_dirty(rctx, &rctx->clip_misc_state.atom);
@@ -1450,6 +1536,7 @@ static void r600_update_compressed_resource_state(struct r600_context *rctx)
                for (i = 0; i < PIPE_SHADER_TYPES; ++i) {
                        r600_update_compressed_colortex_mask(&rctx->samplers[i].views);
                }
+               r600_update_compressed_colortex_mask_images(&rctx->fragment_images);
        }
 
        /* Decompress textures if needed. */
@@ -1462,6 +1549,15 @@ static void r600_update_compressed_resource_state(struct r600_context *rctx)
                        r600_decompress_color_textures(rctx, views);
                }
        }
+
+       {
+               struct r600_image_state *istate;
+               istate = &rctx->fragment_images;
+               if (istate->compressed_depthtex_mask)
+                       r600_decompress_depth_images(rctx, istate);
+               if (istate->compressed_colortex_mask)
+                       r600_decompress_color_images(rctx, istate);
+       }
 }
 
 #define SELECT_SHADER_OR_FAIL(x) do {                                  \
@@ -1694,7 +1790,8 @@ void r600_emit_clip_misc_state(struct r600_context *rctx, struct r600_atom *atom
                                S_028810_CLIP_DISABLE(state->clip_disable));
        radeon_set_context_reg(cs, R_02881C_PA_CL_VS_OUT_CNTL,
                               state->pa_cl_vs_out_cntl |
-                              (state->clip_plane_enable & state->clip_dist_write));
+                              (state->clip_plane_enable & state->clip_dist_write) |
+                              (state->cull_dist_write << 8));
        /* reuse needs to be set off if we write oViewport */
        if (rctx->b.chip_class >= EVERGREEN)
                radeon_set_context_reg(cs, R_028AB4_VGT_REUSE_OFF,
@@ -1757,7 +1854,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
 
        /* make sure that the gfx ring is only one active */
        if (radeon_emitted(rctx->b.dma.cs, 0)) {
-               rctx->b.dma.flush(rctx, RADEON_FLUSH_ASYNC, NULL);
+               rctx->b.dma.flush(rctx, PIPE_FLUSH_ASYNC, NULL);
        }
 
        /* Re-emit the framebuffer state if needed. */
@@ -2949,6 +3046,24 @@ static void r600_invalidate_buffer(struct pipe_context *ctx, struct pipe_resourc
                        r600_sampler_views_dirty(rctx, state);
                }
        }
+
+       /* SSBOs */
+       struct r600_image_state *istate = &rctx->fragment_buffers;
+       {
+               uint32_t mask = istate->enabled_mask;
+               bool found = false;
+               while (mask) {
+                       unsigned i = u_bit_scan(&mask);
+                       if (istate->views[i].base.resource == &rbuffer->b.b) {
+                               found = true;
+                               istate->dirty_mask |= 1 << i;
+                       }
+               }
+               if (found) {
+                       r600_mark_atom_dirty(rctx, &istate->atom);
+               }
+       }
+
 }
 
 static void r600_set_active_query_state(struct pipe_context *ctx, boolean enable)
@@ -3014,6 +3129,7 @@ void r600_init_common_state_functions(struct r600_context *rctx)
        rctx->b.b.set_vertex_buffers = r600_set_vertex_buffers;
        rctx->b.b.set_sampler_views = r600_set_sampler_views;
        rctx->b.b.sampler_view_destroy = r600_sampler_view_destroy;
+       rctx->b.b.memory_barrier = r600_memory_barrier;
        rctx->b.b.texture_barrier = r600_texture_barrier;
        rctx->b.b.set_stream_output_targets = r600_set_streamout_targets;
        rctx->b.b.set_active_query_state = r600_set_active_query_state;