[virglrenderer-devel] [PATCH v3] virgl: Add method to query supported MSAA samples and positions
Gert Wollny
gert.wollny at collabora.com
Thu Jul 5 16:06:45 UTC 2018
Query the number of supported samples and the sample position and
store these to the caps.v2 structure. We support only up to 16 samples.
This implementation requires a GL host backend.
v2: - glTexImage2Dmultisample is not available on a gles 3.1 host
and trying to call it crashed qemu (Jakob Bornecrantz)
Use glTexStorage2DMultisample instead and delete texture each
round because the texture becomes immutable.
- move call to get sample positions only when caps v2 needs to be
filled.
v3: - rebase against master
- take care of nits (Dave)
Signed-off-by: Gert Wollny <gert.wollny at collabora.com>
---
src/virgl_hw.h | 1 +
src/vrend_formats.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
src/vrend_renderer.c | 4 ++++
src/vrend_renderer.h | 3 +++
4 files changed, 52 insertions(+)
diff --git a/src/virgl_hw.h b/src/virgl_hw.h
index 589cd73..44c7108 100644
--- a/src/virgl_hw.h
+++ b/src/virgl_hw.h
@@ -305,6 +305,7 @@ struct virgl_caps_v2 {
uint32_t uniform_buffer_offset_alignment;
uint32_t shader_buffer_offset_alignment;
uint32_t capability_bits;
+ uint32_t sample_locations[8];
};
union virgl_caps {
diff --git a/src/vrend_formats.c b/src/vrend_formats.c
index eb9f217..82a1b5c 100644
--- a/src/vrend_formats.c
+++ b/src/vrend_formats.c
@@ -443,3 +443,47 @@ void vrend_build_format_list_gles(void)
*/
add_formats(gles_z32_format);
}
+
+unsigned vrend_renderer_query_multisample_caps(unsigned max_samples, struct virgl_caps_v2 *caps)
+{
+ GLuint tex;
+ GLuint fbo;
+ GLenum status;
+
+ uint max_samples_confirmed = 1;
+ uint test_num_samples[4] = {2,4,8,16};
+ int out_buf_offsets[4] = {0,1,2,4};
+
+ glGenFramebuffers( 1, &fbo );
+ memset(caps->sample_locations, 0, 8 * sizeof(uint32_t));
+
+ for (int i = 0; i < 4 && test_num_samples[i] <= max_samples; ++i) {
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
+ glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, test_num_samples[i], GL_RGBA32F, 16, 16, GL_TRUE);
+ status = glGetError();
+ if (status == GL_NO_ERROR) {
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex, 0);
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status == GL_FRAMEBUFFER_COMPLETE) {
+ max_samples_confirmed = test_num_samples[i];
+
+ for (uint k = 0; k < test_num_samples[i]; ++k) {
+ float msp[2];
+ uint32_t compressed;
+ glGetMultisamplefv(GL_SAMPLE_POSITION, k, msp);
+ debug_printf("VIRGL: sample postion [%2d/%2d] = (%f, %f)\n",
+ k, test_num_samples[i], msp[0], msp[1]);
+ compressed = ((unsigned)(floor(msp[0] * 16.0f)) & 0xf) << 4;
+ compressed |= ((unsigned)(floor(msp[1] * 16.0f)) & 0xf);
+ caps->sample_locations[out_buf_offsets[i] + (k >> 2)] |= compressed << (8 * (k & 3));
+ }
+ }
+ }
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glDeleteTextures(1, &tex);
+ }
+ glDeleteFramebuffers(1, &fbo);
+ return max_samples_confirmed;
+}
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 23494a8..0e21b10 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -7314,6 +7314,8 @@ static void vrend_renderer_fill_caps_gles(uint32_t set, UNUSED uint32_t version,
/* Not available on GLES */
caps->v2.texture_buffer_offset_alignment = 0;
+
+ caps->v1.max_samples = vrend_renderer_query_multisample_caps(max, &caps->v2);
}
void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
@@ -7540,6 +7542,8 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, (GLint*)&caps->v2.shader_buffer_offset_alignment);
}
+ caps->v1.max_samples = vrend_renderer_query_multisample_caps(max, &caps->v2);
+
caps->v2.capability_bits |= VIRGL_CAP_TGSI_INVARIANT;
if (gl_ver >= 43 || epoxy_has_gl_extension("GL_ARB_texture_view"))
diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h
index d07d11c..f59d45f 100644
--- a/src/vrend_renderer.h
+++ b/src/vrend_renderer.h
@@ -390,6 +390,9 @@ void vrend_renderer_reset(void);
int vrend_renderer_get_poll_fd(void);
void vrend_decode_reset(bool ctx_0_only);
+unsigned vrend_renderer_query_multisample_caps(unsigned max_samples,
+ struct virgl_caps_v2 *caps);
+
struct gl_version {
uint32_t major;
uint32_t minor;
--
2.16.4
More information about the virglrenderer-devel
mailing list