#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "os/os_thread.h"
-#include "util/u_format.h"
+#include "util/format/u_format.h"
#include "util/u_inlines.h"
#include "util/u_math.h"
#include "util/u_memory.h"
{
struct svga_texture *texture = svga_texture(st->base.resource);
SVGA3dCopyBox box;
- enum pipe_error ret;
assert(!st->use_direct_map);
(util_format_get_blockwidth(texture->b.b.format)
* util_format_get_blockheight(texture->b.b.format)));
- ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
- assert(ret == PIPE_OK);
- }
+ SVGA_RETRY(svga, SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags));
}
-static boolean
+static bool
svga_texture_get_handle(struct pipe_screen *screen,
struct pipe_resource *texture,
struct winsys_handle *whandle)
}
-static enum pipe_error
+static void
readback_image_vgpu9(struct svga_context *svga,
struct svga_winsys_surface *surf,
unsigned slice,
unsigned level)
{
- enum pipe_error ret;
-
- ret = SVGA3D_ReadbackGBImage(svga->swc, surf, slice, level);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_ReadbackGBImage(svga->swc, surf, slice, level);
- }
- return ret;
+ SVGA_RETRY(svga, SVGA3D_ReadbackGBImage(svga->swc, surf, slice, level));
}
-static enum pipe_error
+static void
readback_image_vgpu10(struct svga_context *svga,
struct svga_winsys_surface *surf,
unsigned slice,
unsigned level,
unsigned numMipLevels)
{
- enum pipe_error ret;
unsigned subResource;
subResource = slice * numMipLevels + level;
- ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, surf, subResource);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, surf, subResource);
- }
- return ret;
+ SVGA_RETRY(svga, SVGA3D_vgpu10_ReadbackSubResource(svga->swc, surf,
+ subResource));
}
unsigned usage = st->base.usage;
if (need_tex_readback(st)) {
- enum pipe_error ret;
-
svga_surfaces_flush(svga);
if (!svga->swc->force_coherent || tex->imported) {
for (i = 0; i < st->box.d; i++) {
if (svga_have_vgpu10(svga)) {
- ret = readback_image_vgpu10(svga, surf, st->slice + i, level,
- tex->b.b.last_level + 1);
+ readback_image_vgpu10(svga, surf, st->slice + i, level,
+ tex->b.b.last_level + 1);
} else {
- ret = readback_image_vgpu9(svga, surf, st->slice + i, level);
+ readback_image_vgpu9(svga, surf, st->slice + i, level);
}
}
svga->hud.num_readbacks++;
SVGA_STATS_COUNT_INC(sws, SVGA_STATS_COUNT_TEXREADBACK);
- assert(ret == PIPE_OK);
- (void) ret;
-
svga_context_flush(svga, NULL);
}
/*
{
SVGA3dSize baseLevelSize;
uint8_t *map;
- boolean retry;
+ boolean retry, rebind;
unsigned offset, mip_width, mip_height;
+ struct svga_winsys_context *swc = svga->swc;
+
+ if (swc->force_coherent) {
+ usage |= PIPE_TRANSFER_PERSISTENT | PIPE_TRANSFER_COHERENT;
+ }
+
+ map = SVGA_TRY_MAP(svga->swc->surface_map
+ (svga->swc, surf, usage, &retry, &rebind), retry);
- map = svga->swc->surface_map(svga->swc, surf, usage, &retry);
if (map == NULL && retry) {
/*
* At this point, the svga_surfaces_flush() should already have
* called in svga_texture_get_transfer().
*/
svga->hud.surface_write_flushes++;
+ svga_retry_enter(svga);
+ svga_context_flush(svga, NULL);
+ map = svga->swc->surface_map(svga->swc, surf, usage, &retry, &rebind);
+ svga_retry_exit(svga);
+ }
+
+ if (map && rebind) {
+ enum pipe_error ret;
+
+ ret = SVGA3D_BindGBSurface(swc, surf);
+ if (ret != PIPE_OK) {
+ svga_context_flush(svga, NULL);
+ ret = SVGA3D_BindGBSurface(swc, surf);
+ assert(ret == PIPE_OK);
+ }
svga_context_flush(svga, NULL);
- map = svga->swc->surface_map(svga->swc, surf, usage, &retry);
}
/*
struct svga_transfer *st;
struct svga_winsys_surface *surf = tex->handle;
boolean use_direct_map = svga_have_gb_objects(svga) &&
- !svga_have_gb_dma(svga);
+ (!svga_have_gb_dma(svga) || (usage & PIPE_TRANSFER_WRITE));
void *map = NULL;
int64_t begin = svga_get_time(svga);
pipe_resource_reference(&st->base.resource, texture);
/* If this is the first time mapping to the surface in this
- * command buffer, clear the dirty masks of this surface.
+ * command buffer and there is no pending primitives, clear
+ * the dirty masks of this surface.
*/
- if (sws->surface_is_flushed(sws, surf)) {
+ if (sws->surface_is_flushed(sws, surf) &&
+ (svga_have_vgpu10(svga) ||
+ !svga_hwtnl_has_pending_prim(svga->hwtnl))) {
svga_clear_texture_dirty(tex);
}
swc->surface_unmap(swc, surf, &rebind);
if (rebind) {
- enum pipe_error ret;
- ret = SVGA3D_BindGBSurface(swc, surf);
- if (ret != PIPE_OK) {
- /* flush and retry */
- svga_context_flush(svga, NULL);
- ret = SVGA3D_BindGBSurface(swc, surf);
- assert(ret == PIPE_OK);
- }
- if (swc->force_coherent) {
- ret = SVGA3D_UpdateGBSurface(swc, surf);
- if (ret != PIPE_OK) {
- /* flush and retry */
- svga_context_flush(svga, NULL);
- ret = SVGA3D_UpdateGBSurface(swc, surf);
- assert(ret == PIPE_OK);
- }
- }
+ SVGA_RETRY(svga, SVGA3D_BindGBSurface(swc, surf));
}
}
-static enum pipe_error
+static void
update_image_vgpu9(struct svga_context *svga,
struct svga_winsys_surface *surf,
const SVGA3dBox *box,
unsigned slice,
unsigned level)
{
- enum pipe_error ret;
-
- ret = SVGA3D_UpdateGBImage(svga->swc, surf, box, slice, level);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_UpdateGBImage(svga->swc, surf, box, slice, level);
- }
- return ret;
+ SVGA_RETRY(svga, SVGA3D_UpdateGBImage(svga->swc, surf, box, slice, level));
}
-static enum pipe_error
+static void
update_image_vgpu10(struct svga_context *svga,
struct svga_winsys_surface *surf,
const SVGA3dBox *box,
unsigned level,
unsigned numMipLevels)
{
- enum pipe_error ret;
unsigned subResource;
subResource = slice * numMipLevels + level;
- ret = SVGA3D_vgpu10_UpdateSubResource(svga->swc, surf, box, subResource);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_vgpu10_UpdateSubResource(svga->swc, surf, box, subResource);
- }
- return ret;
+ SVGA_RETRY(svga, SVGA3D_vgpu10_UpdateSubResource(svga->swc, surf, box,
+ subResource));
}
{
struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
- if (st->hwbuf)
+ if (!st->swbuf)
sws->buffer_unmap(sws, st->hwbuf);
if (st->base.usage & PIPE_TRANSFER_WRITE) {
/* Now send an update command to update the content in the backend. */
if (st->base.usage & PIPE_TRANSFER_WRITE) {
struct svga_winsys_surface *surf = tex->handle;
- enum pipe_error ret;
assert(svga_have_gb_objects(svga));
unsigned i;
for (i = 0; i < nlayers; i++) {
- ret = update_image_vgpu10(svga, surf, &box,
- st->slice + i, transfer->level,
- tex->b.b.last_level + 1);
- assert(ret == PIPE_OK);
+ update_image_vgpu10(svga, surf, &box,
+ st->slice + i, transfer->level,
+ tex->b.b.last_level + 1);
}
} else {
assert(nlayers == 1);
- ret = update_image_vgpu9(svga, surf, &box, st->slice,
- transfer->level);
- assert(ret == PIPE_OK);
+ update_image_vgpu9(svga, surf, &box, st->slice,
+ transfer->level);
}
}
- (void) ret;
}
}
/* Verify the number of mipmap levels isn't impossibly large. For example,
* if the base 2D image is 16x16, we can't have 8 mipmap levels.
- * The state tracker should never ask us to create a resource with invalid
+ * the gallium frontend should never ask us to create a resource with invalid
* parameters.
*/
{
* and it always requests PIPE_BIND_RENDER_TARGET, therefore
* passing the SVGA3D_SURFACE_HINT_RENDERTARGET here defeats its purpose.
*
- * However, this was changed since other state trackers
+ * However, this was changed since other gallium frontends
* (XA for example) uses it accurately and certain device versions
* relies on it in certain situations to render correctly.
*/
return NULL;
}
-boolean
+bool
svga_texture_generate_mipmap(struct pipe_context *pipe,
struct pipe_resource *pt,
enum pipe_format format,
struct svga_pipe_sampler_view *sv;
struct svga_context *svga = svga_context(pipe);
struct svga_texture *tex = svga_texture(pt);
- enum pipe_error ret;
assert(svga_have_vgpu10(svga));
/* Only support 2D texture for now */
if (pt->target != PIPE_TEXTURE_2D)
- return FALSE;
+ return false;
/* Fallback to the mipmap generation utility for those formats that
* do not support hw generate mipmap
*/
if (!svga_format_support_gen_mips(format))
- return FALSE;
+ return false;
/* Make sure the texture surface was created with
* SVGA3D_SURFACE_BIND_RENDER_TARGET
*/
if (!tex->handle || !(tex->key.flags & SVGA3D_SURFACE_BIND_RENDER_TARGET))
- return FALSE;
+ return false;
templ.format = format;
templ.u.tex.first_layer = first_layer;
psv = pipe->create_sampler_view(pipe, pt, &templ);
if (psv == NULL)
- return FALSE;
+ return false;
sv = svga_pipe_sampler_view(psv);
- ret = svga_validate_pipe_sampler_view(svga, sv);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = svga_validate_pipe_sampler_view(svga, sv);
- assert(ret == PIPE_OK);
- }
+ SVGA_RETRY(svga, svga_validate_pipe_sampler_view(svga, sv));
- ret = SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle);
- }
+ SVGA_RETRY(svga, SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle));
pipe_sampler_view_reference(&psv, NULL);
svga->hud.num_generate_mipmap++;
- return TRUE;
+ return true;
}
struct svga_winsys_surface *dstsurf;
struct pipe_resource *texture = st->base.resource;
struct svga_texture *tex = svga_texture(texture);
- enum pipe_error ret;
unsigned subResource;
unsigned numMipLevels;
unsigned i, layer;
/* send a transferFromBuffer command to update the host texture surface */
assert((offset & 15) == 0);
- ret = SVGA3D_vgpu10_TransferFromBuffer(svga->swc, srcsurf,
- offset,
- st->base.stride,
- st->base.layer_stride,
- dstsurf, subResource,
- &st->upload.box);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_vgpu10_TransferFromBuffer(svga->swc, srcsurf,
- offset,
- st->base.stride,
- st->base.layer_stride,
- dstsurf, subResource,
- &st->upload.box);
- assert(ret == PIPE_OK);
- }
+ SVGA_RETRY(svga, SVGA3D_vgpu10_TransferFromBuffer(svga->swc, srcsurf,
+ offset,
+ st->base.stride,
+ st->base.layer_stride,
+ dstsurf, subResource,
+ &st->upload.box));
offset += st->base.layer_stride;
/* Set rendered-to flag */