virgl: Add method to query supported MSAA samples and positions

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@collabora.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
macos/master
Gert Wollny 7 years ago committed by Dave Airlie
parent a1160620cc
commit c0e0274e8c
  1. 1
      src/virgl_hw.h
  2. 44
      src/vrend_formats.c
  3. 4
      src/vrend_renderer.c
  4. 3
      src/vrend_renderer.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 {

@ -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;
}

@ -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"))

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

Loading…
Cancel
Save