#include "svga_debug.h"
#include "svga_screen.h"
#include "svga_surface.h"
+#include "svga_resource_texture.h"
/*
if (svga->curr.nr_fbs++ > MAX_RT_PER_BATCH)
return PIPE_ERROR_OUT_OF_MEMORY;
+ /* Check to see if we need to propagate the render target surface */
+ if (hw->cbufs[i] && svga_surface_needs_propagation(hw->cbufs[i]))
+ svga_propagate_surface(svga, hw->cbufs[i], TRUE);
+
ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_COLOR0 + i,
curr->cbufs[i]);
if (ret != PIPE_OK)
pipe_surface_reference(&hw->cbufs[i], curr->cbufs[i]);
}
+
+ /* Set the rendered-to flag */
+ struct pipe_surface *s = curr->cbufs[i];
+ if (s) {
+ svga_set_texture_rendered_to(svga_texture(s->texture),
+ s->u.tex.first_layer, s->u.tex.level);
+ }
}
if ((curr->zsbuf != hw->zsbuf) || (reemit && hw->zsbuf)) {
if (ret != PIPE_OK)
return ret;
+ /* Check to see if we need to propagate the depth stencil surface */
+ if (hw->zsbuf && svga_surface_needs_propagation(hw->zsbuf))
+ svga_propagate_surface(svga, hw->zsbuf, TRUE);
+
if (curr->zsbuf &&
util_format_is_depth_and_stencil(curr->zsbuf->format)) {
ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_STENCIL,
}
pipe_surface_reference(&hw->zsbuf, curr->zsbuf);
+
+ /* Set the rendered-to flag */
+ struct pipe_surface *s = curr->zsbuf;
+ if (s) {
+ svga_set_texture_rendered_to(svga_texture(s->texture),
+ s->u.tex.first_layer, s->u.tex.level);
+ }
}
return PIPE_OK;
struct pipe_framebuffer_state *curr = &svga->curr.framebuffer;
struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
const unsigned num_color = MAX2(curr->nr_cbufs, hw->nr_cbufs);
+ int last_rtv = -1;
unsigned i;
- enum pipe_error ret;
+ enum pipe_error ret = PIPE_OK;
assert(svga_have_vgpu10(svga));
+ /* Reset the has_backed_views flag.
+ * The flag is set in svga_validate_surface_view() if
+ * a backed surface view is used.
+ */
+ svga->state.hw_draw.has_backed_views = FALSE;
+
/* Setup render targets array. Note that we loop over the max of the
* number of previously bound buffers and the new buffers to unbind
* any previously bound buffers when the new number of buffers is less
*/
for (i = 0; i < num_color; i++) {
if (curr->cbufs[i]) {
- rtv[i] = svga_validate_surface_view(svga,
- svga_surface(curr->cbufs[i]));
+ struct pipe_surface *s = curr->cbufs[i];
+
+ rtv[i] = svga_validate_surface_view(svga, svga_surface(s));
if (rtv[i] == NULL) {
return PIPE_ERROR_OUT_OF_MEMORY;
}
assert(svga_surface(rtv[i])->view_id != SVGA3D_INVALID_ID);
+ last_rtv = i;
+
+ /* Set the rendered-to flag */
+ svga_set_texture_rendered_to(svga_texture(s->texture),
+ s->u.tex.first_layer, s->u.tex.level);
}
else {
rtv[i] = NULL;
/* Setup depth stencil view */
if (curr->zsbuf) {
+ struct pipe_surface *s = curr->zsbuf;
+
dsv = svga_validate_surface_view(svga, svga_surface(curr->zsbuf));
- if (dsv == NULL) {
+ if (!dsv) {
return PIPE_ERROR_OUT_OF_MEMORY;
}
+
+ /* Set the rendered-to flag */
+ svga_set_texture_rendered_to(svga_texture(s->texture),
+ s->u.tex.first_layer, s->u.tex.level);
}
else {
dsv = NULL;
}
- ret = SVGA3D_vgpu10_SetRenderTargets(svga->swc, num_color, rtv, dsv);
- if (ret != PIPE_OK)
- return ret;
+ /* avoid emitting redundant SetRenderTargets command */
+ if ((num_color != svga->state.hw_clear.num_rendertargets) ||
+ (dsv != svga->state.hw_clear.dsv) ||
+ memcmp(rtv, svga->state.hw_clear.rtv, num_color * sizeof(rtv[0]))) {
- for (i = 0; i < ss->max_color_buffers; i++) {
- if (hw->cbufs[i] != curr->cbufs[i]) {
- /* propagate the backed view surface before unbinding it */
- if (hw->cbufs[i] && svga_surface(hw->cbufs[i])->backed) {
- svga_propagate_surface(svga,
- &svga_surface(hw->cbufs[i])->backed->base);
+ ret = SVGA3D_vgpu10_SetRenderTargets(svga->swc, num_color, rtv, dsv);
+ if (ret != PIPE_OK)
+ return ret;
+
+ /* number of render targets sent to the device, not including trailing
+ * unbound render targets.
+ */
+ svga->state.hw_clear.num_rendertargets = last_rtv + 1;
+ svga->state.hw_clear.dsv = dsv;
+ memcpy(svga->state.hw_clear.rtv, rtv, num_color * sizeof(rtv[0]));
+
+ for (i = 0; i < ss->max_color_buffers; i++) {
+ if (hw->cbufs[i] != curr->cbufs[i]) {
+ /* propagate the backed view surface before unbinding it */
+ if (hw->cbufs[i] && svga_surface(hw->cbufs[i])->backed) {
+ svga_propagate_surface(svga,
+ &svga_surface(hw->cbufs[i])->backed->base,
+ TRUE);
+ }
+ pipe_surface_reference(&hw->cbufs[i], curr->cbufs[i]);
}
- pipe_surface_reference(&hw->cbufs[i], curr->cbufs[i]);
}
- }
- hw->nr_cbufs = curr->nr_cbufs;
+ hw->nr_cbufs = curr->nr_cbufs;
- if (hw->zsbuf != curr->zsbuf) {
- /* propagate the backed view surface before unbinding it */
- if (hw->zsbuf && svga_surface(hw->zsbuf)->backed) {
- svga_propagate_surface(svga, &svga_surface(hw->zsbuf)->backed->base);
+ if (hw->zsbuf != curr->zsbuf) {
+ /* propagate the backed view surface before unbinding it */
+ if (hw->zsbuf && svga_surface(hw->zsbuf)->backed) {
+ svga_propagate_surface(svga, &svga_surface(hw->zsbuf)->backed->base,
+ TRUE);
+ }
+ pipe_surface_reference(&hw->zsbuf, curr->zsbuf);
}
- pipe_surface_reference(&hw->zsbuf, curr->zsbuf);
}
return ret;
enum pipe_error
svga_rebind_framebuffer_bindings(struct svga_context *svga)
{
- const struct svga_screen *ss = svga_screen(svga->pipe.screen);
- struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
+ struct svga_hw_clear_state *hw = &svga->state.hw_clear;
unsigned i;
enum pipe_error ret;
if (!svga->rebind.flags.rendertargets)
return PIPE_OK;
- for (i = 0; i < ss->max_color_buffers; i++) {
- if (hw->cbufs[i]) {
+ for (i = 0; i < hw->num_rendertargets; i++) {
+ if (hw->rtv[i]) {
ret = svga->swc->resource_rebind(svga->swc,
- svga_surface(hw->cbufs[i])->handle,
+ svga_surface(hw->rtv[i])->handle,
NULL,
SVGA_RELOC_WRITE);
if (ret != PIPE_OK)
}
}
- if (hw->zsbuf) {
+ if (hw->dsv) {
ret = svga->swc->resource_rebind(svga->swc,
- svga_surface(hw->zsbuf)->handle,
+ svga_surface(hw->dsv)->handle,
NULL,
SVGA_RELOC_WRITE);
if (ret != PIPE_OK)
/* Enable prescale to adjust vertex positions to match
VGPU10 convention only if rasterization is enabled.
*/
- if (svga->curr.rast->templ.rasterizer_discard) {
+ if (svga->curr.rast && svga->curr.rast->templ.rasterizer_discard) {
degenerate = TRUE;
goto out;
} else {
* screen-space coordinates slightly relative to D3D which is
* what hardware implements natively.
*/
- if (svga->curr.rast->templ.half_pixel_center) {
+ if (svga->curr.rast && svga->curr.rast->templ.half_pixel_center) {
float adjust_x = 0.0;
float adjust_y = 0.0;
break;
case PIPE_PRIM_LINES:
adjust_x = -0.5;
- adjust_y = 0;
+ adjust_y = -0.125;
break;
case PIPE_PRIM_TRIANGLES:
adjust_x = -0.5;
adjust_y = -0.5;
break;
+ default:
+ /* nothing */
+ break;
}
}