...
 
Commits (4)
......@@ -42,12 +42,17 @@ static void *virgl_buffer_transfer_map(struct pipe_context *ctx,
bool readback;
bool flush = false;
if (vbuf->discarded) {
usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
vbuf->discarded = false;
}
trans = virgl_resource_create_transfer(&vctx->transfer_pool, resource,
&vbuf->metadata, level, usage, box);
if (usage & PIPE_TRANSFER_READ)
flush = true;
else
flush = virgl_res_needs_flush(vctx, trans);
flush = virgl_res_needs_flush(vctx, trans, false);
if (flush)
ctx->flush(ctx, NULL, 0);
......
......@@ -514,6 +514,9 @@ static void virgl_set_constant_buffer(struct pipe_context *ctx,
}
}
static void virgl_flush_eq(struct virgl_context *ctx, void *closure,
struct pipe_fence_handle **fence);
void virgl_transfer_inline_write(struct pipe_context *ctx,
struct pipe_resource *res,
unsigned level,
......@@ -536,13 +539,12 @@ void virgl_transfer_inline_write(struct pipe_context *ctx,
trans.base.layer_stride = layer_stride;
trans.offset = box->x;
virgl_resource_dirty(grres, 0);
if (virgl_res_needs_flush(vctx, &trans)) {
if (virgl_res_needs_flush(vctx, &trans, true)) {
ctx->flush(ctx, NULL, 0);
vs->vws->resource_wait(vs->vws, grres->hw_res);
}
virgl_resource_dirty(grres, 0);
virgl_encoder_inline_write(vctx, grres, level, usage,
box, data, stride, layer_stride);
}
......@@ -1234,6 +1236,15 @@ static void virgl_get_sample_position(struct pipe_context *ctx,
index, sample_count, out_value[0], out_value[1]);
}
static void
virgl_invalidate_resource(struct pipe_context *ctx,
struct pipe_resource *resource)
{
struct virgl_resource *res = virgl_resource(resource);
res->clean_mask = ~0;
res->discarded = true;
}
struct pipe_context *virgl_context_create(struct pipe_screen *pscreen,
void *priv,
unsigned flags)
......@@ -1329,6 +1340,9 @@ struct pipe_context *virgl_context_create(struct pipe_screen *pscreen,
vctx->base.set_shader_images = virgl_set_shader_images;
vctx->base.memory_barrier = virgl_memory_barrier;
vctx->base.invalidate_resource = virgl_invalidate_resource;
virgl_init_context_resource_functions(&vctx->base);
virgl_init_query_functions(vctx);
virgl_init_so_functions(vctx);
......
......@@ -28,7 +28,7 @@
#include "virgl_screen.h"
bool virgl_res_needs_flush(struct virgl_context *vctx,
struct virgl_transfer *trans)
struct virgl_transfer *trans, bool is_inline)
{
struct virgl_screen *vs = virgl_screen(vctx->base.screen);
struct virgl_resource *res = virgl_resource(trans->base.resource);
......@@ -40,7 +40,7 @@ bool virgl_res_needs_flush(struct virgl_context *vctx,
if (res->clean_mask & (1 << trans->base.level)) {
if (vctx->num_draws == 0 && vctx->num_compute == 0)
return false;
if (!virgl_transfer_queue_is_queued(&vctx->queue, trans))
if (!is_inline && !virgl_transfer_queue_is_queued(&vctx->queue, trans))
return false;
}
......@@ -54,7 +54,8 @@ bool virgl_res_needs_readback(struct virgl_context *vctx,
bool readback = true;
if (res->clean_mask & (1 << level))
readback = false;
else if (usage & PIPE_TRANSFER_DISCARD_RANGE)
else if (usage & PIPE_TRANSFER_DISCARD_RANGE ||
usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE)
readback = false;
else if ((usage & (PIPE_TRANSFER_WRITE | PIPE_TRANSFER_FLUSH_EXPLICIT)) ==
(PIPE_TRANSFER_WRITE | PIPE_TRANSFER_FLUSH_EXPLICIT))
......@@ -138,12 +139,18 @@ static void virgl_buffer_subdata(struct pipe_context *pipe,
unsigned size, const void *data)
{
struct pipe_box box;
struct virgl_resource *res = virgl_resource(resource);
if (offset == 0 && size == resource->width0)
usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
else
usage |= PIPE_TRANSFER_DISCARD_RANGE;
if (res->discarded) {
usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
res->discarded = false;
}
u_box_1d(offset, size, &box);
if (resource->width0 >= getpagesize())
......
......@@ -48,6 +48,7 @@ struct virgl_resource_metadata
struct virgl_resource {
struct u_resource u;
uint16_t clean_mask;
bool discarded;
struct virgl_hw_res *hw_res;
struct virgl_resource_metadata metadata;
};
......@@ -117,7 +118,7 @@ static inline unsigned pipe_to_virgl_bind(const struct virgl_screen *vs, unsigne
}
bool virgl_res_needs_flush(struct virgl_context *vctx,
struct virgl_transfer *transfer);
struct virgl_transfer *transfer, bool is_inline);
bool virgl_res_needs_readback(struct virgl_context *vctx,
struct virgl_resource *res,
unsigned usage, unsigned level);
......
......@@ -275,6 +275,8 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
return !!(vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_MULTI_DRAW_INDIRECT);
case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
return !!(vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_INDIRECT_PARAMS);
case PIPE_CAP_INVALIDATE_BUFFER:
return 1;
case PIPE_CAP_TEXTURE_GATHER_SM5:
case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
......@@ -291,7 +293,6 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
case PIPE_CAP_INVALIDATE_BUFFER:
case PIPE_CAP_GENERATE_MIPMAP:
case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
case PIPE_CAP_STRING_MARKER:
......
......@@ -134,7 +134,7 @@ static void *texture_transfer_map_plain(struct pipe_context *ctx,
assert(resource->nr_samples <= 1);
flush = virgl_res_needs_flush(vctx, trans);
flush = virgl_res_needs_flush(vctx, trans, false);
if (flush)
ctx->flush(ctx, NULL, 0);
......@@ -269,6 +269,12 @@ static void *virgl_texture_transfer_map(struct pipe_context *ctx,
const struct pipe_box *box,
struct pipe_transfer **transfer)
{
struct virgl_resource *res = virgl_resource(resource);
if (res->discarded) {
usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
res->discarded = false;
}
if (needs_resolve(ctx->screen, resource, usage))
return texture_transfer_map_resolve(ctx, resource, level, usage, box,
transfer);
......