diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index a41c53d..677ee63 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -166,8 +166,8 @@ struct pipe_poly_stipple struct pipe_viewport_state { - float scale[4]; - float translate[4]; + float scale[3]; + float translate[3]; }; diff --git a/src/virgl_hw.h b/src/virgl_hw.h index b2d5270..88e214f 100644 --- a/src/virgl_hw.h +++ b/src/virgl_hw.h @@ -220,6 +220,7 @@ struct virgl_caps_v1 { uint32_t prim_mask; uint32_t max_tbo_size; uint32_t max_uniform_blocks; + uint32_t max_viewports; }; union virgl_caps { diff --git a/src/virgl_protocol.h b/src/virgl_protocol.h index 96bef87..76f97d1 100644 --- a/src/virgl_protocol.h +++ b/src/virgl_protocol.h @@ -198,15 +198,14 @@ enum virgl_context_cmd { #define VIRGL_OBJ_SHADER_SO_OUTPUT_DST_OFFSET(x) (((x) & 0xffff) << 16) /* viewport state */ -#define VIRGL_SET_VIEWPORT_STATE_SIZE 8 -#define VIRGL_SET_VIEWPORT_STATE_SCALE_0 1 -#define VIRGL_SET_VIEWPORT_STATE_SCALE_1 2 -#define VIRGL_SET_VIEWPORT_STATE_SCALE_2 3 -#define VIRGL_SET_VIEWPORT_STATE_SCALE_3 4 -#define VIRGL_SET_VIEWPORT_STATE_TRANSLATE_0 5 -#define VIRGL_SET_VIEWPORT_STATE_TRANSLATE_1 6 -#define VIRGL_SET_VIEWPORT_STATE_TRANSLATE_2 7 -#define VIRGL_SET_VIEWPORT_STATE_TRANSLATE_3 8 +#define VIRGL_SET_VIEWPORT_STATE_SIZE(num_viewports) ((6 * num_viewports) + 1) +#define VIRGL_SET_VIEWPORT_START_SLOT 1 +#define VIRGL_SET_VIEWPORT_STATE_SCALE_0(x) (2 + (x * 6)) +#define VIRGL_SET_VIEWPORT_STATE_SCALE_1(x) (3 + (x * 6)) +#define VIRGL_SET_VIEWPORT_STATE_SCALE_2(x) (4 + (x * 6)) +#define VIRGL_SET_VIEWPORT_STATE_TRANSLATE_0(x) (5 + (x * 6)) +#define VIRGL_SET_VIEWPORT_STATE_TRANSLATE_1(x) (6 + (x * 6)) +#define VIRGL_SET_VIEWPORT_STATE_TRANSLATE_2(x) (7 + (x * 6)) /* framebuffer state */ #define VIRGL_SET_FRAMEBUFFER_STATE_SIZE(nr_cbufs) (nr_cbufs + 2) @@ -333,9 +332,10 @@ enum virgl_context_cmd { #define VIRGL_SET_BLEND_COLOR(x) ((x) + 1) /* set scissor state */ -#define VIRGL_SET_SCISSOR_STATE_SIZE 2 -#define VIRGL_SET_SCISSOR_MINX_MINY 1 -#define VIRGL_SET_SCISSOR_MAXX_MAXY 2 +#define VIRGL_SET_SCISSOR_STATE_SIZE(x) (1 + 2 * x) +#define VIRGL_SET_SCISSOR_START_SLOT 1 +#define VIRGL_SET_SCISSOR_MINX_MINY(x) (2 + (x * 2)) +#define VIRGL_SET_SCISSOR_MAXX_MAXY(x) (3 + (x * 3)) /* resource copy region */ #define VIRGL_CMD_RESOURCE_COPY_REGION_SIZE 13 diff --git a/src/vrend_decode.c b/src/vrend_decode.c index cd45591..87e247d 100644 --- a/src/vrend_decode.c +++ b/src/vrend_decode.c @@ -187,18 +187,28 @@ static float uif(unsigned int ui) static int vrend_decode_set_viewport_state(struct vrend_decode_ctx *ctx, int length) { - struct pipe_viewport_state vps; - int i; + struct pipe_viewport_state vps[PIPE_MAX_VIEWPORTS]; + int i, v; + int num_viewports, start_slot; + if (length < 1) + return EINVAL; - if (length != VIRGL_SET_VIEWPORT_STATE_SIZE) + if ((length - 1) % 6) return EINVAL; - for (i = 0; i < 4; i++) - vps.scale[i] = uif(get_buf_entry(ctx, VIRGL_SET_VIEWPORT_STATE_SCALE_0 + i)); - for (i = 0; i < 4; i++) - vps.translate[i] = uif(get_buf_entry(ctx, VIRGL_SET_VIEWPORT_STATE_TRANSLATE_0 + i)); + num_viewports = (length - 1) / 6; + if (num_viewports > PIPE_MAX_VIEWPORTS) + return EINVAL; + + start_slot = get_buf_entry(ctx, VIRGL_SET_VIEWPORT_START_SLOT); + for (v = 0; v < num_viewports; v++) { + for (i = 0; i < 3; i++) + vps[v].scale[i] = uif(get_buf_entry(ctx, VIRGL_SET_VIEWPORT_STATE_SCALE_0(v) + i)); + for (i = 0; i < 3; i++) + vps[v].translate[i] = uif(get_buf_entry(ctx, VIRGL_SET_VIEWPORT_STATE_TRANSLATE_0(v) + i)); + } - vrend_set_viewport_state(ctx->grctx, &vps); + vrend_set_viewport_states(ctx->grctx, start_slot, num_viewports, vps); return 0; } @@ -748,21 +758,33 @@ static int vrend_decode_set_blend_color(struct vrend_decode_ctx *ctx, int length static int vrend_decode_set_scissor_state(struct vrend_decode_ctx *ctx, int length) { - struct pipe_scissor_state ss; + struct pipe_scissor_state ss[PIPE_MAX_VIEWPORTS]; uint32_t temp; + int num_scissor, start_slot; + int s; + if (length < 1) + return EINVAL; - if (length != VIRGL_SET_SCISSOR_STATE_SIZE) + if ((length - 1) % 2) return EINVAL; - temp = get_buf_entry(ctx, VIRGL_SET_SCISSOR_MINX_MINY); - ss.minx = temp & 0xffff; - ss.miny = (temp >> 16) & 0xffff; + num_scissor = (length - 1) / 2; + if (num_scissor > PIPE_MAX_VIEWPORTS) + return EINVAL; - temp = get_buf_entry(ctx, VIRGL_SET_SCISSOR_MAXX_MAXY); - ss.maxx = temp & 0xffff; - ss.maxy = (temp >> 16) & 0xffff; + start_slot = get_buf_entry(ctx, VIRGL_SET_SCISSOR_START_SLOT); + + for (s = 0; s < num_scissor; s++) { + temp = get_buf_entry(ctx, VIRGL_SET_SCISSOR_MINX_MINY(s)); + ss[s].minx = temp & 0xffff; + ss[s].miny = (temp >> 16) & 0xffff; + + temp = get_buf_entry(ctx, VIRGL_SET_SCISSOR_MAXX_MAXY(s)); + ss[s].maxx = temp & 0xffff; + ss[s].maxy = (temp >> 16) & 0xffff; + } - vrend_set_scissor_state(ctx->grctx, &ss); + vrend_set_scissor_state(ctx->grctx, &ss[0]); return 0; } diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index 8a7981f..7d5727f 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -1331,8 +1331,10 @@ void vrend_set_framebuffer_state(struct vrend_context *ctx, * if the viewport Y scale factor is > 0 then we are rendering to * an FBO already so don't need to invert rendering? */ -void vrend_set_viewport_state(struct vrend_context *ctx, - const struct pipe_viewport_state *state) +void vrend_set_viewport_states(struct vrend_context *ctx, + int start_slots, + int num_viewports, + const struct pipe_viewport_state *state) { /* convert back to glViewport */ GLint x, y; @@ -5204,6 +5206,9 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version, caps->v1.max_tbo_size = max; } + /* initial support */ + caps->v1.max_viewports = 1; + caps->v1.prim_mask = (1 << PIPE_PRIM_POINTS) | (1 << PIPE_PRIM_LINES) | (1 << PIPE_PRIM_LINE_STRIP) | (1 << PIPE_PRIM_LINE_LOOP) | (1 << PIPE_PRIM_TRIANGLES) | (1 << PIPE_PRIM_TRIANGLE_STRIP) | (1 << PIPE_PRIM_TRIANGLE_FAN); if (use_core_profile == 0) { caps->v1.prim_mask |= (1 << PIPE_PRIM_QUADS) | (1 << PIPE_PRIM_QUAD_STRIP) | (1 << PIPE_PRIM_POLYGON); diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h index 6e28f3a..f77a533 100644 --- a/src/vrend_renderer.h +++ b/src/vrend_renderer.h @@ -213,8 +213,9 @@ 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); +void vrend_set_viewport_states(struct vrend_context *ctx, + int start_slot, int num_viewports, + const struct pipe_viewport_state *state); void vrend_set_num_sampler_views(struct vrend_context *ctx, uint32_t shader_type, uint32_t start_slot, diff --git a/tests/testvirgl_encode.c b/tests/testvirgl_encode.c index 8829977..7f61f8d 100644 --- a/tests/testvirgl_encode.c +++ b/tests/testvirgl_encode.c @@ -278,10 +278,11 @@ int virgl_encoder_set_viewport_state(struct virgl_context *ctx, const struct pipe_viewport_state *state) { int i; - virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_VIEWPORT_STATE, 0, VIRGL_SET_VIEWPORT_STATE_SIZE)); - for (i = 0; i < 4; i++) + virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_VIEWPORT_STATE, 0, VIRGL_SET_VIEWPORT_STATE_SIZE(1))); + virgl_encoder_write_dword(ctx->cbuf, 0); + for (i = 0; i < 3; i++) virgl_encoder_write_dword(ctx->cbuf, fui(state->scale[i])); - for (i = 0; i < 4; i++) + for (i = 0; i < 3; i++) virgl_encoder_write_dword(ctx->cbuf, fui(state->translate[i])); return 0; } @@ -640,11 +641,17 @@ int virgl_encoder_set_blend_color(struct virgl_context *ctx, } int virgl_encoder_set_scissor_state(struct virgl_context *ctx, + int start_slot, + int num_scissors, const struct pipe_scissor_state *ss) { - virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_SCISSOR_STATE, 0, VIRGL_SET_SCISSOR_STATE_SIZE)); - virgl_encoder_write_dword(ctx->cbuf, (ss->minx | ss->miny << 16)); - virgl_encoder_write_dword(ctx->cbuf, (ss->maxx | ss->maxy << 16)); + int s; + virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_SCISSOR_STATE, 0, VIRGL_SET_SCISSOR_STATE_SIZE(num_scissors))); + virgl_encoder_write_dword(ctx->cbuf, start_slot); + for (s = 0; s < num_scissors; s++) { + virgl_encoder_write_dword(ctx->cbuf, (ss[s].minx | ss[s].miny << 16)); + virgl_encoder_write_dword(ctx->cbuf, (ss[s].maxx | ss[s].maxy << 16)); + } return 0; } diff --git a/tests/testvirgl_encode.h b/tests/testvirgl_encode.h index f463a4a..aedca3a 100644 --- a/tests/testvirgl_encode.h +++ b/tests/testvirgl_encode.h @@ -159,7 +159,9 @@ int virgl_encoder_set_blend_color(struct virgl_context *ctx, const struct pipe_blend_color *color); int virgl_encoder_set_scissor_state(struct virgl_context *ctx, - const struct pipe_scissor_state *ss); + int start_slot, + int num_scissors, + const struct pipe_scissor_state *ss); void virgl_encoder_set_polygon_stipple(struct virgl_context *ctx, const struct pipe_poly_stipple *ps);