Coder Social home page Coder Social logo

Comments (7)

achirkin avatar achirkin commented on July 20, 2024

I did not expose Union in current implementation, because it's ugly. The whole Create interface is not really mature yet, so I've tried to keep internals hidden to be able to rewrite it later.

Maybe another solution would be to add an automatic sorting of fields before comparing them?.. Let's keep this issue open, I want to explore the options. [I am about to finish my thesis now, but I want to work on the bindings after that]

from vulkan.

Rotaerk avatar Rotaerk commented on July 20, 2024

Ah nice; congrats!

from vulkan.

Rotaerk avatar Rotaerk commented on July 20, 2024

Ran into an abstraction limitation related to this. I currently have this helper function:

setSharingQueueFamilyIndices ::
  (
    CanWriteField "sharingMode" a,
    CanWriteField "queueFamilyIndexCount" a,
    CanWriteField "pQueueFamilyIndices" a,
    FieldType "sharingMode" a ~ VkSharingMode,
    FieldType "queueFamilyIndexCount" a ~ Word32,
    FieldType "pQueueFamilyIndices" a ~ Ptr Word32
  ) =>
  [Word32] ->
  CreateVkStruct a '["sharingMode", "queueFamilyIndexCount", "pQueueFamilyIndices"] ()
setSharingQueueFamilyIndices qfis =
  set @"sharingMode" (if null qfis' then VK_SHARING_MODE_EXCLUSIVE else VK_SHARING_MODE_CONCURRENT) &*
  setListCountAndRef @"queueFamilyIndexCount" @"pQueueFamilyIndices" qfis'
  where
    -- If just one QFI is provided, it's the same as providing none; both are exclusive mode,
    -- and the QFI list is ignored in that case.
    qfis' = if length qfis > 1 then qfis else []

I then noticed that different structs have these fields named differently. For example, while VkBufferCreateInfo has sharingMode, VkSwapchainCreateInfo has imageSharingMode. So, I tried to make a generalization of the above function:

setSharingQFIs ::
  forall (sm :: GHC.Symbol) (qfic :: GHC.Symbol) (pqfis :: GHC.Symbol) a.
  (
    CanWriteField sm a,
    CanWriteField qfic a,
    CanWriteField pqfis a,
    FieldType sm a ~ VkSharingMode,
    FieldType qfic a ~ Word32,
    FieldType pqfis a ~ Ptr Word32
  ) =>
  [Word32] ->
  CreateVkStruct a '[sm, qfic, pqfis] ()
setSharingQFIs qfis =
  set @sm (if null qfis' then VK_SHARING_MODE_EXCLUSIVE else VK_SHARING_MODE_CONCURRENT) &*
  setListCountAndRef @qfic @pqfis qfis'
  where
    -- If just one QFI is provided, it's the same as providing none; both are exclusive mode,
    -- and the QFI list is ignored in that case.
    qfis' = if length qfis > 1 then qfis else []

Unfortunately, this gives the following error:

    • Could not deduce: Graphics.Vulkan.Marshal.Create.Union
                          (Graphics.Vulkan.Marshal.Internal.VkStruct
                             (Graphics.Vulkan.Marshal.Internal.VkStruct' a))
                          '[sm]
                          (Graphics.Vulkan.Marshal.Create.Union
                             (Graphics.Vulkan.Marshal.Internal.VkStruct
                                (Graphics.Vulkan.Marshal.Internal.VkStruct' a))
                             '[qfic]
                             '[pqfis])
                        ~ '[sm, qfic, pqfis]
      from the context: (CanWriteField sm a, CanWriteField qfic a,
                         CanWriteField pqfis a, FieldType sm a ~ VkSharingMode,
                         FieldType qfic a ~ Word32, FieldType pqfis a ~ Ptr Word32)
        bound by the type signature for:
                   setSharingQFIs :: forall (sm :: GHC.Symbol) (qfic :: GHC.Symbol) (pqfis :: GHC.Symbol) a.
                                     (CanWriteField sm a, CanWriteField qfic a,
                                      CanWriteField pqfis a, FieldType sm a ~ VkSharingMode,
                                      FieldType qfic a ~ Word32, FieldType pqfis a ~ Ptr Word32) =>
                                     [Word32] -> CreateVkStruct a '[sm, qfic, pqfis] ()
        at src/Main.hs:(599,1)-(610,40)
      Expected type: CreateVkStruct a '[sm, qfic, pqfis] ()
        Actual type: CreateVkStruct
                       a
                       (Graphics.Vulkan.Marshal.Create.Union
                          a
                          '[sm]
                          (Graphics.Vulkan.Marshal.Create.Union
                             (Graphics.Vulkan.Marshal.Internal.VkStruct
                                (Graphics.Vulkan.Marshal.Internal.VkStruct' a))
                             '[qfic]

I suspect this is because it cannot prove that sm, qfic, and pqfis are all different. The only way I can think of around this would be to explicitly add the constraint that it can't prove, though I can't do that if Union isn't exported.

from vulkan.

achirkin avatar achirkin commented on July 20, 2024

Hm, yes, you are right, I have to expose Union.
In the meanwhile, if you feel lucky, you can just unsafeCoerce the result :) Nothing bad should happen since you would be in fact coercing a single type type equality.

from vulkan.

Rotaerk avatar Rotaerk commented on July 20, 2024

I wonder if the Create stuff could be redesigned such that the requirement that all the expected fields be set exactly once is enforced later than it is now... For example, in my setSharingQFIs function, there's no need for the type system to enforce that a given field isn't set more than once. That need only be enforced when it's actually passed to createVk or whatever.

In other words, CreateVkStruct a '["foo", "foo", "foo"] () could be valid, but incompatible with createVk. This would make it easier to write functions like the one above.

from vulkan.

achirkin avatar achirkin commented on July 20, 2024

So, you mean all writing functions would just append the list of written fields and the check for duplicates happens only in the final function createVk :: IsUnion a xs => CreateVkStruct a xs -> a? Good idea! I think we can go with that.

from vulkan.

Rotaerk avatar Rotaerk commented on July 20, 2024

Yeah, exactly. BTW, the name Union made sense for the existing data structure, but for a constraint on a list, would IsSet or IsDistinct or something make more sense? Also, is such a constraint event implementable? I'm not sure how, though I'm not that good with the type-level voodoo you do.

from vulkan.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.