diff options
author | Dave Airlie <airlied@redhat.com> | 2015-01-15 16:03:37 +1300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-01-21 13:38:32 +1300 |
commit | 3c4909c12758b23dabe0286c6a341e4cf47ffd5a (patch) | |
tree | 3f5a37e2c77da67045396cd84ec41715684426a7 | |
parent | 06a4e627c85d212be8132dc95cd1c173e4200a44 (diff) |
renderer: start adding better error handling
-rw-r--r-- | src/gallium/renderer/vrend_decode.c | 164 | ||||
-rw-r--r-- | src/gallium/renderer/vrend_renderer.c | 141 | ||||
-rw-r--r-- | src/gallium/renderer/vrend_renderer.h | 47 |
3 files changed, 232 insertions, 120 deletions
diff --git a/src/gallium/renderer/vrend_decode.c b/src/gallium/renderer/vrend_decode.c index 10eda8cfdbf..25541a056b7 100644 --- a/src/gallium/renderer/vrend_decode.c +++ b/src/gallium/renderer/vrend_decode.c @@ -24,6 +24,7 @@ #include <stdint.h> #include <string.h> #include <stdio.h> +#include <errno.h> #include <epoxy/gl.h> #include "util/u_memory.h" @@ -70,9 +71,10 @@ static int vrend_decode_create_shader(struct vrend_decode_ctx *ctx, uint32_t typ uint32_t shader_offset; unsigned num_tokens; uint8_t *shd_text; - if (!state) - return NULL; + if (!state) + return ENOMEM; + num_tokens = get_buf_entry(ctx, VIRGL_OBJ_SHADER_NUM_TOKENS); if (num_tokens == 0) @@ -81,7 +83,7 @@ static int vrend_decode_create_shader(struct vrend_decode_ctx *ctx, uint32_t typ tokens = calloc(num_tokens + 10, sizeof(struct tgsi_token)); if (!tokens) { free(state); - return -1; + return ENOMEM; } state->stream_output.num_outputs = get_buf_entry(ctx, VIRGL_OBJ_SHADER_SO_NUM_OUTPUTS); @@ -108,7 +110,7 @@ static int vrend_decode_create_shader(struct vrend_decode_ctx *ctx, uint32_t typ fprintf(stderr,"failed to translate\n %s\n", shd_text); free(tokens); free(state); - return -1; + return EINVAL; } state->tokens = tokens; @@ -125,17 +127,19 @@ static int vrend_decode_create_shader(struct vrend_decode_ctx *ctx, uint32_t typ return 0; } -static int vrend_decode_create_stream_output_target(struct vrend_decode_ctx *ctx, uint32_t handle) +static int vrend_decode_create_stream_output_target(struct vrend_decode_ctx *ctx, uint32_t handle, uint16_t length) { uint32_t res_handle, buffer_size, buffer_offset; + if (length != VIRGL_OBJ_STREAMOUT_SIZE) + return EINVAL; + res_handle = get_buf_entry(ctx, VIRGL_OBJ_STREAMOUT_RES_HANDLE); buffer_offset = get_buf_entry(ctx, VIRGL_OBJ_STREAMOUT_BUFFER_OFFSET); buffer_size = get_buf_entry(ctx, VIRGL_OBJ_STREAMOUT_BUFFER_SIZE); - vrend_create_so_target(ctx->grctx, handle, res_handle, buffer_offset, - buffer_size); - return 0; + return vrend_create_so_target(ctx->grctx, handle, res_handle, buffer_offset, + buffer_size); } static void vrend_decode_set_framebuffer_state(struct vrend_decode_ctx *ctx) @@ -287,11 +291,20 @@ static void vrend_decode_draw_vbo(struct vrend_decode_ctx *ctx) vrend_draw_vbo(ctx->grctx, &info); } -static void vrend_decode_create_blend(struct vrend_decode_ctx *ctx, uint32_t handle, uint16_t length) +static int vrend_decode_create_blend(struct vrend_decode_ctx *ctx, uint32_t handle, uint16_t length) { - struct pipe_blend_state *blend_state = CALLOC_STRUCT(pipe_blend_state); + struct pipe_blend_state *blend_state; uint32_t tmp; int i; + + if (length != VIRGL_OBJ_BLEND_SIZE) { + return EINVAL; + } + + blend_state = CALLOC_STRUCT(pipe_blend_state); + if (!blend_state) + return ENOMEM; + tmp = get_buf_entry(ctx, VIRGL_OBJ_BLEND_S0); blend_state->independent_blend_enable = (tmp & 1); blend_state->logicop_enable = (tmp >> 1) & 0x1; @@ -314,15 +327,27 @@ static void vrend_decode_create_blend(struct vrend_decode_ctx *ctx, uint32_t han blend_state->rt[i].colormask = (tmp >> 27) & 0xf; } - vrend_renderer_object_insert(ctx->grctx, blend_state, sizeof(struct pipe_blend_state), handle, - VIRGL_OBJECT_BLEND); + tmp = vrend_renderer_object_insert(ctx->grctx, blend_state, sizeof(struct pipe_blend_state), handle, + VIRGL_OBJECT_BLEND); + if (tmp == 0) { + FREE(blend_state); + return ENOMEM; + } + return 0; } -static void vrend_decode_create_dsa(struct vrend_decode_ctx *ctx, uint32_t handle, uint16_t length) +static int vrend_decode_create_dsa(struct vrend_decode_ctx *ctx, uint32_t handle, uint16_t length) { int i; - struct pipe_depth_stencil_alpha_state *dsa_state = CALLOC_STRUCT(pipe_depth_stencil_alpha_state); + struct pipe_depth_stencil_alpha_state *dsa_state; uint32_t tmp; + + if (length != VIRGL_OBJ_DSA_SIZE) + return EINVAL; + + dsa_state = CALLOC_STRUCT(pipe_depth_stencil_alpha_state); + if (!dsa_state) + return ENOMEM; tmp = get_buf_entry(ctx, VIRGL_OBJ_DSA_S0); dsa_state->depth.enabled = tmp & 0x1; @@ -346,15 +371,27 @@ static void vrend_decode_create_dsa(struct vrend_decode_ctx *ctx, uint32_t handl tmp = get_buf_entry(ctx, VIRGL_OBJ_DSA_ALPHA_REF); dsa_state->alpha.ref_value = uif(tmp); - vrend_renderer_object_insert(ctx->grctx, dsa_state, sizeof(struct pipe_depth_stencil_alpha_state), handle, - VIRGL_OBJECT_DSA); + tmp = vrend_renderer_object_insert(ctx->grctx, dsa_state, sizeof(struct pipe_depth_stencil_alpha_state), handle, + VIRGL_OBJECT_DSA); + if (tmp == 0) { + FREE(dsa_state); + return ENOMEM; + } + return 0; } -static void vrend_decode_create_rasterizer(struct vrend_decode_ctx *ctx, uint32_t handle, uint16_t length) +static int vrend_decode_create_rasterizer(struct vrend_decode_ctx *ctx, uint32_t handle, uint16_t length) { - struct pipe_rasterizer_state *rs_state = CALLOC_STRUCT(pipe_rasterizer_state); + struct pipe_rasterizer_state *rs_state; uint32_t tmp; + if (length != VIRGL_OBJ_RS_SIZE) + return EINVAL; + + rs_state = CALLOC_STRUCT(pipe_rasterizer_state); + if (!rs_state) + return ENOMEM; + tmp = get_buf_entry(ctx, VIRGL_OBJ_RS_S0); #define ebit(name, bit) rs_state->name = (tmp >> bit) & 0x1 #define emask(name, bit, mask) rs_state->name = (tmp >> bit) & mask @@ -399,40 +436,55 @@ static void vrend_decode_create_rasterizer(struct vrend_decode_ctx *ctx, uint32_ rs_state->offset_scale = uif(get_buf_entry(ctx, VIRGL_OBJ_RS_OFFSET_SCALE)); rs_state->offset_clamp = uif(get_buf_entry(ctx, VIRGL_OBJ_RS_OFFSET_CLAMP)); - - vrend_renderer_object_insert(ctx->grctx, rs_state, sizeof(struct pipe_rasterizer_state), handle, + tmp = vrend_renderer_object_insert(ctx->grctx, rs_state, sizeof(struct pipe_rasterizer_state), handle, VIRGL_OBJECT_RASTERIZER); + if (tmp == 0) { + FREE(rs_state); + return ENOMEM; + } + return 0; } -static void vrend_decode_create_surface(struct vrend_decode_ctx *ctx, uint32_t handle) +static int vrend_decode_create_surface(struct vrend_decode_ctx *ctx, uint32_t handle, uint16_t length) { uint32_t res_handle, format, val0, val1; + int ret; + + if (length != VIRGL_OBJ_SURFACE_SIZE) + return EINVAL; + res_handle = get_buf_entry(ctx, VIRGL_OBJ_SURFACE_RES_HANDLE); format = get_buf_entry(ctx, VIRGL_OBJ_SURFACE_FORMAT); /* decide later if these are texture or buffer */ val0 = get_buf_entry(ctx, VIRGL_OBJ_SURFACE_BUFFER_FIRST_ELEMENT); val1 = get_buf_entry(ctx, VIRGL_OBJ_SURFACE_BUFFER_LAST_ELEMENT); - vrend_create_surface(ctx->grctx, handle, res_handle, format, val0, val1); + ret = vrend_create_surface(ctx->grctx, handle, res_handle, format, val0, val1); + return ret; } -static void vrend_decode_create_sampler_view(struct vrend_decode_ctx *ctx, uint32_t handle) +static int vrend_decode_create_sampler_view(struct vrend_decode_ctx *ctx, uint32_t handle, uint16_t length) { uint32_t res_handle, format, val0, val1, swizzle_packed; + if (length != VIRGL_OBJ_SAMPLER_VIEW_SIZE) + return EINVAL; + res_handle = get_buf_entry(ctx, VIRGL_OBJ_SAMPLER_VIEW_RES_HANDLE); format = get_buf_entry(ctx, VIRGL_OBJ_SAMPLER_VIEW_FORMAT); val0 = get_buf_entry(ctx, VIRGL_OBJ_SAMPLER_VIEW_BUFFER_FIRST_ELEMENT); val1 = get_buf_entry(ctx, VIRGL_OBJ_SAMPLER_VIEW_BUFFER_LAST_ELEMENT); swizzle_packed = get_buf_entry(ctx, VIRGL_OBJ_SAMPLER_VIEW_SWIZZLE); - vrend_create_sampler_view(ctx->grctx, handle, res_handle, format, val0, val1,swizzle_packed); + return vrend_create_sampler_view(ctx->grctx, handle, res_handle, format, val0, val1,swizzle_packed); } -static void vrend_decode_create_sampler_state(struct vrend_decode_ctx *ctx, uint32_t handle, uint16_t length) +static int vrend_decode_create_sampler_state(struct vrend_decode_ctx *ctx, uint32_t handle, uint16_t length) { struct pipe_sampler_state state; int i; uint32_t tmp; + if (length != VIRGL_OBJ_SAMPLER_STATE_SIZE) + return EINVAL; tmp = get_buf_entry(ctx, VIRGL_OBJ_SAMPLER_STATE_S0); state.wrap_s = tmp & 0x7; state.wrap_t = (tmp >> 3) & 0x7; @@ -449,19 +501,20 @@ static void vrend_decode_create_sampler_state(struct vrend_decode_ctx *ctx, uint for (i = 0; i < 4; i++) state.border_color.ui[i] = get_buf_entry(ctx, VIRGL_OBJ_SAMPLER_STATE_BORDER_COLOR(i)); - vrend_create_sampler_state(ctx->grctx, handle, &state); + return vrend_create_sampler_state(ctx->grctx, handle, &state); } -static void vrend_decode_create_ve(struct vrend_decode_ctx *ctx, uint32_t handle, uint16_t length) +static int vrend_decode_create_ve(struct vrend_decode_ctx *ctx, uint32_t handle, uint16_t length) { struct pipe_vertex_element *ve; int num_elements; int i; + int ret; num_elements = (length - 1) / 4; ve = calloc(num_elements, sizeof(struct pipe_vertex_element)); if (!ve) - return; + return ENOMEM; for (i = 0; i < num_elements; i++) { ve[i].src_offset = get_buf_entry(ctx, VIRGL_OBJ_VERTEX_ELEMENTS_V0_SRC_OFFSET(i)); @@ -470,65 +523,80 @@ static void vrend_decode_create_ve(struct vrend_decode_ctx *ctx, uint32_t handle ve[i].src_format = get_buf_entry(ctx, VIRGL_OBJ_VERTEX_ELEMENTS_V0_SRC_FORMAT(i)); } - vrend_create_vertex_elements_state(ctx->grctx, handle, num_elements, - ve); + ret = vrend_create_vertex_elements_state(ctx->grctx, handle, num_elements, + ve); + if (ret) { + FREE(ve); + } + return ret; } -static void vrend_decode_create_query(struct vrend_decode_ctx *ctx, uint32_t handle) +static int vrend_decode_create_query(struct vrend_decode_ctx *ctx, uint32_t handle, uint16_t length) { uint32_t query_type; uint32_t res_handle; uint32_t offset; + + if (length != VIRGL_OBJ_QUERY_SIZE) + return EINVAL; + query_type = get_buf_entry(ctx, VIRGL_OBJ_QUERY_TYPE); offset = get_buf_entry(ctx, VIRGL_OBJ_QUERY_OFFSET); res_handle = get_buf_entry(ctx, VIRGL_OBJ_QUERY_RES_HANDLE); - vrend_create_query(ctx->grctx, handle, query_type, res_handle, offset); + return vrend_create_query(ctx->grctx, handle, query_type, res_handle, offset); } -static void vrend_decode_create_object(struct vrend_decode_ctx *ctx) +static void vrend_decode_create_object(struct vrend_decode_ctx *ctx, int length) { uint32_t header = get_buf_entry(ctx, VIRGL_OBJ_CREATE_HEADER); uint32_t handle = get_buf_entry(ctx, VIRGL_OBJ_CREATE_HANDLE); - uint16_t length; uint8_t obj_type = (header >> 8) & 0xff; - - length = header >> 16; - + int ret = 0; + /* has to be at least 3 length */ + if (length < 3) { + vrend_report_buffer_error(ctx->grctx); + return; + } switch (obj_type){ case VIRGL_OBJECT_BLEND: - vrend_decode_create_blend(ctx, handle, length); + ret = vrend_decode_create_blend(ctx, handle, length); break; case VIRGL_OBJECT_DSA: - vrend_decode_create_dsa(ctx, handle, length); + ret = vrend_decode_create_dsa(ctx, handle, length); break; case VIRGL_OBJECT_RASTERIZER: - vrend_decode_create_rasterizer(ctx, handle, length); + ret = vrend_decode_create_rasterizer(ctx, handle, length); break; case VIRGL_OBJECT_VS: case VIRGL_OBJECT_GS: case VIRGL_OBJECT_FS: - vrend_decode_create_shader(ctx, obj_type, handle, length); + ret = vrend_decode_create_shader(ctx, obj_type, handle, length); break; case VIRGL_OBJECT_VERTEX_ELEMENTS: - vrend_decode_create_ve(ctx, handle, length); + ret = vrend_decode_create_ve(ctx, handle, length); break; case VIRGL_OBJECT_SURFACE: - vrend_decode_create_surface(ctx, handle); + ret = vrend_decode_create_surface(ctx, handle, length); break; case VIRGL_OBJECT_SAMPLER_VIEW: - vrend_decode_create_sampler_view(ctx, handle); + ret = vrend_decode_create_sampler_view(ctx, handle, length); break; case VIRGL_OBJECT_SAMPLER_STATE: - vrend_decode_create_sampler_state(ctx, handle, length); + ret = vrend_decode_create_sampler_state(ctx, handle, length); break; case VIRGL_OBJECT_QUERY: - vrend_decode_create_query(ctx, handle); + ret = vrend_decode_create_query(ctx, handle, length); break; case VIRGL_OBJECT_STREAMOUT_TARGET: - vrend_decode_create_stream_output_target(ctx, handle); + ret = vrend_decode_create_stream_output_target(ctx, handle, length); break; } + + if (ret == EINVAL) { + vrend_report_buffer_error(ctx->grctx); + return; + } } static void vrend_decode_bind_object(struct vrend_decode_ctx *ctx) @@ -879,7 +947,7 @@ void vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw) switch (header & 0xff) { case VIRGL_CCMD_CREATE_OBJECT: - vrend_decode_create_object(gdctx); + vrend_decode_create_object(gdctx, len); break; case VIRGL_CCMD_BIND_OBJECT: vrend_decode_bind_object(gdctx); diff --git a/src/gallium/renderer/vrend_renderer.c b/src/gallium/renderer/vrend_renderer.c index d0095ebfeae..ace49376cd8 100644 --- a/src/gallium/renderer/vrend_renderer.c +++ b/src/gallium/renderer/vrend_renderer.c @@ -25,6 +25,7 @@ #include <epoxy/gl.h> #include <stdio.h> +#include <errno.h> #include "pipe/p_shader_tokens.h" #include "pipe/p_context.h" @@ -883,19 +884,20 @@ static void vrend_apply_sampler_state(struct vrend_context *ctx, void vrend_update_stencil_state(struct vrend_context *ctx); -void vrend_create_surface(struct vrend_context *ctx, - uint32_t handle, - uint32_t res_handle, uint32_t format, - uint32_t val0, uint32_t val1) +int vrend_create_surface(struct vrend_context *ctx, + uint32_t handle, + uint32_t res_handle, uint32_t format, + uint32_t val0, uint32_t val1) { struct vrend_surface *surf; struct vrend_resource *res; + uint32_t ret_handle; res = vrend_renderer_ctx_res_lookup(ctx, res_handle); if (!res) { report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_handle); - return; + return EINVAL; } surf = CALLOC_STRUCT(vrend_surface); @@ -907,7 +909,12 @@ void vrend_create_surface(struct vrend_context *ctx, vrend_resource_reference(&surf->texture, res); - vrend_object_insert(ctx->sub->object_hash, surf, sizeof(*surf), handle, VIRGL_OBJECT_SURFACE); + ret_handle = vrend_renderer_object_insert(ctx, surf, sizeof(*surf), handle, VIRGL_OBJECT_SURFACE); + if (ret_handle == 0) { + FREE(surf); + return ENOMEM; + } + return 0; } static void vrend_destroy_surface_object(void *obj_ptr) @@ -984,14 +991,15 @@ static inline GLenum convert_min_filter(unsigned int filter, unsigned int mip_fi return 0; } -void vrend_create_sampler_state(struct vrend_context *ctx, - uint32_t handle, - struct pipe_sampler_state *templ) +int vrend_create_sampler_state(struct vrend_context *ctx, + uint32_t handle, + struct pipe_sampler_state *templ) { struct vrend_sampler_state *state = CALLOC_STRUCT(vrend_sampler_state); + int ret_handle; if (!state) - return; + return ENOMEM; state->base = *templ; @@ -1011,8 +1019,15 @@ void vrend_create_sampler_state(struct vrend_context *ctx, glSamplerParameterIuiv(state->id, GL_TEXTURE_BORDER_COLOR, templ->border_color.ui); } - vrend_renderer_object_insert(ctx, state, sizeof(struct vrend_sampler_state), handle, - VIRGL_OBJECT_SAMPLER_STATE); + ret_handle = vrend_renderer_object_insert(ctx, state, sizeof(struct vrend_sampler_state), handle, + VIRGL_OBJECT_SAMPLER_STATE); + if (!ret_handle) { + if (vrend_state.have_samplers) + glDeleteSamplers(1, &state->id); + FREE(state); + return ENOMEM; + } + return 0; } static inline GLenum to_gl_swizzle(int swizzle) @@ -1028,21 +1043,25 @@ static inline GLenum to_gl_swizzle(int swizzle) assert(0); return 0; } -void vrend_create_sampler_view(struct vrend_context *ctx, - uint32_t handle, - uint32_t res_handle, uint32_t format, - uint32_t val0, uint32_t val1, uint32_t swizzle_packed) + +int vrend_create_sampler_view(struct vrend_context *ctx, + uint32_t handle, + uint32_t res_handle, uint32_t format, + uint32_t val0, uint32_t val1, uint32_t swizzle_packed) { struct vrend_sampler_view *view; struct vrend_resource *res; - + int ret_handle; res = vrend_renderer_ctx_res_lookup(ctx, res_handle); if (!res) { report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_handle); - return; + return EINVAL; } view = CALLOC_STRUCT(vrend_sampler_view); + if (!view) + return ENOMEM; + pipe_reference_init(&view->reference, 1); view->res_handle = res_handle; view->format = format; @@ -1077,7 +1096,12 @@ void vrend_create_sampler_view(struct vrend_context *ctx, view->gl_swizzle_b = to_gl_swizzle(tex_conv_table[format].swizzle[2]); view->gl_swizzle_a = to_gl_swizzle(tex_conv_table[format].swizzle[3]); } - vrend_object_insert(ctx->sub->object_hash, view, sizeof(*view), handle, VIRGL_OBJECT_SAMPLER_VIEW); + ret_handle = vrend_renderer_object_insert(ctx, view, sizeof(*view), handle, VIRGL_OBJECT_SAMPLER_VIEW); + if (ret_handle == 0) { + FREE(view); + return ENOMEM; + } + return 0; } void vrend_fb_bind_texture(struct vrend_resource *res, @@ -1345,15 +1369,19 @@ void vrend_set_viewport_state(struct vrend_context *ctx, } } -void vrend_create_vertex_elements_state(struct vrend_context *ctx, - uint32_t handle, - unsigned num_elements, - const struct pipe_vertex_element *elements) +int vrend_create_vertex_elements_state(struct vrend_context *ctx, + uint32_t handle, + unsigned num_elements, + const struct pipe_vertex_element *elements) { struct vrend_vertex_element_array *v = CALLOC_STRUCT(vrend_vertex_element_array); const struct util_format_description *desc; GLenum type; int i; + uint32_t ret_handle; + + if (!v) + return ENOMEM; v->count = num_elements; for (i = 0; i < num_elements; i++) { @@ -1399,7 +1427,7 @@ void vrend_create_vertex_elements_state(struct vrend_context *ctx, if (type == GL_FALSE) { report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_VERTEX_FORMAT, elements[i].src_format); FREE(v); - return; + return EINVAL; } v->elements[i].type = type; @@ -1411,8 +1439,13 @@ void vrend_create_vertex_elements_state(struct vrend_context *ctx, v->elements[i].nr_chan = desc->nr_channels; } - vrend_object_insert(ctx->sub->object_hash, v, sizeof(struct vrend_vertex_element), handle, - VIRGL_OBJECT_VERTEX_ELEMENTS); + ret_handle = vrend_renderer_object_insert(ctx, v, sizeof(struct vrend_vertex_element), handle, + VIRGL_OBJECT_VERTEX_ELEMENTS); + if (!ret_handle) { + FREE(v); + return ENOMEM; + } + return 0; } void vrend_bind_vertex_elements_state(struct vrend_context *ctx, @@ -1818,7 +1851,7 @@ void vrend_create_vs(struct vrend_context *ctx, sel = vrend_create_shader_state(ctx, vs, PIPE_SHADER_VERTEX); - vrend_object_insert(ctx->sub->object_hash, sel, sizeof(*sel), handle, VIRGL_OBJECT_VS); + vrend_renderer_object_insert(ctx, sel, sizeof(*sel), handle, VIRGL_OBJECT_VS); return; } @@ -1831,7 +1864,7 @@ void vrend_create_gs(struct vrend_context *ctx, sel = vrend_create_shader_state(ctx, gs, PIPE_SHADER_GEOMETRY); - vrend_object_insert(ctx->sub->object_hash, sel, sizeof(*sel), handle, VIRGL_OBJECT_GS); + vrend_renderer_object_insert(ctx, sel, sizeof(*sel), handle, VIRGL_OBJECT_GS); return; } @@ -1844,7 +1877,7 @@ void vrend_create_fs(struct vrend_context *ctx, sel = vrend_create_shader_state(ctx, fs, PIPE_SHADER_FRAGMENT); - vrend_object_insert(ctx->sub->object_hash, sel, sizeof(*sel), handle, VIRGL_OBJECT_FS); + vrend_renderer_object_insert(ctx, sel, sizeof(*sel), handle, VIRGL_OBJECT_FS); return; } @@ -4694,10 +4727,10 @@ vrend_renderer_object_destroy(struct vrend_context *ctx, uint32_t handle) vrend_object_remove(ctx->sub->object_hash, handle, 0); } -void vrend_renderer_object_insert(struct vrend_context *ctx, void *data, +uint32_t vrend_renderer_object_insert(struct vrend_context *ctx, void *data, uint32_t size, uint32_t handle, enum virgl_object_type type) { - vrend_object_insert(ctx->sub->object_hash, data, size, handle, type); + return vrend_object_insert(ctx->sub->object_hash, data, size, handle, type); } static struct vrend_nontimer_hw_query *vrend_create_hw_query(struct vrend_query *query) @@ -4715,22 +4748,22 @@ static struct vrend_nontimer_hw_query *vrend_create_hw_query(struct vrend_query } -void vrend_create_query(struct vrend_context *ctx, uint32_t handle, - uint32_t query_type, uint32_t res_handle, - uint32_t offset) +int vrend_create_query(struct vrend_context *ctx, uint32_t handle, + uint32_t query_type, uint32_t res_handle, + uint32_t offset) { struct vrend_query *q; struct vrend_resource *res; - + uint32_t ret_handle; res = vrend_renderer_ctx_res_lookup(ctx, res_handle); if (!res) { report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_handle); - return; + return EINVAL; } q = CALLOC_STRUCT(vrend_query); if (!q) - return; + return ENOMEM; list_inithead(&q->waiting_queries); list_inithead(&q->ctx_queries); @@ -4767,8 +4800,13 @@ void vrend_create_query(struct vrend_context *ctx, uint32_t handle, if (vrend_is_timer_query(q->gltype)) glGenQueries(1, &q->timer_query_id); - vrend_renderer_object_insert(ctx, q, sizeof(struct vrend_query), handle, - VIRGL_OBJECT_QUERY); + ret_handle = vrend_renderer_object_insert(ctx, q, sizeof(struct vrend_query), handle, + VIRGL_OBJECT_QUERY); + if (!ret_handle) { + FREE(q); + return ENOMEM; + } + return 0; } static void vrend_destroy_query(struct vrend_query *query) @@ -4899,24 +4937,24 @@ void vrend_render_condition(struct vrend_context *ctx, } -void vrend_create_so_target(struct vrend_context *ctx, - uint32_t handle, - uint32_t res_handle, - uint32_t buffer_offset, - uint32_t buffer_size) +int vrend_create_so_target(struct vrend_context *ctx, + uint32_t handle, + uint32_t res_handle, + uint32_t buffer_offset, + uint32_t buffer_size) { struct vrend_so_target *target; struct vrend_resource *res; - + int ret_handle; res = vrend_renderer_ctx_res_lookup(ctx, res_handle); if (!res) { report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_handle); - return; + return EINVAL; } target = CALLOC_STRUCT(vrend_so_target); if (!target) - return; + return ENOMEM; pipe_reference_init(&target->reference, 1); target->res_handle = res_handle; @@ -4925,8 +4963,13 @@ void vrend_create_so_target(struct vrend_context *ctx, vrend_resource_reference(&target->buffer, res); - vrend_object_insert(ctx->sub->object_hash, target, sizeof(*target), handle, - VIRGL_OBJECT_STREAMOUT_TARGET); + ret_handle = vrend_renderer_object_insert(ctx, target, sizeof(*target), handle, + VIRGL_OBJECT_STREAMOUT_TARGET); + if (ret_handle) { + FREE(target); + return ENOMEM; + } + return 0; } static void vrender_get_glsl_version(int *glsl_version) diff --git a/src/gallium/renderer/vrend_renderer.h b/src/gallium/renderer/vrend_renderer.h index 38571c86f57..348dad90268 100644 --- a/src/gallium/renderer/vrend_renderer.h +++ b/src/gallium/renderer/vrend_renderer.h @@ -153,33 +153,34 @@ void vrend_renderer_resource_create(struct vrend_renderer_resource_create_args * void vrend_renderer_resource_unref(uint32_t handle); -void vrend_create_surface(struct vrend_context *ctx, - uint32_t handle, - uint32_t res_handle, uint32_t format, - uint32_t val0, uint32_t val1); -void vrend_create_sampler_view(struct vrend_context *ctx, +int vrend_create_surface(struct vrend_context *ctx, + uint32_t handle, + uint32_t res_handle, uint32_t format, + uint32_t val0, uint32_t val1); +int vrend_create_sampler_view(struct vrend_context *ctx, + uint32_t handle, + uint32_t res_handle, uint32_t format, + uint32_t val0, uint32_t val1, uint32_t swizzle_packed); + +int vrend_create_sampler_state(struct vrend_context *ctx, uint32_t handle, - uint32_t res_handle, uint32_t format, - uint32_t val0, uint32_t val1, uint32_t swizzle_packed); + struct pipe_sampler_state *templ); -void vrend_create_sampler_state(struct vrend_context *ctx, - uint32_t handle, - struct pipe_sampler_state *templ); +int vrend_create_so_target(struct vrend_context *ctx, + uint32_t handle, + uint32_t res_handle, + uint32_t buffer_offset, + uint32_t buffer_size); -void vrend_create_so_target(struct vrend_context *ctx, - uint32_t handle, - uint32_t res_handle, - uint32_t buffer_offset, - uint32_t buffer_size); void vrend_set_streamout_targets(struct vrend_context *ctx, uint32_t append_bitmask, uint32_t num_targets, uint32_t *handles); -void vrend_create_vertex_elements_state(struct vrend_context *ctx, - uint32_t handle, - unsigned num_elements, - const struct pipe_vertex_element *elements); +int vrend_create_vertex_elements_state(struct vrend_context *ctx, + uint32_t handle, + unsigned num_elements, + const struct pipe_vertex_element *elements); void vrend_bind_vertex_elements_state(struct vrend_context *ctx, uint32_t handle); @@ -298,13 +299,13 @@ void vrend_renderer_check_queries(void); void vrend_stop_current_queries(void); boolean vrend_hw_switch_context(struct vrend_context *ctx, boolean now); -void vrend_renderer_object_insert(struct vrend_context *ctx, void *data, +uint32_t vrend_renderer_object_insert(struct vrend_context *ctx, void *data, uint32_t size, uint32_t handle, enum virgl_object_type type); void vrend_renderer_object_destroy(struct vrend_context *ctx, uint32_t handle); -void vrend_create_query(struct vrend_context *ctx, uint32_t handle, - uint32_t query_type, uint32_t res_handle, - uint32_t offset); +int vrend_create_query(struct vrend_context *ctx, uint32_t handle, + uint32_t query_type, uint32_t res_handle, + uint32_t offset); void vrend_begin_query(struct vrend_context *ctx, uint32_t handle); void vrend_end_query(struct vrend_context *ctx, uint32_t handle); |