diff --git a/src/vrend_formats.c b/src/vrend_formats.c index 4647c43..2ecdbb4 100644 --- a/src/vrend_formats.c +++ b/src/vrend_formats.c @@ -453,35 +453,47 @@ unsigned vrend_renderer_query_multisample_caps(unsigned max_samples, struct virg uint max_samples_confirmed = 1; uint test_num_samples[4] = {2,4,8,16}; int out_buf_offsets[4] = {0,1,2,4}; + int lowest_working_ms_count_idx = -1; 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) { + for (int i = 3; i >= 0; i--) { + if (test_num_samples[i] > max_samples) + continue; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex); - glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, test_num_samples[i], GL_RGBA32F, 16, 16, GL_TRUE); + glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, test_num_samples[i], GL_RGBA32F, 64, 64, 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]; + if (max_samples_confirmed < test_num_samples[i]) + 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)); } + lowest_working_ms_count_idx = i; + } else { + /* If a framebuffer doesn't support low sample counts, + * use the sample position from the last working larger count. */ + if (lowest_working_ms_count_idx > 0) { + for (uint k = 0; k < test_num_samples[i]; ++k) { + caps->sample_locations[out_buf_offsets[i] + (k >> 2)] = + caps->sample_locations[out_buf_offsets[lowest_working_ms_count_idx] + (k >> 2)]; + } + } } + glBindFramebuffer(GL_FRAMEBUFFER, 0); } - glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteTextures(1, &tex); } glDeleteFramebuffers(1, &fbo);