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);