summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/swr/swr_state.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/swr/swr_state.cpp')
-rw-r--r--src/gallium/drivers/swr/swr_state.cpp83
1 files changed, 75 insertions, 8 deletions
diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp
index 706bf10f265..47ee3cb2664 100644
--- a/src/gallium/drivers/swr/swr_state.cpp
+++ b/src/gallium/drivers/swr/swr_state.cpp
@@ -42,6 +42,7 @@
#include "swr_tex_sample.h"
#include "swr_scratch.h"
#include "swr_shader.h"
+#include "swr_fence.h"
/* These should be pulled out into separate files as necessary
* Just initializing everything here to get going. */
@@ -629,11 +630,58 @@ swr_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
}
}
+/*
+ * Update resource in-use status
+ * All resources bound to color or depth targets marked as WRITE resources.
+ * VBO Vertex/index buffers and texture views marked as READ resources.
+ */
+void
+swr_update_resource_status(struct pipe_context *pipe,
+ const struct pipe_draw_info *p_draw_info)
+{
+ struct swr_context *ctx = swr_context(pipe);
+ struct pipe_framebuffer_state *fb = &ctx->framebuffer;
+
+ /* colorbuffer targets */
+ if (fb->nr_cbufs)
+ for (uint32_t i = 0; i < fb->nr_cbufs; ++i)
+ if (fb->cbufs[i])
+ swr_resource_write(pipe, swr_resource(fb->cbufs[i]->texture));
+
+ /* depth/stencil target */
+ if (fb->zsbuf)
+ swr_resource_write(pipe, swr_resource(fb->zsbuf->texture));
+
+ /* VBO vertex buffers */
+ for (uint32_t i = 0; i < ctx->num_vertex_buffers; i++) {
+ struct pipe_vertex_buffer *vb = &ctx->vertex_buffer[i];
+ if (!vb->user_buffer)
+ swr_resource_read(pipe, swr_resource(vb->buffer));
+ }
+
+ /* VBO index buffer */
+ if (p_draw_info && p_draw_info->indexed) {
+ struct pipe_index_buffer *ib = &ctx->index_buffer;
+ if (!ib->user_buffer)
+ swr_resource_read(pipe, swr_resource(ib->buffer));
+ }
+
+ /* texture sampler views */
+ for (uint32_t i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) {
+ struct pipe_sampler_view *view =
+ ctx->sampler_views[PIPE_SHADER_FRAGMENT][i];
+ if (view)
+ swr_resource_read(pipe, swr_resource(view->texture));
+ }
+}
void
-swr_update_derived(struct swr_context *ctx,
+swr_update_derived(struct pipe_context *pipe,
const struct pipe_draw_info *p_draw_info)
{
+ struct swr_context *ctx = swr_context(pipe);
+ struct swr_screen *screen = swr_screen(ctx->pipe.screen);
+
/* Any state that requires dirty flags to be re-triggered sets this mask */
/* For example, user_buffer vertex and index buffers. */
unsigned post_update_dirty_flags = 0;
@@ -671,17 +719,24 @@ swr_update_derived(struct swr_context *ctx,
/* Make the attachment updates */
swr_draw_context *pDC = &ctx->swrDC;
SWR_SURFACE_STATE *renderTargets = pDC->renderTargets;
+ unsigned need_fence = FALSE;
for (i = 0; i < SWR_NUM_ATTACHMENTS; i++) {
void *new_base = nullptr;
if (new_attachment[i])
new_base = new_attachment[i]->pBaseAddress;
-
+
/* StoreTile for changed target */
if (renderTargets[i].pBaseAddress != new_base) {
if (renderTargets[i].pBaseAddress) {
+ /* If changing attachment to a new target, mark tiles as
+ * INVALID so they are reloaded from surface.
+ * If detaching attachment, mark tiles as RESOLVED so core
+ * won't try to load from non-existent target. */
enum SWR_TILE_STATE post_state = (new_attachment[i]
? SWR_TILE_INVALID : SWR_TILE_RESOLVED);
- swr_store_render_target(ctx, i, post_state);
+ swr_store_render_target(pipe, i, post_state);
+
+ need_fence |= TRUE;
}
/* Make new attachment */
@@ -692,6 +747,11 @@ swr_update_derived(struct swr_context *ctx,
renderTargets[i] = {0};
}
}
+
+ /* This fence ensures any attachment changes are resolved before the
+ * next draw */
+ if (need_fence)
+ swr_fence_submit(ctx, screen->flush_fence);
}
/* Raster state */
@@ -793,8 +853,7 @@ swr_update_derived(struct swr_context *ctx,
vpm->m32 = state->translate[2];
/* Now that the matrix is calculated, clip the view coords to screen
- * size. OpenGL allows for -ve x,y in the viewport.
- */
+ * size. OpenGL allows for -ve x,y in the viewport. */
vp->x = std::max(vp->x, 0.0f);
vp->y = std::max(vp->y, 0.0f);
vp->width = std::min(vp->width, (float)fb->width);
@@ -817,7 +876,7 @@ swr_update_derived(struct swr_context *ctx,
/* vertex buffers */
SWR_VERTEX_BUFFER_STATE swrVertexBuffers[PIPE_MAX_ATTRIBS];
for (UINT i = 0; i < ctx->num_vertex_buffers; i++) {
- pipe_vertex_buffer *vb = &ctx->vertex_buffer[i];
+ struct pipe_vertex_buffer *vb = &ctx->vertex_buffer[i];
pitch = vb->stride;
if (!vb->user_buffer) {
@@ -871,7 +930,7 @@ swr_update_derived(struct swr_context *ctx,
/* index buffer, if required (info passed in by swr_draw_vbo) */
SWR_FORMAT index_type = R32_UINT; /* Default for non-indexed draws */
if (info.indexed) {
- pipe_index_buffer *ib = &ctx->index_buffer;
+ struct pipe_index_buffer *ib = &ctx->index_buffer;
pitch = ib->index_size ? ib->index_size : sizeof(uint32_t);
index_type = swr_convert_index_type(pitch);
@@ -1195,7 +1254,7 @@ swr_update_derived(struct swr_context *ctx,
if (search != ctx->blendJIT->end()) {
func = search->second;
} else {
- HANDLE hJitMgr = swr_screen(ctx->pipe.screen)->hJitMgr;
+ HANDLE hJitMgr = screen->hJitMgr;
func = JitCompileBlend(hJitMgr, compileState);
debug_printf("BLEND shader %p\n", func);
assert(func && "Error: BlendShader = NULL");
@@ -1253,9 +1312,17 @@ swr_update_derived(struct swr_context *ctx,
SwrSetBackendState(ctx->swrContext, &backendState);
+ /* Ensure that any in-progress attachment change StoreTiles finish */
+ if (swr_is_fence_pending(screen->flush_fence))
+ swr_fence_finish(pipe->screen, screen->flush_fence, 0);
+
+ /* Finally, update the in-use status of all resources involved in draw */
+ swr_update_resource_status(pipe, p_draw_info);
+
ctx->dirty = post_update_dirty_flags;
}
+
static struct pipe_stream_output_target *
swr_create_so_target(struct pipe_context *pipe,
struct pipe_resource *buffer,