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;
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,
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 &&
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 */
{
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);
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. */
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 { \
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,
/* 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. */
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)
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;