fix(agc): rasterize a single-sample scan into a multisampled target at the pixel center

With PA_SC_AA_CONFIG at one sample and MSAA_ENABLE off, the hardware scans
each pixel once and gives every sample of a multisampled color target its
result: radeonsi programs exactly this when GL multisampling is disabled on
a multisampled framebuffer (si_emit_msaa_config leaves sc_aa_config 0), and
GL defines it as single-sample rasterization with full coverage. Such a draw
without depth or alpha-to-coverage now rasterizes the target's sample count
with every sample location at the pixel center, which covers all samples
exactly when the center is covered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Achraf Reyani 2026-10-12 19:05:04 +09:00
parent 9bc3623517
commit 69728a0cb0
2 changed files with 15 additions and 0 deletions

View File

@ -794,6 +794,11 @@ State DecodeState(const QueueState& queue, bool vertexWorkgroup) {
if (slotExport == 7 && ((read(cx, 0x31c + slot * 0xfu) >> 8u) & 7u) != 4u) throw std::runtime_error("AGC graphics: color export format 7 (UINT16_ABGR) into a target that is not unsigned integer is unsupported");
color.exportIndex = index;
color.uintExport = slotExport == 7;
if (color.samples > 1 && result.samples == 1 && result.colors.empty() && !result.depth && !result.alphaToCoverage && (read(cx, 0x292) & 1u) == 0) {
result.samples = color.samples;
result.customSampleLocations = true;
result.sampleLocations.fill(0);
}
Require(color.samples == result.samples, "a color target's sample count differs from the rasterizer's");
APS5_LOG_OUT_DEBUG("Color %u address=0x%llx extent=%ux%u bytes=%llu VkFormat=%u", slot, static_cast<unsigned long long>(color.address), color.extent.width, color.extent.height, static_cast<unsigned long long>(color.bytes), static_cast<unsigned>(color.format));
if (result.colors.empty()) {

View File

@ -1855,6 +1855,16 @@ void multisampleTests() {
queue.context[0x302] = 0x44cc;
expectFailure([&] { DecodeState(queue); }, "nonstandard sample locations");
queue = multisampled();
queue.context[0x2f8] = 0;
queue.context[0x292] = 2;
queue.context[0x31d] = 0x12000;
state = DecodeState(queue);
Require(state.samples == 4 && state.colors.size() == 1 && state.colors[0].samples == 4 && state.customSampleLocations, "single-sample scan conversion into a 4x target did not rasterize the target's samples");
const auto centered = AgcDriver::Graphics::SampleLocations(state);
for (std::uint32_t sample = 0; sample < state.samples; ++sample) Require(centered[sample].x == 0.5f && centered[sample].y == 0.5f, "single-sample scan conversion did not place every sample at the pixel center");
queue.context[0x292] = 3;
expectFailure([&] { DecodeState(queue); }, "MSAA_ENABLE on a single-sample target");
queue = multisampled();
queue.context[0x2f8] = 0x00300003;
queue.context[0x31d] = 0x1b000;
for (std::uint32_t pixel = 0; pixel < 4; ++pixel) {