Skip to content
This repository has been archived by the owner on Jul 19, 2018. It is now read-only.

Fixes for pipeline multi sample issue 2159 and 2180 #2220

Merged
merged 4 commits into from
Nov 30, 2017

Conversation

jzulauf-lunarg
Copy link
Contributor

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.

Copy link
Contributor Author

@jzulauf-lunarg jzulauf-lunarg left a 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

@@ -173,13 +176,18 @@ struct NearestGreaterThan {
};
template <typename T, typename Comp>
T NearestNonEqual(const T value, const Comp &comp) {
Copy link
Contributor Author

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.

Copy link
Contributor

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();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Converting to std::nextafter

Copy link
Contributor

@krOoze krOoze Nov 27, 2017

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.

Copy link
Contributor Author

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.

@@ -946,6 +958,297 @@ struct OneOffDescriptorSet {
return pool_ != VK_NULL_HANDLE && layout_ != VK_NULL_HANDLE && set_ != VK_NULL_HANDLE;
}
};

struct CreatePipelineHelper {
Copy link
Contributor Author

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

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) {
Copy link
Contributor Author

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.

}
};
};
namespace chain_util {
Copy link
Contributor Author

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


// 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);
Copy link
Contributor Author

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.

vkDestroyDescriptorPool(device, ds_pool_, nullptr);
}

void InitDescriptorPoolInfo() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reuse OneOffDescriptorSet?

Copy link
Contributor Author

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.

Copy link
Contributor Author

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_;
Copy link
Collaborator

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.

Copy link
Contributor Author

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

std::vector<VkDescriptorSetLayoutBinding> dsl_bindings_;
VkDescriptorSetLayoutCreateInfo ds_layout_ci_ = {};
VkDescriptorSetLayout ds_layout_ = VK_NULL_HANDLE;
VkDescriptorSet descriptorSet_ = VK_NULL_HANDLE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

descriptor_set_

Copy link
Contributor

@krOoze krOoze left a 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:

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 };
Copy link
Contributor

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.

Copy link
Contributor Author

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

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;
Copy link
Contributor

@krOoze krOoze Nov 21, 2017

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??

std::unique_ptr<VkShaderObj> vs_;
std::unique_ptr<VkShaderObj> fs_;
VkLayerTest *layer_test_;
CreatePipelineHelper(VkLayerTest *test) : layer_test_(test) {}
Copy link
Contributor

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?

vkDestroyPipeline(device, pipeline_, nullptr);
vkDestroyPipelineLayout(device, pipeline_layout_, nullptr);
vkDestroyDescriptorSetLayout(device, ds_layout_, nullptr);
vkDestroyDescriptorPool(device, ds_pool_, nullptr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could alternatively use Vk*Objs for automatic destruction?
There's no Vk*LayoutObj yet, but I am slowly working on those in private branch...

Copy link
Contributor Author

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.
Copy link
Contributor

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...

Copy link
Contributor Author

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

std::vector<VkDescriptorPoolSize> ds_pool_sizes_;
VkDescriptorPoolCreateInfo ds_pool_ci_ = {};
VkDescriptorPool ds_pool_ = VK_NULL_HANDLE;
std::vector<VkDescriptorSetLayoutBinding> dsl_bindings_;
Copy link
Contributor

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.

ASSERT_VK_SUCCESS(err);
}

void LateBindPipelineInfo() {
Copy link
Contributor

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)) {
Copy link
Contributor

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.

}
}

VkResult CreateGraphicsPipeline(bool implicit_destroy = true, bool do_late_bind = true) {
Copy link
Contributor

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?

info_override(helper);
helper.InitState();

test->Monitor()->SetDesiredFailureMsg(flags, error);
Copy link
Contributor

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;
Copy link
Contributor

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
Copy link
Contributor Author

@jzulauf-lunarg jzulauf-lunarg left a 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.

@@ -173,13 +176,18 @@ struct NearestGreaterThan {
};
template <typename T, typename Comp>
T NearestNonEqual(const T value, const Comp &comp) {
Copy link
Contributor Author

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.

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 };
Copy link
Contributor Author

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

vkDestroyPipeline(device, pipeline_, nullptr);
vkDestroyPipelineLayout(device, pipeline_layout_, nullptr);
vkDestroyDescriptorSetLayout(device, ds_layout_, nullptr);
vkDestroyDescriptorPool(device, ds_pool_, nullptr);
Copy link
Contributor Author

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.

vkDestroyDescriptorPool(device, ds_pool_, nullptr);
}

void InitDescriptorPoolInfo() {
Copy link
Contributor Author

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.

alloc_info_.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
alloc_info_.descriptorSetCount = 1;
alloc_info_.pSetLayouts = &ds_layout_;
}
Copy link
Contributor Author

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...

@jzulauf-lunarg
Copy link
Contributor Author

Can I get a thumbs up or a set of requested changes?

@mark-lunarg
Copy link
Collaborator

LGTM.

@jzulauf-lunarg jzulauf-lunarg merged commit 9fc644b into master Nov 30, 2017
@jzulauf-lunarg jzulauf-lunarg deleted the zulauf_multisample_2180 branch January 12, 2018 15:21
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants