KhronosGroup / Vulkan-Docs

The Vulkan API Specification and related tools
Other
2.78k stars 466 forks source link

Change the way out parameters are defined. #10

Open ratchetfreak opened 8 years ago

ratchetfreak commented 8 years ago

The creation, allocation and capability-query functions use out parameters to return the created/allocated object (and the actual return value for errors). However not all languages support this and automatically mapping the pointer arguments to return values can be tricky.

Instead marking them explicitly will make it clearer where the result goes.

        <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INITIALIZATION_FAILED,VK_ERROR_LAYER_NOT_PRESENT,VK_ERROR_EXTENSION_NOT_PRESENT,VK_ERROR_INCOMPATIBLE_DRIVER">
            <proto><type>VkResult</type> <name>vkCreateInstance</name></proto>
            <param>const <type>VkInstanceCreateInfo</type>* <name>pCreateInfo</name></param>
            <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
            <param out="true"><type>VkInstance</type>* <name>pInstance</name></param>
        </command>
        <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INITIALIZATION_FAILED">
            <proto><type>VkResult</type> <name>vkEnumeratePhysicalDevices</name></proto>
            <param><type>VkInstance</type> <name>instance</name></param>
            <param optional="false,true" out="true"><type>uint32_t</type>* <name>pPhysicalDeviceCount</name></param>
            <param optional="true" len="pPhysicalDeviceCount" out="true"><type>VkPhysicalDevice</type>* <name>pPhysicalDevices</name></param>
        </command>
oddhack commented 8 years ago

It is complexified as the array query commands have two parameters whose behavior depends on each other's values (*pPhysicalDeviceCount may be out, or in/out). If you're writing a binding for a language that has to copy out of the return array from the C API, I suspect you're writing a semantically different query that has to understand this special behavior at a level that's hard to express in the XML - it sounds like the binding might need to allocate a working buffer of its own for conversion to the target language's objects.

Not necc. opposed to adding the out attribute, just unclear if it's really enough for those cases.

ratchetfreak commented 8 years ago

I understand that nvidia's C++ binding did some trickery to support returning std::vector.

Putting the out as the value of the attribute would probably be better so inout and in (the default) can be expressed. It was my first idea but I just couldn't come up with a concise name for how to call the attribute.

        <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INITIALIZATION_FAILED,VK_ERROR_LAYER_NOT_PRESENT,VK_ERROR_EXTENSION_NOT_PRESENT,VK_ERROR_INCOMPATIBLE_DRIVER">
            <proto><type>VkResult</type> <name>vkCreateInstance</name></proto>
            <param>const <type>VkInstanceCreateInfo</type>* <name>pCreateInfo</name></param>
            <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
            <param attr="out"><type>VkInstance</type>* <name>pInstance</name></param>
        </command>
        <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INITIALIZATION_FAILED">
            <proto><type>VkResult</type> <name>vkEnumeratePhysicalDevices</name></proto>
            <param><type>VkInstance</type> <name>instance</name></param>
            <param optional="false,true" attr="out,inout"><type>uint32_t</type>* <name>pPhysicalDeviceCount</name></param>
            <param optional="true" len="pPhysicalDeviceCount" attr="out"><type>VkPhysicalDevice</type>* <name>pPhysicalDevices</name></param>
        </command>
hlandau commented 8 years ago

How about dir="inout"?

NicolBolas commented 8 years ago

Vulkan rather consistently uses the pattern of "pointer to size + pointer to array", where if the pointer-to-array is NULL, then it returns the size in pointer-to-size". So it might be best to have an explicit name for that exact pattern. Maybe query-array or something. inout seems to generic for something so specific. So this function would be specified as:

    <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INITIALIZATION_FAILED">
        <proto><type>VkResult</type> <name>vkEnumeratePhysicalDevices</name></proto>
        <param><type>VkInstance</type> <name>instance</name></param>
        <param optional="false,true" attr="query-array"><type>uint32_t</type>* <name>pPhysicalDeviceCount</name></param>
        <param optional="true" len="pPhysicalDeviceCount" attr="out"><type>VkPhysicalDevice</type>* <name>pPhysicalDevices</name></param>
    </command>