virgl: limit command length to 16 bits
authorGurchetan Singh <gurchetansingh@chromium.org>
Thu, 24 Jan 2019 02:11:41 +0000 (18:11 -0800)
committerGert Wollny <gert.wollny@collabora.com>
Fri, 15 Feb 2019 10:19:05 +0000 (11:19 +0100)
Much of our logic is based around the idea the upper 16 bits
of a command dword can encode the length of the command.

Now that the command buffer >= 2^16 - 1, we should check for
this.

v2: alignment, and only check VIRGL_ENCODE_MAX_DWORDS
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
src/gallium/drivers/virgl/virgl_encode.c
src/gallium/drivers/virgl/virgl_protocol.h

index a4ddc623ef64e43d201a3505db2a29a208f9d38a..fe390ea93fe797d919b1c13fce6e806875c315c6 100644 (file)
@@ -37,6 +37,8 @@
 #include "virgl_resource.h"
 #include "virgl_screen.h"
 
+#define VIRGL_ENCODE_MAX_DWORDS MIN2(VIRGL_MAX_CMDBUF_DWORDS, VIRGL_CMD0_MAX_DWORDS)
+
 static int virgl_encoder_write_cmd_dword(struct virgl_context *ctx,
                                         uint32_t dword)
 {
@@ -295,10 +297,10 @@ int virgl_encode_shader_state(struct virgl_context *ctx,
    while (left_bytes) {
       uint32_t length, offlen;
       int hdr_len = base_hdr_size + (first_pass ? strm_hdr_size : 0);
-      if (ctx->cbuf->cdw + hdr_len + 1 >= VIRGL_MAX_CMDBUF_DWORDS)
+      if (ctx->cbuf->cdw + hdr_len + 1 >= VIRGL_ENCODE_MAX_DWORDS)
          ctx->base.flush(&ctx->base, NULL, 0);
 
-      thispass = (VIRGL_MAX_CMDBUF_DWORDS - ctx->cbuf->cdw - hdr_len - 1) * 4;
+      thispass = (VIRGL_ENCODE_MAX_DWORDS - ctx->cbuf->cdw - hdr_len - 1) * 4;
 
       length = MIN2(thispass, left_bytes);
       len = ((length + 3) / 4) + hdr_len;
@@ -547,7 +549,7 @@ int virgl_encoder_inline_write(struct virgl_context *ctx,
    transfer.base.box = *box;
 
    length = 11 + (size + 3) / 4;
-   if ((ctx->cbuf->cdw + length + 1) > VIRGL_MAX_CMDBUF_DWORDS) {
+   if ((ctx->cbuf->cdw + length + 1) > VIRGL_ENCODE_MAX_DWORDS) {
       if (box->height > 1 || box->depth > 1) {
          debug_printf("inline transfer failed due to multi dimensions and too large\n");
          assert(0);
@@ -556,10 +558,10 @@ int virgl_encoder_inline_write(struct virgl_context *ctx,
 
    left_bytes = size;
    while (left_bytes) {
-      if (ctx->cbuf->cdw + 12 >= VIRGL_MAX_CMDBUF_DWORDS)
+      if (ctx->cbuf->cdw + 12 >= VIRGL_ENCODE_MAX_DWORDS)
          ctx->base.flush(&ctx->base, NULL, 0);
 
-      thispass = (VIRGL_MAX_CMDBUF_DWORDS - ctx->cbuf->cdw - 12) * 4;
+      thispass = (VIRGL_ENCODE_MAX_DWORDS - ctx->cbuf->cdw - 12) * 4;
 
       length = MIN2(thispass, left_bytes);
 
index 62b28bd5d0086750dc646fbf8f9be3f4eb82bff3..c55a8cc20570c095623a99e0cb3f7c6a0324e5e7 100644 (file)
@@ -105,6 +105,7 @@ enum virgl_context_cmd {
 */
 
 #define VIRGL_CMD0(cmd, obj, len) ((cmd) | ((obj) << 8) | ((len) << 16))
+#define VIRGL_CMD0_MAX_DWORDS (((1ULL << 16) - 1) / 4) * 4
 
 /* hw specification */
 #define VIRGL_MAX_COLOR_BUFS 8