mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
Compare commits
4
Commits
b9f940ac63
...
2afbcaaf4f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2afbcaaf4f | ||
|
|
e8dafacb1c | ||
|
|
6336943b87 | ||
|
|
a31eabd12b |
@@ -525,6 +525,16 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
}
|
||||
effectiveStages = &adjustedStages;
|
||||
}
|
||||
// A static rasterizer discard leaves the pipeline without fragment shader state, and then
|
||||
// pStages may not name a fragment stage (VUID-VkGraphicsPipelineCreateInfo-pStages-06894).
|
||||
// Nothing would run it anyway.
|
||||
if (payload.rasterizerDiscardEnable) {
|
||||
if (effectiveStages != &adjustedStages) adjustedStages = *effectiveStages;
|
||||
std::erase_if(adjustedStages, [](const VkPipelineShaderStageCreateInfo& stageInfo) {
|
||||
return stageInfo.stage == VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
});
|
||||
effectiveStages = &adjustedStages;
|
||||
}
|
||||
{
|
||||
VkShaderStageFlags stagesPresent = 0;
|
||||
for (const auto& stageInfo : *effectiveStages) {
|
||||
|
||||
@@ -265,7 +265,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
dynamic.dynamicStateCount = 2;
|
||||
dynamic.pDynamicStates = kDynamic;
|
||||
VkGraphicsPipelineCreateInfo info{VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO};
|
||||
info.stageCount = 2;
|
||||
// As PipelineFactory builds it: a static discard has no fragment shader state, so no
|
||||
// fragment stage (VUID-VkGraphicsPipelineCreateInfo-pStages-06894).
|
||||
info.stageCount = discard ? 1u : 2u;
|
||||
info.pStages = stages;
|
||||
info.pVertexInputState = &vertexInput;
|
||||
info.pInputAssemblyState = &assembly;
|
||||
|
||||
@@ -32,6 +32,7 @@ set(MGL_P8A_AMBIENT_CASES
|
||||
BufferTextureScenario.*
|
||||
ClearTexImageUndefinedLevelZeroScenario.*
|
||||
ClearOrderScenario.*
|
||||
ClipControlScenario.*
|
||||
ClipDistanceScenario.*
|
||||
CopyImageLevelRangeScenario.*
|
||||
CopyImagePacked16Scenario.*
|
||||
|
||||
@@ -371,10 +371,22 @@ layout(std430, binding = 0) readonly buffer Input {
|
||||
return result;
|
||||
}
|
||||
|
||||
// The sequential binary32 sum. The shader's dot() may round differently - GLSL leaves a
|
||||
// dot product's rounding (fused or not) to the implementation, and llvmpipe's ES
|
||||
// compiler answers 1.0 where lavapipe answers this - so the probe accepts any value
|
||||
// within one ulp of it, the same in every invocation, and checks the reduction against
|
||||
// the value the driver actually produced.
|
||||
constexpr float kSampledLuminance = 0.2125f + 0.7154f + 0.0721f;
|
||||
|
||||
float ExpectedInput(InputMode mode, std::uint32_t localIndex) {
|
||||
return mode == InputMode::SampledRgba32f ? kSampledLuminance : static_cast<float>(localIndex + 1u);
|
||||
bool WithinOneUlp(float lhs, float rhs) {
|
||||
const std::uint32_t a = FloatBits(lhs);
|
||||
const std::uint32_t b = FloatBits(rhs);
|
||||
if ((a ^ b) >> 31) return false; // never across a sign
|
||||
return (a > b ? a - b : b - a) <= 1u;
|
||||
}
|
||||
|
||||
float ExpectedInput(InputMode mode, std::uint32_t localIndex, float sampledLuminance) {
|
||||
return mode == InputMode::SampledRgba32f ? sampledLuminance : static_cast<float>(localIndex + 1u);
|
||||
}
|
||||
|
||||
ValidationResult ValidateProbe(const ProbeOutput& output, InputMode mode) {
|
||||
@@ -405,6 +417,16 @@ layout(std430, binding = 0) readonly buffer Input {
|
||||
return Failure("record identity", message.str());
|
||||
}
|
||||
}
|
||||
float sampledLuminance = kSampledLuminance;
|
||||
if (mode == InputMode::SampledRgba32f) {
|
||||
sampledLuminance = output.reduction[slotForLocal[0]].x;
|
||||
if (!WithinOneUlp(sampledLuminance, kSampledLuminance)) {
|
||||
std::ostringstream message;
|
||||
message << "localIndex 0 input was " << FormatFloat(sampledLuminance) << ", expected "
|
||||
<< FormatFloat(kSampledLuminance) << " within one ulp";
|
||||
return Failure("input", message.str());
|
||||
}
|
||||
}
|
||||
for (std::size_t localIndex = 0; localIndex < kInvocationCount; ++localIndex) {
|
||||
const std::size_t slot = slotForLocal[localIndex];
|
||||
const UVec4& invocation = output.invocation[slot];
|
||||
@@ -417,7 +439,7 @@ layout(std430, binding = 0) readonly buffer Input {
|
||||
<< ",0)";
|
||||
return Failure("record identity", message.str());
|
||||
}
|
||||
const float expectedInput = ExpectedInput(mode, static_cast<std::uint32_t>(localIndex));
|
||||
const float expectedInput = ExpectedInput(mode, static_cast<std::uint32_t>(localIndex), sampledLuminance);
|
||||
const float actualInput = output.reduction[slot].x;
|
||||
if (!SameBits(actualInput, expectedInput)) {
|
||||
std::ostringstream message;
|
||||
@@ -500,7 +522,7 @@ layout(std430, binding = 0) readonly buffer Input {
|
||||
float inclusive = 0.0f;
|
||||
for (const std::size_t slot : subgroupSlots[subgroupID]) {
|
||||
const std::uint32_t localIndex = output.invocation[slot].x;
|
||||
inclusive += ExpectedInput(mode, localIndex);
|
||||
inclusive += ExpectedInput(mode, localIndex, sampledLuminance);
|
||||
nativePrefix[slot] = inclusive;
|
||||
const float actualNative = output.reduction[slot].y;
|
||||
if (!SameBits(actualNative, inclusive)) {
|
||||
@@ -664,7 +686,7 @@ layout(std430, binding = 0) readonly buffer Input {
|
||||
float total = 0.0f;
|
||||
for (const float subtotal : nativeSubtotal) total += subtotal;
|
||||
float sampledExpectedTotal = 0.0f;
|
||||
for (std::size_t i = 0; i < kInvocationCount; ++i) sampledExpectedTotal += kSampledLuminance;
|
||||
for (std::size_t i = 0; i < kInvocationCount; ++i) sampledExpectedTotal += sampledLuminance;
|
||||
const float expectedTotal = mode == InputMode::IndexedSsbo ? 131328.0f : sampledExpectedTotal;
|
||||
if (!SameBits(total, expectedTotal) || !SameBits(mergedPrefix[index511Slot], expectedTotal)) {
|
||||
std::ostringstream message;
|
||||
|
||||
@@ -6147,7 +6147,6 @@
|
||||
"DirectGLES.Split.XfbCaptureBufferReuseScenario.EverySpanIntoOneRespecifiedBufferObject",
|
||||
"DirectGLES.Split.XfbPrimitiveQueryScenario.ACaptureThatFitsReportsEveryPrimitiveOnBothTargets",
|
||||
"DirectGLES.Split.XfbPrimitiveQueryScenario.AnOverflowingVertexOnlyCaptureStopsWritingAtTheBufferCapacity",
|
||||
"DirectVulkan.Split.AdoptTier0.LargeArenaAdoptionScenario.ASessionThatCannotRunT0FallsBackToT2OnceByName",
|
||||
"DirectVulkan.Split.AdoptTier0.LargeArenaAdoptionScenario.GpuWriteIntoTheArenaIsReadBack",
|
||||
"DirectVulkan.Split.AdoptTier0.LargeArenaAdoptionScenario.ReadbackSeesTheLatestCpuWrite",
|
||||
"DirectVulkan.Split.AdoptTier0.LargeArenaAdoptionScenario.RespecifiedIndexArenaKeepsVaoBinding",
|
||||
@@ -6596,7 +6595,6 @@
|
||||
"DirectVulkan.Spawn.Indirect.WireIndirectDrawScenario.ShaderWrittenCommandsWithoutAnApplicationBarrierAreOrdered",
|
||||
"DirectVulkan.Spawn.IndirectDispatch.WireIndirectDispatchScenario.ShaderWrittenGroupCountsWithoutAnApplicationBarrierAreOrdered",
|
||||
"DirectVulkan.Spawn.ShaderMipDepth1D.WireMipShapeScenario.Depth1DChainWithoutANativeBlitDeclinesByName",
|
||||
"DirectVulkan.Split.AdoptTier0.LargeArenaAdoptionScenario.ASessionThatCannotRunT0FallsBackToT2OnceByName",
|
||||
"DirectVulkan.Split.Indirect.WireIndirectDrawScenario.ShaderWrittenCommandsWithoutAnApplicationBarrierAreOrdered",
|
||||
"DirectVulkan.Split.IndirectDispatch.WireIndirectDispatchScenario.ShaderWrittenGroupCountsWithoutAnApplicationBarrierAreOrdered",
|
||||
"DirectVulkan.Split.ShaderMipDepth1D.WireMipShapeScenario.Depth1DChainWithoutANativeBlitDeclinesByName",
|
||||
@@ -7746,7 +7744,6 @@
|
||||
"DirectGLESTextureSync.ARecycledTextureSlotReMintsTheTwinOnTheHandleArm",
|
||||
"DirectGLESVertexInputDraw.TheAttributeWalkTakesItsBuffersFromTheRecordNotTheFrontendVao",
|
||||
"DirectGLESVertexInputDraw.TheIndexArmTakesItsBufferAndItsSerialFromTheRecord",
|
||||
"DirectVulkanSanity.AdvertisesSubgroupOnlyWhenVulkanReportsUsableSupport",
|
||||
"DirectVulkanSanity.AdvertisesTextureStorageForDirectStateAccess",
|
||||
"DirectVulkanSanity.AdvertisesUniformBufferObjectAndStencilTexturing",
|
||||
"DirectVulkanSanity.AdvertisesVoxyRequiredRenderingExtensions",
|
||||
@@ -14695,6 +14692,7 @@
|
||||
"SplitBufferSet.AShadowThatFailsThePageGranularTestKeepsTheInwardAlignmentAndItsEdges",
|
||||
"SplitBufferSet.ASubPageMapIsOneProtectedPageAndAWriteThroughItFaults",
|
||||
"SplitBufferSet.AZeroBlockSizeTurnsThePushOffRatherThanMakingItUnlimited",
|
||||
"SplitBufferSet.AnOlderWritebackCannotRetireANewerGpuWriteMark",
|
||||
"SplitBufferSet.BothEdgesOfAWriteMapPublishOneStateRecord",
|
||||
"SplitBufferSet.MembershipIsSyncPersistentMappedRangesOwnEarlyOutChain",
|
||||
"SplitBufferSet.Row0EverySsboBindingPointIsMarkedByADraw",
|
||||
@@ -15019,7 +15017,6 @@
|
||||
"DirectGLESTextureSync.ARecycledTextureSlotReMintsTheTwinOnTheHandleArm",
|
||||
"DirectGLESVertexInputDraw.TheAttributeWalkTakesItsBuffersFromTheRecordNotTheFrontendVao",
|
||||
"DirectGLESVertexInputDraw.TheIndexArmTakesItsBufferAndItsSerialFromTheRecord",
|
||||
"DirectVulkanSanity.AdvertisesSubgroupOnlyWhenVulkanReportsUsableSupport",
|
||||
"DirectVulkanSanity.AdvertisesTextureStorageForDirectStateAccess",
|
||||
"DirectVulkanSanity.AdvertisesUniformBufferObjectAndStencilTexturing",
|
||||
"DirectVulkanSanity.AdvertisesVoxyRequiredRenderingExtensions",
|
||||
@@ -16184,6 +16181,7 @@
|
||||
"SplitBufferSet.AShadowThatFailsThePageGranularTestKeepsTheInwardAlignmentAndItsEdges",
|
||||
"SplitBufferSet.ASubPageMapIsOneProtectedPageAndAWriteThroughItFaults",
|
||||
"SplitBufferSet.AZeroBlockSizeTurnsThePushOffRatherThanMakingItUnlimited",
|
||||
"SplitBufferSet.AnOlderWritebackCannotRetireANewerGpuWriteMark",
|
||||
"SplitBufferSet.BothEdgesOfAWriteMapPublishOneStateRecord",
|
||||
"SplitBufferSet.MembershipIsSyncPersistentMappedRangesOwnEarlyOutChain",
|
||||
"SplitBufferSet.Row0EverySsboBindingPointIsMarkedByADraw",
|
||||
|
||||
Reference in New Issue
Block a user