summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/svga/svga_surface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/svga/svga_surface.c')
-rw-r--r--src/gallium/drivers/svga/svga_surface.c135
1 files changed, 76 insertions, 59 deletions
diff --git a/src/gallium/drivers/svga/svga_surface.c b/src/gallium/drivers/svga/svga_surface.c
index 3eebf6eca43..b4344f1c45e 100644
--- a/src/gallium/drivers/svga/svga_surface.c
+++ b/src/gallium/drivers/svga/svga_surface.c
@@ -28,7 +28,7 @@
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
-#include "os/os_thread.h"
+#include "util/u_thread.h"
#include "util/u_bitmask.h"
#include "util/format/u_format.h"
#include "util/u_math.h"
@@ -189,13 +189,13 @@ svga_texture_view_surface(struct svga_context *svga,
int layer_pick,
unsigned num_layers,
int zslice_pick,
- boolean cacheable,
+ bool cacheable,
struct svga_host_surface_cache_key *key) /* OUT */
{
struct svga_screen *ss = svga_screen(svga->pipe.screen);
struct svga_winsys_surface *handle = NULL;
- boolean validated;
- boolean needCopyResource;
+ bool invalidated;
+ bool needCopyResource;
SVGA_DBG(DEBUG_PERF,
"svga: Create surface view: layer %d zslice %d mips %d..%d\n",
@@ -241,8 +241,8 @@ svga_texture_view_surface(struct svga_context *svga,
} else {
SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n");
handle = svga_screen_surface_create(ss, bind_flags, PIPE_USAGE_DEFAULT,
- &validated, key);
- needCopyResource = TRUE;
+ &invalidated, key);
+ needCopyResource = true;
if (cacheable && !tex->backed_handle) {
tex->backed_handle = handle;
@@ -277,14 +277,14 @@ done:
/**
* A helper function to create a surface view.
- * The view boolean flag specifies whether svga_texture_view_surface()
- * will be called to create a cloned surface and resource for the view.
+ * The clone_resource boolean flag specifies whether to clone the resource
+ * for the surface view.
*/
static struct pipe_surface *
svga_create_surface_view(struct pipe_context *pipe,
struct pipe_resource *pt,
const struct pipe_surface *surf_tmpl,
- boolean view)
+ bool clone_resource)
{
struct svga_context *svga = svga_context(pipe);
struct svga_texture *tex = svga_texture(pt);
@@ -357,7 +357,7 @@ svga_create_surface_view(struct pipe_context *pipe,
assert(format != SVGA3D_FORMAT_INVALID);
- if (view) {
+ if (clone_resource) {
SVGA_DBG(DEBUG_VIEWS,
"New backed surface view: resource %p, level %u layer %u z %u, %p\n",
pt, surf_tmpl->u.tex.level, layer, zslice, s);
@@ -396,7 +396,7 @@ svga_create_surface_view(struct pipe_context *pipe,
tex->key.format,
surf_tmpl->u.tex.level, 1,
layer, nlayers, zslice,
- TRUE, &s->key);
+ true, &s->key);
if (!s->handle) {
FREE(s);
goto done;
@@ -436,22 +436,22 @@ svga_create_surface(struct pipe_context *pipe,
struct svga_context *svga = svga_context(pipe);
struct pipe_screen *screen = pipe->screen;
struct pipe_surface *surf = NULL;
- boolean view = FALSE;
+ bool view = false;
SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATESURFACE);
if (svga_screen(screen)->debug.force_surface_view)
- view = TRUE;
+ view = true;
if (surf_tmpl->u.tex.level != 0 &&
svga_screen(screen)->debug.force_level_surface_view)
- view = TRUE;
+ view = true;
if (pt->target == PIPE_TEXTURE_3D)
- view = TRUE;
+ view = true;
if (svga_have_vgpu10(svga) || svga_screen(screen)->debug.no_surface_view)
- view = FALSE;
+ view = false;
surf = svga_create_surface_view(pipe, pt, surf_tmpl, view);
@@ -462,10 +462,11 @@ svga_create_surface(struct pipe_context *pipe,
/**
- * Clone the surface view and its associated resource.
+ * Create an alternate surface view and clone the resource if specified
*/
static struct svga_surface *
-create_backed_surface_view(struct svga_context *svga, struct svga_surface *s)
+create_backed_surface_view(struct svga_context *svga, struct svga_surface *s,
+ bool clone_resource)
{
struct svga_texture *tex = svga_texture(s->base.texture);
@@ -478,7 +479,7 @@ create_backed_surface_view(struct svga_context *svga, struct svga_surface *s)
backed_view = svga_create_surface_view(&svga->pipe,
&tex->b,
&s->base,
- TRUE);
+ clone_resource);
if (!backed_view)
goto done;
@@ -486,7 +487,8 @@ create_backed_surface_view(struct svga_context *svga, struct svga_surface *s)
SVGA_STATS_TIME_POP(svga_sws(svga));
}
- else if (s->backed->age < tex->age) {
+ else if (s->backed->handle != tex->handle &&
+ s->backed->age < tex->age) {
/*
* There is already an existing backing surface, but we still need to
* sync the backing resource if the original resource has been modified
@@ -519,6 +521,8 @@ create_backed_surface_view(struct svga_context *svga, struct svga_surface *s)
svga_mark_surface_dirty(&s->backed->base);
s->backed->age = tex->age;
+ assert(s->backed->base.context == &svga->pipe);
+
done:
return s->backed;
}
@@ -547,15 +551,15 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
* associated resource. We will then use the cloned surface view for
* render target.
*/
- for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_TESS_EVAL; shader++) {
+ for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_COMPUTE; shader++) {
if (svga_check_sampler_view_resource_collision(svga, s->handle, shader)) {
SVGA_DBG(DEBUG_VIEWS,
"same resource used in shaderResource and renderTarget 0x%x\n",
s->handle);
- s = create_backed_surface_view(svga, s);
+ s = create_backed_surface_view(svga, s, true);
if (s)
- svga->state.hw_draw.has_backed_views = TRUE;
+ svga->state.hw_draw.has_backed_views = true;
/* s may be null here if the function failed */
break;
@@ -567,9 +571,10 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
* view was created for another context.
*/
if (s && s->base.context != &svga->pipe) {
- struct pipe_surface *surf;
- surf = svga_create_surface_view(&svga->pipe, s->base.texture, &s->base, FALSE);
- s = svga_surface(surf);
+ s = create_backed_surface_view(svga, s, false);
+
+ if (s)
+ svga->state.hw_draw.has_backed_views = true;
}
if (s && s->view_id == SVGA3D_INVALID_ID) {
@@ -577,7 +582,7 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
SVGA3dRenderTargetViewDesc desc;
struct svga_texture *stex = svga_texture(s->base.texture);
- if (stex->validated == FALSE) {
+ if (stex->surface_state < SVGA_SURFACE_STATE_INVALIDATED) {
assert(stex->handle);
/* We are about to render into a surface that has not been validated.
@@ -586,7 +591,7 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
* content when the associated mob is first bound to the surface.
*/
SVGA_RETRY(svga, SVGA3D_InvalidateGBSurface(svga->swc, stex->handle));
- stex->validated = TRUE;
+ stex->surface_state = SVGA_SURFACE_STATE_INVALIDATED;
}
desc.tex.mipSlice = s->real_level;
@@ -594,38 +599,48 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
desc.tex.arraySize =
s->base.u.tex.last_layer - s->base.u.tex.first_layer + 1;
- s->view_id = util_bitmask_add(svga->surface_view_id_bm);
-
resType = svga_resource_type(s->base.texture->target);
if (util_format_is_depth_or_stencil(s->base.format)) {
- ret = SVGA3D_vgpu10_DefineDepthStencilView(svga->swc,
- s->view_id,
- s->handle,
- s->key.format,
- resType,
- &desc);
- }
- else {
- SVGA3dSurfaceFormat view_format = s->key.format;
- const struct svga_texture *stex = svga_texture(s->base.texture);
- /* Can't create RGBA render target view of a RGBX surface so adjust
- * the view format. We do something similar for texture samplers in
- * svga_validate_pipe_sampler_view().
+ /* Create depth stencil view only if the resource is created
+ * with depth stencil bind flag.
*/
- if (view_format == SVGA3D_B8G8R8A8_UNORM &&
- (stex->key.format == SVGA3D_B8G8R8X8_UNORM ||
- stex->key.format == SVGA3D_B8G8R8X8_TYPELESS)) {
- view_format = SVGA3D_B8G8R8X8_UNORM;
+ if (stex->key.flags & SVGA3D_SURFACE_BIND_DEPTH_STENCIL) {
+ s->view_id = util_bitmask_add(svga->surface_view_id_bm);
+ ret = SVGA3D_vgpu10_DefineDepthStencilView(svga->swc,
+ s->view_id,
+ s->handle,
+ s->key.format,
+ resType,
+ &desc);
}
+ }
+ else {
+ /* Create render target view only if the resource is created
+ * with render target bind flag.
+ */
+ if (stex->key.flags & SVGA3D_SURFACE_BIND_RENDER_TARGET) {
+ SVGA3dSurfaceFormat view_format = s->key.format;
+
+ /* Can't create RGBA render target view of a RGBX surface so adjust
+ * the view format. We do something similar for texture samplers in
+ * svga_validate_pipe_sampler_view().
+ */
+ if (view_format == SVGA3D_B8G8R8A8_UNORM &&
+ (stex->key.format == SVGA3D_B8G8R8X8_UNORM ||
+ stex->key.format == SVGA3D_B8G8R8X8_TYPELESS)) {
+ view_format = SVGA3D_B8G8R8X8_UNORM;
+ }
- ret = SVGA3D_vgpu10_DefineRenderTargetView(svga->swc,
- s->view_id,
- s->handle,
- view_format,
- resType,
- &desc);
+ s->view_id = util_bitmask_add(svga->surface_view_id_bm);
+ ret = SVGA3D_vgpu10_DefineRenderTargetView(svga->swc,
+ s->view_id,
+ s->handle,
+ view_format,
+ resType,
+ &desc);
+ }
}
if (ret != PIPE_OK) {
@@ -664,7 +679,9 @@ svga_surface_destroy(struct pipe_context *pipe,
*/
if (s->handle != t->handle && s->handle != t->backed_handle) {
SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle);
- svga_screen_surface_destroy(ss, &s->key, &s->handle);
+ svga_screen_surface_destroy(ss, &s->key,
+ svga_was_texture_rendered_to(t),
+ &s->handle);
}
if (s->view_id != SVGA3D_INVALID_ID) {
@@ -706,7 +723,7 @@ svga_mark_surface_dirty(struct pipe_surface *surf)
struct svga_texture *tex = svga_texture(surf->texture);
if (!s->dirty) {
- s->dirty = TRUE;
+ s->dirty = true;
if (s->handle == tex->handle) {
/* hmm so 3d textures always have all their slices marked ? */
@@ -762,7 +779,7 @@ svga_mark_surfaces_dirty(struct svga_context *svga)
*/
void
svga_propagate_surface(struct svga_context *svga, struct pipe_surface *surf,
- boolean reset)
+ bool reset)
{
struct svga_surface *s = svga_surface(surf);
struct svga_texture *tex = svga_texture(surf->texture);
@@ -876,12 +893,12 @@ svga_propagate_rendertargets(struct svga_context *svga)
for (i = 0; i < svga->state.hw_clear.num_rendertargets; i++) {
struct pipe_surface *s = svga->state.hw_clear.rtv[i];
if (s) {
- svga_propagate_surface(svga, s, FALSE);
+ svga_propagate_surface(svga, s, false);
}
}
if (svga->state.hw_clear.dsv) {
- svga_propagate_surface(svga, svga->state.hw_clear.dsv, FALSE);
+ svga_propagate_surface(svga, svga->state.hw_clear.dsv, false);
}
}
@@ -889,7 +906,7 @@ svga_propagate_rendertargets(struct svga_context *svga)
/**
* Check if we should call svga_propagate_surface on the surface.
*/
-boolean
+bool
svga_surface_needs_propagation(const struct pipe_surface *surf)
{
const struct svga_surface *s = svga_surface_const(surf);