renderer: handle resource inline writes using common code

inline resource writes should use common code for transfers
macos/master
Dave Airlie 10 years ago
parent cccbc3b5e4
commit aea7785887
  1. 25
      src/vrend_decode.c
  2. 60
      src/vrend_renderer.c
  3. 34
      src/vrend_renderer.h

@ -287,14 +287,20 @@ static int vrend_decode_set_sampler_views(struct vrend_decode_ctx *ctx, uint16_t
static int vrend_decode_resource_inline_write(struct vrend_decode_ctx *ctx, uint16_t length)
{
struct vrend_transfer_info info;
struct pipe_box box;
uint32_t res_handle = get_buf_entry(ctx, VIRGL_RESOURCE_IW_RES_HANDLE);
uint32_t level, usage, stride, layer_stride;
uint32_t level, usage, stride, layer_stride, data_len;
struct iovec dataiovec;
void *data;
if (length < 12)
return EINVAL;
if (length + ctx->ds->buf_offset > ctx->ds->buf_total)
return EINVAL;
data_len = (length - 11) * 4;
level = get_buf_entry(ctx, VIRGL_RESOURCE_IW_LEVEL);
usage = get_buf_entry(ctx, VIRGL_RESOURCE_IW_USAGE);
stride = get_buf_entry(ctx, VIRGL_RESOURCE_IW_STRIDE);
@ -307,10 +313,21 @@ static int vrend_decode_resource_inline_write(struct vrend_decode_ctx *ctx, uint
box.depth = get_buf_entry(ctx, VIRGL_RESOURCE_IW_D);
data = get_buf_ptr(ctx, VIRGL_RESOURCE_IW_DATA_START);
vrend_transfer_inline_write(ctx->grctx, res_handle, level,
usage, &box, data, stride, layer_stride);
return 0;
info.handle = res_handle;
info.ctx_id = 0;
info.level = level;
info.stride = stride;
info.layer_stride = layer_stride;
info.box = &box;
info.offset = 0;
dataiovec.iov_base = data;
dataiovec.iov_len = data_len;
info.iovec = &dataiovec;
info.iovec_cnt = 1;
return vrend_transfer_inline_write(ctx->grctx, &info, usage);
}
static int vrend_decode_draw_vbo(struct vrend_decode_ctx *ctx, int length)

@ -1674,41 +1674,7 @@ void vrend_set_num_sampler_views(struct vrend_context *ctx,
ctx->sub->views[shader_type].num_views = start_slot + num_sampler_views;
}
void vrend_transfer_inline_write(struct vrend_context *ctx,
uint32_t res_handle,
unsigned level,
unsigned usage,
const struct pipe_box *box,
const void *data,
unsigned stride,
unsigned layer_stride)
{
struct vrend_resource *res;
res = vrend_renderer_ctx_res_lookup(ctx, res_handle);
if (!res) {
report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_handle);
return;
}
if (res->ptr) {
memcpy(res->ptr + box->x, data, box->width);
} else if (res->target == GL_ELEMENT_ARRAY_BUFFER_ARB ||
res->target == GL_ARRAY_BUFFER_ARB ||
res->target == GL_TEXTURE_BUFFER ||
res->target == GL_UNIFORM_BUFFER ||
res->target == GL_TRANSFORM_FEEDBACK_BUFFER) {
glBindBufferARB(res->target, res->id);
glBufferSubData(res->target, box->x, box->width, data);
} else {
GLenum glformat, gltype;
glBindTexture(res->target, res->id);
glformat = tex_conv_table[res->base.format].glformat;
gltype = tex_conv_table[res->base.format].gltype;
glTexSubImage2D(res->target, level, box->x, box->y, box->width, box->height,
glformat, gltype, data);
}
}
static void vrend_destroy_shader_object(void *obj_ptr)
@ -4211,6 +4177,32 @@ int vrend_renderer_transfer_iov(const struct vrend_transfer_info *info,
info);
}
int vrend_transfer_inline_write(struct vrend_context *ctx,
struct vrend_transfer_info *info,
unsigned usage)
{
struct vrend_resource *res;
res = vrend_renderer_ctx_res_lookup(ctx, info->handle);
if (!res) {
report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, info->handle);
return EINVAL;
}
if (!check_transfer_bounds(res, info->level, info->box)) {
report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, info->handle);
return EINVAL;
}
if (!check_iov_bounds(res, info, info->iovec, info->iovec_cnt)) {
report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, info->handle);
return EINVAL;
}
return vrend_renderer_transfer_write_iov(ctx, res, info->iovec, info->iovec_cnt, info);
}
void vrend_set_stencil_ref(struct vrend_context *ctx,
struct pipe_stencil_ref *ref)
{

@ -79,6 +79,18 @@ struct vrend_format_table {
uint8_t swizzle[4];
};
struct vrend_transfer_info {
uint32_t handle;
uint32_t ctx_id;
int level;
uint32_t stride;
uint32_t layer_stride;
struct pipe_box *box;
uint64_t offset;
struct iovec *iovec;
unsigned int iovec_cnt;
};
struct vrend_if_cbs {
void (*write_fence)(unsigned fence_id);
@ -185,14 +197,9 @@ void vrend_set_single_vbo(struct vrend_context *ctx,
void vrend_set_num_vbo(struct vrend_context *ctx,
int num_vbo);
void vrend_transfer_inline_write(struct vrend_context *ctx,
uint32_t res_handle,
unsigned level,
unsigned usage,
const struct pipe_box *box,
const void *data,
unsigned stride,
unsigned layer_stride);
int vrend_transfer_inline_write(struct vrend_context *ctx,
struct vrend_transfer_info *info,
unsigned usage);
void vrend_set_viewport_state(struct vrend_context *ctx,
const struct pipe_viewport_state *state);
@ -222,17 +229,6 @@ void vrend_set_index_buffer(struct vrend_context *ctx,
uint32_t index_size,
uint32_t offset);
struct vrend_transfer_info {
uint32_t handle;
uint32_t ctx_id;
int level;
uint32_t stride;
uint32_t layer_stride;
struct pipe_box *box;
uint64_t offset;
struct iovec *iovec;
unsigned int iovec_cnt;
};
#define VREND_TRANSFER_WRITE 1
#define VREND_TRANSFER_READ 2

Loading…
Cancel
Save