[virglrenderer-devel] [PATCH 7/9] add framebuffer_no_attachment support

Dave Airlie airlied at gmail.com
Tue Jul 31 22:28:19 UTC 2018


From: Dave Airlie <airlied at redhat.com>

This requires adding new protocol to pass the width/height/layers/sample
default values from the host.

Reviewed-by: Erik Faye-Lund <erik.faye-lund at collabora.com>
---
 src/virgl_hw.h       |  1 +
 src/virgl_protocol.h | 11 +++++++++++
 src/vrend_decode.c   | 24 ++++++++++++++++++++++++
 src/vrend_renderer.c | 21 +++++++++++++++++++++
 src/vrend_renderer.h |  3 +++
 5 files changed, 60 insertions(+)

diff --git a/src/virgl_hw.h b/src/virgl_hw.h
index 661be1e..739500f 100644
--- a/src/virgl_hw.h
+++ b/src/virgl_hw.h
@@ -225,6 +225,7 @@ enum virgl_formats {
 #define VIRGL_CAP_TXQS                 (1 << 5)
 #define VIRGL_CAP_MEMORY_BARRIER       (1 << 6)
 #define VIRGL_CAP_COMPUTE_SHADER       (1 << 7)
+#define VIRGL_CAP_FB_NO_ATTACH         (1 << 8)
 
 /* virgl bind flags - these are compatible with mesa 10.5 gallium.
  * but are fixed, no other should be passed to virgl either.
diff --git a/src/virgl_protocol.h b/src/virgl_protocol.h
index 43c010e..91f1299 100644
--- a/src/virgl_protocol.h
+++ b/src/virgl_protocol.h
@@ -89,6 +89,7 @@ enum virgl_context_cmd {
    VIRGL_CCMD_SET_SHADER_IMAGES,
    VIRGL_CCMD_MEMORY_BARRIER,
    VIRGL_CCMD_LAUNCH_GRID,
+   VIRGL_CCMD_SET_FRAMEBUFFER_STATE_NO_ATTACH,
 };
 
 /*
@@ -528,4 +529,14 @@ enum virgl_context_cmd {
 #define VIRGL_LAUNCH_GRID_Z 6
 #define VIRGL_LAUNCH_INDIRECT_HANDLE 7
 #define VIRGL_LAUNCH_INDIRECT_OFFSET 8
+
+/* framebuffer state no attachment */
+#define VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_SIZE 2
+#define VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_WIDTH_HEIGHT 1
+#define VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_WIDTH(x) (x & 0xffff)
+#define VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_HEIGHT(x) ((x >> 16) & 0xffff)
+#define VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_LAYERS_SAMPLES 2
+#define VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_LAYERS(x) (x & 0xffff)
+#define VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_SAMPLES(x) ((x >> 16) & 0xff)
+
 #endif
diff --git a/src/vrend_decode.c b/src/vrend_decode.c
index e3deb65..4e4dd7c 100644
--- a/src/vrend_decode.c
+++ b/src/vrend_decode.c
@@ -157,6 +157,27 @@ static int vrend_decode_set_framebuffer_state(struct vrend_decode_ctx *ctx, int
    return 0;
 }
 
+static int vrend_decode_set_framebuffer_state_no_attach(struct vrend_decode_ctx *ctx, int length)
+{
+   uint32_t width, height;
+   uint32_t layers, samples;
+   uint32_t tmp;
+
+   if (length != VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_SIZE)
+      return EINVAL;
+
+   tmp = get_buf_entry(ctx, VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_WIDTH_HEIGHT);
+   width = VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_WIDTH(tmp);
+   height = VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_HEIGHT(tmp);
+
+   tmp = get_buf_entry(ctx, VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_LAYERS_SAMPLES);
+   layers = VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_LAYERS(tmp);
+   samples = VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_SAMPLES(tmp);
+
+   vrend_set_framebuffer_state_no_attach(ctx->grctx, width, height, layers, samples);
+   return 0;
+}
+
 static int vrend_decode_clear(struct vrend_decode_ctx *ctx, int length)
 {
    union pipe_color_union color;
@@ -1412,6 +1433,9 @@ int vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw)
       case VIRGL_CCMD_LAUNCH_GRID:
          ret = vrend_decode_launch_grid(gdctx, len);
          break;
+      case VIRGL_CCMD_SET_FRAMEBUFFER_STATE_NO_ATTACH:
+         ret = vrend_decode_set_framebuffer_state_no_attach(gdctx, len);
+         break;
       default:
          ret = EINVAL;
       }
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 3241ac3..58b1f52 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -101,6 +101,7 @@ enum features_id
    feat_debug_cb,
    feat_draw_instance,
    feat_dual_src_blend,
+   feat_fb_no_attach,
    feat_geometry_shader,
    feat_gl_conditional_render,
    feat_gl_prim_restart,
@@ -158,6 +159,7 @@ static const  struct {
    [feat_debug_cb] = { UNAVAIL, UNAVAIL, {} }, /* special case */
    [feat_draw_instance] = { 31, 30, { "GL_ARB_draw_instanced" } },
    [feat_dual_src_blend] = { 33, UNAVAIL, { "GL_ARB_blend_func_extended" } },
+   [feat_fb_no_attach] = { 43, 31, { "GL_ARB_framebuffer_no_attachments" } },
    [feat_geometry_shader] = { 32, UNAVAIL, {} },
    [feat_gl_conditional_render] = { 30, UNAVAIL, {} },
    [feat_gl_prim_restart] = { 31, UNAVAIL, {} },
@@ -2091,6 +2093,22 @@ void vrend_set_framebuffer_state(struct vrend_context *ctx,
    ctx->sub->shader_dirty = true;
 }
 
+void vrend_set_framebuffer_state_no_attach(struct vrend_context *ctx,
+                                           uint32_t width, uint32_t height,
+                                           uint32_t layers, uint32_t samples)
+{
+   if (has_feature(feat_fb_no_attach)) {
+      glFramebufferParameteri(GL_FRAMEBUFFER,
+                              GL_FRAMEBUFFER_DEFAULT_WIDTH, width);
+      glFramebufferParameteri(GL_FRAMEBUFFER,
+                              GL_FRAMEBUFFER_DEFAULT_HEIGHT, height);
+      glFramebufferParameteri(GL_FRAMEBUFFER,
+                              GL_FRAMEBUFFER_DEFAULT_LAYERS, layers);
+      glFramebufferParameteri(GL_FRAMEBUFFER,
+                              GL_FRAMEBUFFER_DEFAULT_SAMPLES, samples);
+   }
+}
+
 /*
  * if the viewport Y scale factor is > 0 then we are rendering to
  * an FBO already so don't need to invert rendering?
@@ -8187,6 +8205,9 @@ void vrend_renderer_fill_caps(uint32_t set, UNUSED uint32_t version,
       caps->v2.capability_bits |= VIRGL_CAP_COMPUTE_SHADER;
    }
 
+   if (has_feature(feat_fb_no_attach))
+      caps->v2.capability_bits |= VIRGL_CAP_FB_NO_ATTACH;
+
    if (has_feature(feat_texture_view))
       caps->v2.capability_bits |= VIRGL_CAP_TEXTURE_VIEW;
 
diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h
index 79f4897..93185c1 100644
--- a/src/vrend_renderer.h
+++ b/src/vrend_renderer.h
@@ -248,6 +248,9 @@ void vrend_launch_grid(struct vrend_context *ctx,
                        uint32_t *grid,
                        uint32_t indirect_handle,
                        uint32_t indirect_offset);
+void vrend_set_framebuffer_state_no_attach(struct vrend_context *ctx,
+                                           uint32_t width, uint32_t height,
+                                           uint32_t layers, uint32_t samples);
 #define VREND_TRANSFER_WRITE 1
 #define VREND_TRANSFER_READ 2
 int vrend_renderer_transfer_iov(const struct vrend_transfer_info *info, int transfer_mode);
-- 
2.14.3



More information about the virglrenderer-devel mailing list