-
Notifications
You must be signed in to change notification settings - Fork 172
Fixes for pipeline multi sample issue 2159 and 2180 #2220
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some explanatory information about the thinking behind the changes
tests/layer_validation_tests.cpp
Outdated
@@ -173,13 +176,18 @@ struct NearestGreaterThan { | |||
}; | |||
template <typename T, typename Comp> | |||
T NearestNonEqual(const T value, const Comp &comp) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous version had some numerical corner cases uncovered when expanding the usage. This is simpler and while it has an iterative fallback (for further missed corners), I couldn't find a test case that uses it. There are some ULP differences between this and the prior implementation that don't matter to layer validation testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is awful. What does it even do?
Guessing by the name, should probably be just nextafterf()
;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Converting to std::nextafter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jzulauf-lunarg From experience, it wont pass the Android CI test here. You might have to use the C version of the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just google'd this... android/ndk#82 -- thanks for the heads up.
tests/layer_validation_tests.cpp
Outdated
@@ -946,6 +958,297 @@ struct OneOffDescriptorSet { | |||
return pool_ != VK_NULL_HANDLE && layout_ != VK_NULL_HANDLE && set_ != VK_NULL_HANDLE; | |||
} | |||
}; | |||
|
|||
struct CreatePipelineHelper { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This refactors out common setup code for testing CreateGraphicsPipelines. For typical usage see OneshotTest below
tests/layer_validation_tests.cpp
Outdated
return err; | ||
} | ||
template <typename Test, typename OverrideFunc, typename Error> | ||
static void OneshotTest(Test *test, OverrideFunc &info_override, const VkFlags flags, Error error, bool positive_test = false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The usage here is similar to the rest of the framework, init, twiddle, init some more, test. Oneshot works for all the cases where simple twiddling with the create info structs (and the things they point to) in info_override is sufficient.
tests/layer_validation_tests.cpp
Outdated
} | ||
}; | ||
}; | ||
namespace chain_util { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More common code removal for a pattern in the pNext test added below
tests/layer_validation_tests.cpp
Outdated
|
||
// Cause the error by enabling sample shading... | ||
auto set_shading_enable = [](CreatePipelineHelper &helper) { helper.pipe_ms_state_ci_.sampleShadingEnable = VK_TRUE; }; | ||
CreatePipelineHelper::OneshotTest(this, set_shading_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_10000620); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typical OneshotTest usage. The info_override is a simple one-liner.
tests/layer_validation_tests.cpp
Outdated
vkDestroyDescriptorPool(device, ds_pool_, nullptr); | ||
} | ||
|
||
void InitDescriptorPoolInfo() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reuse OneOffDescriptorSet?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking further into the test cases, VkPipelineObj should be something I'm using instead as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using OneOffDescriptor, but the VkPipelineObj has some late binding smarts that could fixup intentional errors.
VkPipelineCacheCreateInfo pc_ci_ = {}; | ||
VkPipeline pipeline_ = VK_NULL_HANDLE; | ||
VkPipelineCache pipeline_cache_ = VK_NULL_HANDLE; | ||
std::unique_ptr<VkShaderObj> vs_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why separate VS/FS members? The tests you want to replace use a mix of stages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most are VS/FS only, but looking at adapting/replacing the helper with use of the VkPipelineObj (which I didn't notice before), and that supports more stages AFAICT
tests/layer_validation_tests.cpp
Outdated
std::vector<VkDescriptorSetLayoutBinding> dsl_bindings_; | ||
VkDescriptorSetLayoutCreateInfo ds_layout_ci_ = {}; | ||
VkDescriptorSetLayout ds_layout_ = VK_NULL_HANDLE; | ||
VkDescriptorSet descriptorSet_ = VK_NULL_HANDLE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
descriptor_set_
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the utility is quite useful and will simplify testing of PSO.
In future it would be nice if it was generalized. I would want to do something like Init( UPTO_DRAW )
which would get me up to the state where I can just call vkCmdDraw
to test it.
Some nits:
tests/layer_validation_tests.cpp
Outdated
VkPipelineLayoutCreateInfo pipeline_layout_ci_ = {}; | ||
VkPipelineLayout pipeline_layout_ = VK_NULL_HANDLE; | ||
VkPipelineViewportStateCreateInfo vp_state_ci_ = {}; | ||
std::vector<VkDynamicState> dyn_states_ = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does it by default have any dynamic states?
Also: all the other members seem to be only zero initialized here. Why does this one have actual value here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
being lazy with other initialization.... fixing
tests/layer_validation_tests.cpp
Outdated
void InitMultisampleInfo() { | ||
pipe_ms_state_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; | ||
pipe_ms_state_ci_.pNext = NULL; | ||
pipe_ms_state_ci_.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why 4 samples by default??
tests/layer_validation_tests.cpp
Outdated
std::unique_ptr<VkShaderObj> vs_; | ||
std::unique_ptr<VkShaderObj> fs_; | ||
VkLayerTest *layer_test_; | ||
CreatePipelineHelper(VkLayerTest *test) : layer_test_(test) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to pass by reference, not pointer?
tests/layer_validation_tests.cpp
Outdated
vkDestroyPipeline(device, pipeline_, nullptr); | ||
vkDestroyPipelineLayout(device, pipeline_layout_, nullptr); | ||
vkDestroyDescriptorSetLayout(device, ds_layout_, nullptr); | ||
vkDestroyDescriptorPool(device, ds_pool_, nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could alternatively use Vk*Obj
s for automatic destruction?
There's no Vk*LayoutObj
yet, but I am slowly working on those in private branch...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the Vk*Obj's have built-in smarts that might correct for intentionally induced errors. As easily induced intentional errors are a design goal, avoiding these for now.
VALIDATION_ERROR_10000b0e~^~N~^~None~^~VkPipelineMultisampleStateCreateInfo~^~VUID-VkPipelineMultisampleStateCreateInfo-rasterizationSamples-01415~^~(VK_NV_framebuffer_mixed_samples)~^~The spec valid usage text states 'If the subpass has any color attachments and rasterizationSamples is greater than the number of color samples, then sampleShadingEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-VkPipelineMultisampleStateCreateInfo-rasterizationSamples-01415)~^~ | ||
VALIDATION_ERROR_10009005~^~Y~^~Unknown~^~vkCmdSetViewport~^~VUID-VkPipelineMultisampleStateCreateInfo-flags-zerobitmask~^~core~^~The spec valid usage text states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkPipelineMultisampleStateCreateInfo-flags-zerobitmask)~^~implicit, TBD in parameter validation layer. | ||
VALIDATION_ERROR_1001c40d~^~Y~^~Unknown~^~vkCmdSetViewport~^~VUID-VkPipelineMultisampleStateCreateInfo-pNext-pNext~^~core~^~The spec valid usage text states 'Each pNext member of any structure (including this one) in the pNext chain must be either NULL or a pointer to a valid instance of VkPipelineCoverageModulationStateCreateInfoNV, VkPipelineCoverageToColorStateCreateInfoNV, or VkPipelineSampleLocationsStateCreateInfoEXT' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkPipelineMultisampleStateCreateInfo-pNext-pNext)~^~implicit, TBD in parameter validation layer. | ||
VALIDATION_ERROR_1001c40d~^~Y~^~InvalidPipelineSamplePNext~^~vkCmdSetViewport~^~VUID-VkPipelineMultisampleStateCreateInfo-pNext-pNext~^~core~^~The spec valid usage text states 'Each pNext member of any structure (including this one) in the pNext chain must be either NULL or a pointer to a valid instance of VkPipelineCoverageModulationStateCreateInfoNV, VkPipelineCoverageToColorStateCreateInfoNV, or VkPipelineSampleLocationsStateCreateInfoEXT' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkPipelineMultisampleStateCreateInfo-pNext-pNext)~^~implicit, TBD in parameter validation layer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it still TBD? You seem to have implemented it...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are improvements needed that will best be done in enhancements to code generation
tests/layer_validation_tests.cpp
Outdated
std::vector<VkDescriptorPoolSize> ds_pool_sizes_; | ||
VkDescriptorPoolCreateInfo ds_pool_ci_ = {}; | ||
VkDescriptorPool ds_pool_ = VK_NULL_HANDLE; | ||
std::vector<VkDescriptorSetLayoutBinding> dsl_bindings_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could just be private static array?
the user can use his own vector, or modify the default array through the ds_layout_ci_.pBindings
.
tests/layer_validation_tests.cpp
Outdated
ASSERT_VK_SUCCESS(err); | ||
} | ||
|
||
void LateBindPipelineInfo() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be private? The CreateGraphicsPipeline
seems to call it implicitly anyway, so probably no need to call it explicitly
if (do_late_bind) { | ||
LateBindPipelineInfo(); | ||
} | ||
if (implicit_destroy && (pipeline_ != VK_NULL_HANDLE)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vkDestroy*
should be able to destroy VK_NULL_HANDLE
. Though there used to be some driver bugs, so probably better.
tests/layer_validation_tests.cpp
Outdated
} | ||
} | ||
|
||
VkResult CreateGraphicsPipeline(bool implicit_destroy = true, bool do_late_bind = true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
implicit_destroy
is bit confusing name. I did not really expect it to do that. Maybe destroy_previous_pipeline
. Even so it would be weird the old pipeline to just get leaked.
Maybe just create the pipelines into a stack?
tests/layer_validation_tests.cpp
Outdated
info_override(helper); | ||
helper.InitState(); | ||
|
||
test->Monitor()->SetDesiredFailureMsg(flags, error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work?
The positive tests usually set something like m_errorMonitor->ExpectSuccess();
.
rs_state_ci_.pNext = nullptr; | ||
rs_state_ci_.flags = 0; | ||
rs_state_ci_.depthClampEnable = VK_FALSE; | ||
rs_state_ci_.rasterizerDiscardEnable = VK_FALSE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be very commonly used setting. Might be worth to make some shortcut for setting VK_TRUE
.
Added validation checks for: VUID-VkPipelineMultisampleStateCreateInfo-sampleShadingEnable-00784 (VALIDATION_ERROR_10000620) If the sample rate shading feature is not enabled, sampleShadingEnable must be VK_FALSE VUID-VkPipelineMultisampleStateCreateInfo-minSampleShading-00786 (VALIDATION_ERROR_10000624) minSampleShading must be in the range [0,1] Change-Id: I21cdaf99f8970df4f2e03026a4dae00746ad8386
Added tests for validation checks: VUID-VkPipelineMultisampleStateCreateInfo-sampleShadingEnable-00784 (VALIDATION_ERROR_10000620) VUID-VkPipelineMultisampleStateCreateInfo-minSampleShading-00786 (VALIDATION_ERROR_10000624) Change-Id: I49fcfc8f55275f27a976ea88619674c3b87285ae
Updated validation check for VUID-VkPipelineMultisampleStateCreateInfo-pNext-pNext (VALIDATION_ERROR_1001c40d) to include the valid extension pNext sType values valid for the current spec: VkPipelineCoverageModulationStateCreateInfoNV, VkPipelineCoverageToColorStateCreateInfoNV, or VkPipelineSampleLocationsStateCreateInfoEXT Change-Id: Ic3e054110c2bad4b44121a67e7e61e627fa9c559
Added test for validation checks of VUID-VkPipelineMultisampleStateCreateInfo-pNext-pNext (VALIDATION_ERROR_1001c40d) Change-Id: I41fb10698d88db1e4b143007c36b5a798e1adc6b
12f5820
to
452b738
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've incorporated a good deal of the feedback, haven't migrated to the Vk*Obj, as some of them have "clean up" code that might get in the way of inducing errors, which after all is the point of the layer_validation_tests.
Undoubtedly there will be further refinement each time a test (or tranche of tests) is converted to the Helper.
tests/layer_validation_tests.cpp
Outdated
@@ -173,13 +176,18 @@ struct NearestGreaterThan { | |||
}; | |||
template <typename T, typename Comp> | |||
T NearestNonEqual(const T value, const Comp &comp) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just google'd this... android/ndk#82 -- thanks for the heads up.
tests/layer_validation_tests.cpp
Outdated
VkPipelineLayoutCreateInfo pipeline_layout_ci_ = {}; | ||
VkPipelineLayout pipeline_layout_ = VK_NULL_HANDLE; | ||
VkPipelineViewportStateCreateInfo vp_state_ci_ = {}; | ||
std::vector<VkDynamicState> dyn_states_ = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
being lazy with other initialization.... fixing
tests/layer_validation_tests.cpp
Outdated
vkDestroyPipeline(device, pipeline_, nullptr); | ||
vkDestroyPipelineLayout(device, pipeline_layout_, nullptr); | ||
vkDestroyDescriptorSetLayout(device, ds_layout_, nullptr); | ||
vkDestroyDescriptorPool(device, ds_pool_, nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the Vk*Obj's have built-in smarts that might correct for intentionally induced errors. As easily induced intentional errors are a design goal, avoiding these for now.
tests/layer_validation_tests.cpp
Outdated
vkDestroyDescriptorPool(device, ds_pool_, nullptr); | ||
} | ||
|
||
void InitDescriptorPoolInfo() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using OneOffDescriptor, but the VkPipelineObj has some late binding smarts that could fixup intentional errors.
tests/layer_validation_tests.cpp
Outdated
alloc_info_.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; | ||
alloc_info_.descriptorSetCount = 1; | ||
alloc_info_.pSetLayouts = &ds_layout_; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is monkey-see-monkey-do from several examples... assuming they'll find a use as I expand testcase adoption...
Can I get a thumbs up or a set of requested changes? |
LGTM. |
Fixes for #2180 and #2159
Includes a common code refactor of the CreateGraphicsPipeline setup code for layer_validation_tests.cpp, used by the new cases, but presented here for review/feedback/refinement before refactoring the 20+ other copies in extant test cases to use it.