summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/svga
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/svga')
-rw-r--r--src/gallium/drivers/svga/svga_cmd.c2
-rw-r--r--src/gallium/drivers/svga/svga_context.c5
-rw-r--r--src/gallium/drivers/svga/svga_context.h1
-rw-r--r--src/gallium/drivers/svga/svga_pipe_draw.c82
-rw-r--r--src/gallium/drivers/svga/svga_resource_texture.c3
-rw-r--r--src/gallium/drivers/svga/svga_state_framebuffer.c15
-rw-r--r--src/gallium/drivers/svga/svga_state_tss.c27
-rw-r--r--src/gallium/drivers/svga/svga_swtnl.h11
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_draw.c39
-rw-r--r--src/gallium/drivers/svga/svga_tgsi_emit.h1
-rw-r--r--src/gallium/drivers/svga/svga_tgsi_insn.c19
11 files changed, 101 insertions, 104 deletions
diff --git a/src/gallium/drivers/svga/svga_cmd.c b/src/gallium/drivers/svga/svga_cmd.c
index 7b2dfe2549..e975f3b02f 100644
--- a/src/gallium/drivers/svga/svga_cmd.c
+++ b/src/gallium/drivers/svga/svga_cmd.c
@@ -67,7 +67,7 @@ void surface_to_surfaceid(struct svga_winsys_context *swc, // IN
id->mipmap = s->real_level;
}
else {
- id->sid = SVGA3D_INVALID_ID;
+ swc->surface_relocation(swc, &id->sid, NULL, flags);
id->face = 0;
id->mipmap = 0;
}
diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index 3b30b9e341..cd3f6b8982 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -214,6 +214,11 @@ void svga_context_flush( struct svga_context *svga,
svga_screen_cache_flush(svgascreen, fence);
+ /* To force the reemission of rendertargets and texture bindings at
+ * the beginning of every command buffer.
+ */
+ svga->dirty |= SVGA_NEW_COMMAND_BUFFER;
+
if (SVGA_DEBUG & DEBUG_SYNC) {
if (fence)
svga->pipe.screen->fence_finish( svga->pipe.screen, fence, 0);
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 67a7614c8a..1fb5a04887 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -382,6 +382,7 @@ struct svga_context
#define SVGA_NEW_ZERO_STRIDE 0x2000000
#define SVGA_NEW_TEXTURE_FLAGS 0x4000000
#define SVGA_NEW_STENCIL_REF 0x8000000
+#define SVGA_NEW_COMMAND_BUFFER 0x10000000
diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c
index de08bc5e56..001ec3616c 100644
--- a/src/gallium/drivers/svga/svga_pipe_draw.c
+++ b/src/gallium/drivers/svga/svga_pipe_draw.c
@@ -146,23 +146,15 @@ retry:
}
-
-
-
static void
-svga_draw_range_elements( struct pipe_context *pipe,
- struct pipe_resource *index_buffer,
- unsigned index_size,
- int index_bias,
- unsigned min_index,
- unsigned max_index,
- unsigned prim, unsigned start, unsigned count)
+svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct svga_context *svga = svga_context( pipe );
- unsigned reduced_prim = u_reduced_prim(prim);
+ unsigned reduced_prim = u_reduced_prim( info->mode );
+ unsigned count = info->count;
enum pipe_error ret = 0;
- if (!u_trim_pipe_prim( prim, &count ))
+ if (!u_trim_pipe_prim( info->mode, &count ))
return;
/*
@@ -187,34 +179,32 @@ svga_draw_range_elements( struct pipe_context *pipe,
return;
#endif
- if (svga->state.sw.need_swtnl)
- {
- ret = svga_swtnl_draw_range_elements( svga,
- index_buffer,
- index_size,
- index_bias,
- min_index, max_index,
- prim,
- start, count );
+ if (svga->state.sw.need_swtnl) {
+ ret = svga_swtnl_draw_vbo( svga, info );
}
else {
- if (index_buffer) {
+ if (info->indexed && svga->curr.ib.buffer) {
+ unsigned offset;
+
+ assert(svga->curr.ib.offset % svga->curr.ib.index_size == 0);
+ offset = svga->curr.ib.offset / svga->curr.ib.index_size;
+
ret = retry_draw_range_elements( svga,
- index_buffer,
- index_size,
- index_bias,
- min_index,
- max_index,
- prim,
- start,
- count,
+ svga->curr.ib.buffer,
+ svga->curr.ib.index_size,
+ info->index_bias,
+ info->min_index,
+ info->max_index,
+ info->mode,
+ info->start + offset,
+ info->count,
TRUE );
}
else {
- ret = retry_draw_arrays( svga,
- prim,
- start,
- count,
+ ret = retry_draw_arrays( svga,
+ info->mode,
+ info->start,
+ info->count,
TRUE );
}
}
@@ -226,30 +216,6 @@ svga_draw_range_elements( struct pipe_context *pipe,
}
-static void
-svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
-{
- struct svga_context *svga = svga_context(pipe);
-
- if (info->indexed && svga->curr.ib.buffer) {
- unsigned offset;
-
- assert(svga->curr.ib.offset % svga->curr.ib.index_size == 0);
- offset = svga->curr.ib.offset / svga->curr.ib.index_size;
-
- svga_draw_range_elements(pipe, svga->curr.ib.buffer,
- svga->curr.ib.index_size, info->index_bias,
- info->min_index, info->max_index,
- info->mode, info->start + offset, info->count);
- }
- else {
- svga_draw_range_elements(pipe, NULL, 0, 0,
- info->min_index, info->max_index,
- info->mode, info->start, info->count);
- }
-}
-
-
void svga_init_draw_functions( struct svga_context *svga )
{
svga->pipe.draw_vbo = svga_draw_vbo;
diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c
index ff83c750aa..26eb03a895 100644
--- a/src/gallium/drivers/svga/svga_resource_texture.c
+++ b/src/gallium/drivers/svga/svga_resource_texture.c
@@ -583,7 +583,8 @@ svga_texture_from_handle(struct pipe_screen *screen,
assert(screen);
/* Only supports one type */
- if (template->target != PIPE_TEXTURE_2D ||
+ if ((template->target != PIPE_TEXTURE_2D &&
+ template->target != PIPE_TEXTURE_RECT) ||
template->last_level != 0 ||
template->depth0 != 1) {
return NULL;
diff --git a/src/gallium/drivers/svga/svga_state_framebuffer.c b/src/gallium/drivers/svga/svga_state_framebuffer.c
index bd92f00343..fcbb35e797 100644
--- a/src/gallium/drivers/svga/svga_state_framebuffer.c
+++ b/src/gallium/drivers/svga/svga_state_framebuffer.c
@@ -43,15 +43,18 @@ static int emit_framebuffer( struct svga_context *svga,
{
const struct pipe_framebuffer_state *curr = &svga->curr.framebuffer;
struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
+ boolean reemit = !!(dirty & SVGA_NEW_COMMAND_BUFFER);
unsigned i;
enum pipe_error ret;
- /* XXX: Need shadow state in svga->hw to eliminate redundant
- * uploads, especially of NULL buffers.
+ /*
+ * We need to reemit non-null surface bindings, even when they are not
+ * dirty, to ensure that the resources are paged in.
*/
for(i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
- if (curr->cbufs[i] != hw->cbufs[i]) {
+ if (curr->cbufs[i] != hw->cbufs[i] ||
+ (reemit && hw->cbufs[i])) {
if (svga->curr.nr_fbs++ > 8)
return PIPE_ERROR_OUT_OF_MEMORY;
@@ -64,7 +67,8 @@ static int emit_framebuffer( struct svga_context *svga,
}
- if (curr->zsbuf != hw->zsbuf) {
+ if (curr->zsbuf != hw->zsbuf ||
+ (reemit && hw->zsbuf)) {
ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_DEPTH, curr->zsbuf);
if (ret != PIPE_OK)
return ret;
@@ -92,7 +96,8 @@ static int emit_framebuffer( struct svga_context *svga,
struct svga_tracked_state svga_hw_framebuffer =
{
"hw framebuffer state",
- SVGA_NEW_FRAME_BUFFER,
+ SVGA_NEW_FRAME_BUFFER |
+ SVGA_NEW_COMMAND_BUFFER,
emit_framebuffer
};
diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c
index 76a2dae143..4a50b19474 100644
--- a/src/gallium/drivers/svga/svga_state_tss.c
+++ b/src/gallium/drivers/svga/svga_state_tss.c
@@ -56,6 +56,7 @@ static int
update_tss_binding(struct svga_context *svga,
unsigned dirty )
{
+ boolean reemit = !!(dirty & SVGA_NEW_COMMAND_BUFFER);
unsigned i;
unsigned count = MAX2( svga->curr.num_sampler_views,
svga->state.hw_draw.num_views );
@@ -107,12 +108,18 @@ update_tss_binding(struct svga_context *svga,
max_lod);
}
- if (view->dirty) {
+ /*
+ * We need to reemit non-null texture bindings, even when they are not
+ * dirty, to ensure that the resources are paged in.
+ */
+
+ if (view->dirty ||
+ (reemit && view->v)) {
queue.bind[queue.bind_count].unit = i;
queue.bind[queue.bind_count].view = view;
queue.bind_count++;
}
- else if (view->v) {
+ if (!view->dirty && view->v) {
svga_validate_sampler_view(svga, view->v);
}
}
@@ -128,18 +135,21 @@ update_tss_binding(struct svga_context *svga,
goto fail;
for (i = 0; i < queue.bind_count; i++) {
+ struct svga_winsys_surface *handle;
+
ts[i].stage = queue.bind[i].unit;
ts[i].name = SVGA3D_TS_BIND_TEXTURE;
if (queue.bind[i].view->v) {
- svga->swc->surface_relocation(svga->swc,
- &ts[i].value,
- queue.bind[i].view->v->handle,
- SVGA_RELOC_READ);
+ handle = queue.bind[i].view->v->handle;
}
else {
- ts[i].value = SVGA3D_INVALID_ID;
+ handle = NULL;
}
+ svga->swc->surface_relocation(svga->swc,
+ &ts[i].value,
+ handle,
+ SVGA_RELOC_READ);
queue.bind[i].view->dirty = FALSE;
}
@@ -157,7 +167,8 @@ fail:
struct svga_tracked_state svga_hw_tss_binding = {
"texture binding emit",
SVGA_NEW_TEXTURE_BINDING |
- SVGA_NEW_SAMPLER,
+ SVGA_NEW_SAMPLER |
+ SVGA_NEW_COMMAND_BUFFER,
update_tss_binding
};
diff --git a/src/gallium/drivers/svga/svga_swtnl.h b/src/gallium/drivers/svga/svga_swtnl.h
index 65c675f99c..fc094e5142 100644
--- a/src/gallium/drivers/svga/svga_swtnl.h
+++ b/src/gallium/drivers/svga/svga_swtnl.h
@@ -38,15 +38,8 @@ void svga_destroy_swtnl( struct svga_context *svga );
enum pipe_error
-svga_swtnl_draw_range_elements(struct svga_context *svga,
- struct pipe_resource *indexBuffer,
- unsigned indexSize,
- int indexBias,
- unsigned min_index,
- unsigned max_index,
- unsigned prim,
- unsigned start,
- unsigned count);
+svga_swtnl_draw_vbo(struct svga_context *svga,
+ const struct pipe_draw_info *info);
#endif
diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c
index eb71c23195..814e8edd70 100644
--- a/src/gallium/drivers/svga/svga_swtnl_draw.c
+++ b/src/gallium/drivers/svga/svga_swtnl_draw.c
@@ -36,13 +36,8 @@
enum pipe_error
-svga_swtnl_draw_range_elements(struct svga_context *svga,
- struct pipe_resource *indexBuffer,
- unsigned indexSize,
- int indexBias,
- unsigned min_index,
- unsigned max_index,
- unsigned prim, unsigned start, unsigned count)
+svga_swtnl_draw_vbo(struct svga_context *svga,
+ const struct pipe_draw_info *info)
{
struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
struct pipe_transfer *ib_transfer = NULL;
@@ -76,19 +71,18 @@ svga_swtnl_draw_range_elements(struct svga_context *svga,
draw_set_mapped_vertex_buffer(draw, i, map);
}
+ /* TODO move this to update_swtnl_draw */
+ draw_set_index_buffer(draw, &svga->curr.ib);
+
/* Map index buffer, if present */
- if (indexBuffer) {
- map = pipe_buffer_map(&svga->pipe, indexBuffer,
+ map = NULL;
+ if (info->indexed && svga->curr.ib.buffer) {
+ map = pipe_buffer_map(&svga->pipe, svga->curr.ib.buffer,
PIPE_TRANSFER_READ,
- &ib_transfer);
-
- draw_set_mapped_element_buffer_range(draw,
- indexSize, indexBias,
- min_index,
- max_index,
- map);
+ &ib_transfer);
}
-
+ draw_set_mapped_index_buffer(draw, map);
+
if (svga->curr.cb[PIPE_SHADER_VERTEX]) {
map = pipe_buffer_map(&svga->pipe,
svga->curr.cb[PIPE_SHADER_VERTEX],
@@ -101,7 +95,7 @@ svga_swtnl_draw_range_elements(struct svga_context *svga,
svga->curr.cb[PIPE_SHADER_VERTEX]->width0);
}
- draw_arrays(svga->swtnl.draw, prim, start, count);
+ draw_vbo(draw, info);
draw_flush(svga->swtnl.draw);
@@ -117,9 +111,9 @@ svga_swtnl_draw_range_elements(struct svga_context *svga,
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
- if (indexBuffer) {
- pipe_buffer_unmap(&svga->pipe, indexBuffer, ib_transfer);
- draw_set_mapped_element_buffer(draw, 0, 0, NULL);
+ if (ib_transfer) {
+ pipe_buffer_unmap(&svga->pipe, svga->curr.ib.buffer, ib_transfer);
+ draw_set_mapped_index_buffer(draw, NULL);
}
if (svga->curr.cb[PIPE_SHADER_VERTEX]) {
@@ -157,7 +151,8 @@ boolean svga_init_swtnl( struct svga_context *svga )
draw_install_aapoint_stage(svga->swtnl.draw, &svga->pipe);
draw_install_pstipple_stage(svga->swtnl.draw, &svga->pipe);
- draw_set_driver_clipping(svga->swtnl.draw, debug_get_bool_option("SVGA_SWTNL_FSE", FALSE));
+ if (debug_get_bool_option("SVGA_SWTNL_FSE", FALSE))
+ draw_set_driver_clipping(svga->swtnl.draw, TRUE, TRUE);
return TRUE;
diff --git a/src/gallium/drivers/svga/svga_tgsi_emit.h b/src/gallium/drivers/svga/svga_tgsi_emit.h
index 48eced2ece..b4e90a957d 100644
--- a/src/gallium/drivers/svga/svga_tgsi_emit.h
+++ b/src/gallium/drivers/svga/svga_tgsi_emit.h
@@ -353,6 +353,7 @@ static INLINE ubyte svga_tgsi_sampler_type( struct svga_shader_emitter *emit,
case PIPE_TEXTURE_1D:
return SVGA3DSAMP_2D;
case PIPE_TEXTURE_2D:
+ case PIPE_TEXTURE_RECT:
return SVGA3DSAMP_2D;
case PIPE_TEXTURE_3D:
return SVGA3DSAMP_VOLUME;
diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c b/src/gallium/drivers/svga/svga_tgsi_insn.c
index 67e1f22a70..72dccdf150 100644
--- a/src/gallium/drivers/svga/svga_tgsi_insn.c
+++ b/src/gallium/drivers/svga/svga_tgsi_insn.c
@@ -806,6 +806,20 @@ static boolean emit_cmp(struct svga_shader_emitter *emit,
const struct src_register src2 = translate_src_register(
emit, &insn->Src[2] );
+ if (emit->unit == PIPE_SHADER_VERTEX) {
+ SVGA3dShaderDestToken temp = get_temp(emit);
+ struct src_register zero = scalar(get_zero_immediate(emit), TGSI_SWIZZLE_X);
+
+ /* Since vertex shaders don't support the CMP instruction,
+ * simulate it with SLT and LRP instructions.
+ * SLT TMP, SRC0, 0.0
+ * LRP DST, TMP, SRC1, SRC2
+ */
+ if (!submit_op2(emit, inst_token(SVGA3DOP_SLT), temp, src0, zero))
+ return FALSE;
+ return submit_op3(emit, inst_token(SVGA3DOP_LRP), dst, src(temp), src1, src2);
+ }
+
/* CMP DST, SRC0, SRC2, SRC1 */
return submit_op3( emit, inst_token( SVGA3DOP_CMP ), dst, src0, src2, src1);
}
@@ -2682,6 +2696,11 @@ needs_to_create_zero( struct svga_shader_emitter *emit )
return TRUE;
}
+ if (emit->unit == PIPE_SHADER_VERTEX) {
+ if (emit->info.opcode_count[TGSI_OPCODE_CMP] >= 1)
+ return TRUE;
+ }
+
if (emit->info.opcode_count[TGSI_OPCODE_IF] >= 1 ||
emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1 ||
emit->info.opcode_count[TGSI_OPCODE_DDX] >= 1 ||