diff --git a/docs/backends.rst b/docs/backends.rst index f52714c5..d076d55d 100644 --- a/docs/backends.rst +++ b/docs/backends.rst @@ -65,6 +65,13 @@ A full explanation of push constants and its use in Vulkan can be found `here `_. Using push constants in WGPU closely follows the Vulkan model. +The advantage of push constants is that they are typically faster to update than uniform buffers. +Modifications to push constants are included in the command encoder; updating a uniform +buffer involves sending a separate command to the GPU. + +The disadvantage of push constants and that their size limit is much smaller. The limit +is guaranteed to be at least 128 bytes, and 256 bytes is typical + Given an adapter, first determine if it supports push constants:: >> "push-constants" in adapter.features @@ -74,7 +81,7 @@ If push constants are supported, determine the maximum number of bytes that can be allocated for push constants:: >> adapter.limits["max-push-constant-size"] - 4096 + 256 You must tell the adapter to create a device that supports push constants, and you must tell it the number of bytes of push constants that you are using. @@ -120,7 +127,9 @@ Finally, you set the value of the push constant by using set_push_constants(this_pass, ShaderStage.FRAGMENT, 64, 128, <64 bytes>) set_push_constants(this_pass, ShaderStage.VERTEX + ShaderStage.FRAGMENT, 128, 192, <64 bytes>) -Bytes must be set separately for each of the three shader stages. +Bytes must be set separately for each of the three shader stages. If the push constant has +already been set, on the next use you only need to call ``set_push_constants`` on those +bytes you wish to change. .. py:function:: wgpu.backends.wpgu_native.create_pipeline_layout(device, *, label="", bind_group_layouts, push_constant_layouts=[]) diff --git a/tests_mem/testutils.py b/tests_mem/testutils.py index b71d7eb6..a801021f 100644 --- a/tests_mem/testutils.py +++ b/tests_mem/testutils.py @@ -145,7 +145,37 @@ def ob_name_from_test_func(func): def create_and_release(create_objects_func): - """Decorator.""" + """ + This wrapper goes around a test that takes a single argument n. That test should + be a generator function that yields a descriptor followed + n different objects corresponding to the name of the test function. Hence + a test named `test_release_foo_bar` would yield a descriptor followed by + n FooBar objects. + + The descriptor is a dictionary with three fields, each optional. + + The keys "expected_counts_after_create" and "expected_counts_after_release" each have + as their value a sub-dictionary giving the number of still-alive WGPU objects. + The key "expected_counts_after_create" gives the expected state after the + n objects have been created and put into a list; "expected_counts_after_release" + gives the state after the n objects have been released. + + These sub-dictionaries have as their keys the names of WGPU object types, and + their value is a tuple of two integers: the first is the number of Python objects + expected to exist and the second is the number of native objects. Any type not in + the subdictionary has an implied value of (0, 0). + + The key "ignore" has as its value a collection of object types that we should ignore + in this test. We do not have enough information to determine how many are created + or deleted. + + If the descriptor doesn't contain an "expected_counts_after_create", then the default + is {"FooBar": (n, n)}, where "FooBar" is derived from the name of the test. + + If the descriptor doesn't contain an "expected_counts_after_release", then the + default is {}, indicated that creating and removing the objects should completely + clean itself up. + """ def core_test_func(): """The core function that does the testing."""