summaryrefslogtreecommitdiff
path: root/lib/mesa/src/gallium/drivers/freedreno/freedreno_state.c
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2017-08-26 16:59:42 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2017-08-26 16:59:42 +0000
commit81ece42815e80818f160cdd85fab57d65b56ad15 (patch)
tree1059ff094da1aa50334115952fcb1cfcbda3acc6 /lib/mesa/src/gallium/drivers/freedreno/freedreno_state.c
parentb0244145d5bb49623d58f6b5cab8143ada692b60 (diff)
Revert to Mesa 13.0.6 to hopefully address rendering issues a handful of
people have reported with xpdf/fvwm on ivy bridge with modesetting driver.
Diffstat (limited to 'lib/mesa/src/gallium/drivers/freedreno/freedreno_state.c')
-rw-r--r--lib/mesa/src/gallium/drivers/freedreno/freedreno_state.c84
1 files changed, 61 insertions, 23 deletions
diff --git a/lib/mesa/src/gallium/drivers/freedreno/freedreno_state.c b/lib/mesa/src/gallium/drivers/freedreno/freedreno_state.c
index e75865a93..8c9040545 100644
--- a/lib/mesa/src/gallium/drivers/freedreno/freedreno_state.c
+++ b/lib/mesa/src/gallium/drivers/freedreno/freedreno_state.c
@@ -27,6 +27,7 @@
*/
#include "pipe/p_state.h"
+#include "util/u_dual_blend.h"
#include "util/u_string.h"
#include "util/u_memory.h"
#include "util/u_helpers.h"
@@ -36,6 +37,7 @@
#include "freedreno_resource.h"
#include "freedreno_texture.h"
#include "freedreno_gmem.h"
+#include "freedreno_query_hw.h"
#include "freedreno_util.h"
/* All the generic state handling.. In case of CSO's that are specific
@@ -88,26 +90,22 @@ fd_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask)
*/
static void
fd_set_constant_buffer(struct pipe_context *pctx, uint shader, uint index,
- struct pipe_constant_buffer *cb)
+ const struct pipe_constant_buffer *cb)
{
struct fd_context *ctx = fd_context(pctx);
struct fd_constbuf_stateobj *so = &ctx->constbuf[shader];
+ util_copy_constant_buffer(&so->cb[index], cb);
+
/* Note that the state tracker can unbind constant buffers by
* passing NULL here.
*/
if (unlikely(!cb)) {
so->enabled_mask &= ~(1 << index);
so->dirty_mask &= ~(1 << index);
- pipe_resource_reference(&so->cb[index].buffer, NULL);
return;
}
- pipe_resource_reference(&so->cb[index].buffer, cb->buffer);
- so->cb[index].buffer_offset = cb->buffer_offset;
- so->cb[index].buffer_size = cb->buffer_size;
- so->cb[index].user_buffer = cb->user_buffer;
-
so->enabled_mask |= 1 << index;
so->dirty_mask |= 1 << index;
ctx->dirty |= FD_DIRTY_CONSTBUF;
@@ -118,16 +116,39 @@ fd_set_framebuffer_state(struct pipe_context *pctx,
const struct pipe_framebuffer_state *framebuffer)
{
struct fd_context *ctx = fd_context(pctx);
- struct pipe_framebuffer_state *cso = &ctx->framebuffer;
+ struct pipe_framebuffer_state *cso;
+
+ if (ctx->screen->reorder) {
+ struct fd_batch *batch, *old_batch = NULL;
+
+ fd_batch_reference(&old_batch, ctx->batch);
+
+ if (likely(old_batch))
+ fd_hw_query_set_stage(old_batch, old_batch->draw, FD_STAGE_NULL);
- DBG("%d: cbufs[0]=%p, zsbuf=%p", ctx->needs_flush,
- framebuffer->cbufs[0], framebuffer->zsbuf);
+ batch = fd_batch_from_fb(&ctx->screen->batch_cache, ctx, framebuffer);
+ fd_batch_reference(&ctx->batch, NULL);
+ fd_reset_wfi(batch);
+ ctx->batch = batch;
+ ctx->dirty = ~0;
- fd_context_render(pctx);
+ if (old_batch && old_batch->blit && !old_batch->back_blit) {
+ /* for blits, there is not really much point in hanging on
+ * to the uncommitted batch (ie. you probably don't blit
+ * multiple times to the same surface), so we might as
+ * well go ahead and flush this one:
+ */
+ fd_batch_flush(old_batch, false);
+ }
- if ((cso->width != framebuffer->width) ||
- (cso->height != framebuffer->height))
- ctx->needs_rb_fbd = true;
+ fd_batch_reference(&old_batch, NULL);
+ } else {
+ DBG("%d: cbufs[0]=%p, zsbuf=%p", ctx->batch->needs_flush,
+ framebuffer->cbufs[0], framebuffer->zsbuf);
+ fd_batch_flush(ctx->batch, false);
+ }
+
+ cso = &ctx->batch->framebuffer;
util_copy_framebuffer_state(cso, framebuffer);
@@ -186,14 +207,16 @@ fd_set_vertex_buffers(struct pipe_context *pctx,
* we need to mark VTXSTATE as dirty as well to trigger patching
* and re-emitting the vtx shader:
*/
- for (i = 0; i < count; i++) {
- bool new_enabled = vb && (vb[i].buffer || vb[i].user_buffer);
- bool old_enabled = so->vb[i].buffer || so->vb[i].user_buffer;
- uint32_t new_stride = vb ? vb[i].stride : 0;
- uint32_t old_stride = so->vb[i].stride;
- if ((new_enabled != old_enabled) || (new_stride != old_stride)) {
- ctx->dirty |= FD_DIRTY_VTXSTATE;
- break;
+ if (ctx->screen->gpu_id < 300) {
+ for (i = 0; i < count; i++) {
+ bool new_enabled = vb && (vb[i].buffer || vb[i].user_buffer);
+ bool old_enabled = so->vb[i].buffer || so->vb[i].user_buffer;
+ uint32_t new_stride = vb ? vb[i].stride : 0;
+ uint32_t old_stride = so->vb[i].stride;
+ if ((new_enabled != old_enabled) || (new_stride != old_stride)) {
+ ctx->dirty |= FD_DIRTY_VTXSTATE;
+ break;
+ }
}
}
@@ -225,8 +248,17 @@ static void
fd_blend_state_bind(struct pipe_context *pctx, void *hwcso)
{
struct fd_context *ctx = fd_context(pctx);
+ struct pipe_blend_state *cso = hwcso;
+ bool old_is_dual = ctx->blend ?
+ ctx->blend->rt[0].blend_enable && util_blend_state_is_dual(ctx->blend, 0) :
+ false;
+ bool new_is_dual = cso ?
+ cso->rt[0].blend_enable && util_blend_state_is_dual(cso, 0) :
+ false;
ctx->blend = hwcso;
ctx->dirty |= FD_DIRTY_BLEND;
+ if (old_is_dual != new_is_dual)
+ ctx->dirty |= FD_DIRTY_BLEND_DUAL;
}
static void
@@ -308,6 +340,7 @@ fd_create_stream_output_target(struct pipe_context *pctx,
unsigned buffer_size)
{
struct pipe_stream_output_target *target;
+ struct fd_resource *rsc = fd_resource(prsc);
target = CALLOC_STRUCT(pipe_stream_output_target);
if (!target)
@@ -320,6 +353,10 @@ fd_create_stream_output_target(struct pipe_context *pctx,
target->buffer_offset = buffer_offset;
target->buffer_size = buffer_size;
+ assert(rsc->base.b.target == PIPE_BUFFER);
+ util_range_add(&rsc->valid_buffer_range,
+ buffer_offset, buffer_offset + buffer_size);
+
return target;
}
@@ -349,7 +386,8 @@ fd_set_stream_output_targets(struct pipe_context *pctx,
if (!changed && append)
continue;
- so->offsets[i] = 0;
+ if (!append)
+ so->offsets[i] = offsets[i];
pipe_so_target_reference(&so->targets[i], targets[i]);
}