How to pass a variable number of MTLTextures to a fragment shader?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















What is the correct syntax for passing a variable number of MTLTexture's as an array to a fragment shader?



This StackOverflow Question: "How to use texture2d_array array in metal?" mentions the use of:



array<texture2d<half>, 5>


However, this requires specifying the size of the array. In Metal Shading Language Specification.pdf (Sec. 2.11) they also demonstrate this type. However, they also refer to array_ref but it's not clear to me how to use it, or if it's even allowed as a parameter type for a fragment shared given this statement:




"The array_ref type cannot be passed as an argument to graphics
and kernel functions."




What I'm currently doing is just declaring the parameter as:



fragment float4 fragmentShader(RasterizerData in [[ stage_in ]],
sampler s [[ sampler(0) ]],
const array<texture2d<half>, 128> textures [[ texture(0) ]]) {

const half4 c = textures[in.textureIndex].sample(s, in.coords);
}


Since the limit is 128 fragment textures. In any render pass, I might use between 1..n textures, where I ensure that n does not exceed 128. That seems to work for me, but am I Doing It Wrong?





My use-case is drawing a 2D plane that is sub-divided into a bunch of tiles. Each tile's content is sampled from a designated texture in the array based on a pre-computed texture index. The textures are set using setFragmentTexture:atIndex in the correct order at the start of the render pass. The texture index is passed from the vertex shader to the fragment shader.










share|improve this question





























    0















    What is the correct syntax for passing a variable number of MTLTexture's as an array to a fragment shader?



    This StackOverflow Question: "How to use texture2d_array array in metal?" mentions the use of:



    array<texture2d<half>, 5>


    However, this requires specifying the size of the array. In Metal Shading Language Specification.pdf (Sec. 2.11) they also demonstrate this type. However, they also refer to array_ref but it's not clear to me how to use it, or if it's even allowed as a parameter type for a fragment shared given this statement:




    "The array_ref type cannot be passed as an argument to graphics
    and kernel functions."




    What I'm currently doing is just declaring the parameter as:



    fragment float4 fragmentShader(RasterizerData in [[ stage_in ]],
    sampler s [[ sampler(0) ]],
    const array<texture2d<half>, 128> textures [[ texture(0) ]]) {

    const half4 c = textures[in.textureIndex].sample(s, in.coords);
    }


    Since the limit is 128 fragment textures. In any render pass, I might use between 1..n textures, where I ensure that n does not exceed 128. That seems to work for me, but am I Doing It Wrong?





    My use-case is drawing a 2D plane that is sub-divided into a bunch of tiles. Each tile's content is sampled from a designated texture in the array based on a pre-computed texture index. The textures are set using setFragmentTexture:atIndex in the correct order at the start of the render pass. The texture index is passed from the vertex shader to the fragment shader.










    share|improve this question

























      0












      0








      0








      What is the correct syntax for passing a variable number of MTLTexture's as an array to a fragment shader?



      This StackOverflow Question: "How to use texture2d_array array in metal?" mentions the use of:



      array<texture2d<half>, 5>


      However, this requires specifying the size of the array. In Metal Shading Language Specification.pdf (Sec. 2.11) they also demonstrate this type. However, they also refer to array_ref but it's not clear to me how to use it, or if it's even allowed as a parameter type for a fragment shared given this statement:




      "The array_ref type cannot be passed as an argument to graphics
      and kernel functions."




      What I'm currently doing is just declaring the parameter as:



      fragment float4 fragmentShader(RasterizerData in [[ stage_in ]],
      sampler s [[ sampler(0) ]],
      const array<texture2d<half>, 128> textures [[ texture(0) ]]) {

      const half4 c = textures[in.textureIndex].sample(s, in.coords);
      }


      Since the limit is 128 fragment textures. In any render pass, I might use between 1..n textures, where I ensure that n does not exceed 128. That seems to work for me, but am I Doing It Wrong?





      My use-case is drawing a 2D plane that is sub-divided into a bunch of tiles. Each tile's content is sampled from a designated texture in the array based on a pre-computed texture index. The textures are set using setFragmentTexture:atIndex in the correct order at the start of the render pass. The texture index is passed from the vertex shader to the fragment shader.










      share|improve this question














      What is the correct syntax for passing a variable number of MTLTexture's as an array to a fragment shader?



      This StackOverflow Question: "How to use texture2d_array array in metal?" mentions the use of:



      array<texture2d<half>, 5>


      However, this requires specifying the size of the array. In Metal Shading Language Specification.pdf (Sec. 2.11) they also demonstrate this type. However, they also refer to array_ref but it's not clear to me how to use it, or if it's even allowed as a parameter type for a fragment shared given this statement:




      "The array_ref type cannot be passed as an argument to graphics
      and kernel functions."




      What I'm currently doing is just declaring the parameter as:



      fragment float4 fragmentShader(RasterizerData in [[ stage_in ]],
      sampler s [[ sampler(0) ]],
      const array<texture2d<half>, 128> textures [[ texture(0) ]]) {

      const half4 c = textures[in.textureIndex].sample(s, in.coords);
      }


      Since the limit is 128 fragment textures. In any render pass, I might use between 1..n textures, where I ensure that n does not exceed 128. That seems to work for me, but am I Doing It Wrong?





      My use-case is drawing a 2D plane that is sub-divided into a bunch of tiles. Each tile's content is sampled from a designated texture in the array based on a pre-computed texture index. The textures are set using setFragmentTexture:atIndex in the correct order at the start of the render pass. The texture index is passed from the vertex shader to the fragment shader.







      macos metal fragment-shader






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 16 '18 at 19:28









      kennyckennyc

      1,66231627




      1,66231627
























          1 Answer
          1






          active

          oldest

          votes


















          0














          You should consider an array texture instead of a texture array. That is, a texture whose type is MTLTextureType2DArray. You use the arrayLength property of the texture descriptor to specify how many 2-D slices the array texture contains.



          To populate the texture, you specify which slice you're writing to with methods such as -replaceRegion:... or -copyFrom{Buffer,Texture}:...toTexture:....



          In a shader, you can specify which element to sample or read from using the array parameter.






          share|improve this answer
























          • I had considered that but then all of the source textures need to be the same size, which is not the case for me. For example, I might have an image that is 21,000 x 5,000 pixels that I'm representing with four textures of size 5,000 x 1,000 and one texture of size 1,000 x 1,000. Using a single texture is not possible because the maximum size is 16384. Smaller textures give me more granularity at determine which textures are "dirty" and who's mipmaps need to be regenerated. These textures are being filled in from an XPC service rendering arbitrary tiles.

            – kennyc
            Nov 17 '18 at 9:19











          • Follow Up: By reworking my tiling engine and allowing for "overflow" in tiles so that I can get tiles of a uniform size, the use if a 2D Array dramatically improves performance and cleans up the code quite a bit. The Metal docs, WWDC videos and Xcode debugging tools are pretty good, but there's still so much to learn if you're not already experienced with low-level graphics.

            – kennyc
            Nov 17 '18 at 22:37












          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53344214%2fhow-to-pass-a-variable-number-of-mtltextures-to-a-fragment-shader%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          You should consider an array texture instead of a texture array. That is, a texture whose type is MTLTextureType2DArray. You use the arrayLength property of the texture descriptor to specify how many 2-D slices the array texture contains.



          To populate the texture, you specify which slice you're writing to with methods such as -replaceRegion:... or -copyFrom{Buffer,Texture}:...toTexture:....



          In a shader, you can specify which element to sample or read from using the array parameter.






          share|improve this answer
























          • I had considered that but then all of the source textures need to be the same size, which is not the case for me. For example, I might have an image that is 21,000 x 5,000 pixels that I'm representing with four textures of size 5,000 x 1,000 and one texture of size 1,000 x 1,000. Using a single texture is not possible because the maximum size is 16384. Smaller textures give me more granularity at determine which textures are "dirty" and who's mipmaps need to be regenerated. These textures are being filled in from an XPC service rendering arbitrary tiles.

            – kennyc
            Nov 17 '18 at 9:19











          • Follow Up: By reworking my tiling engine and allowing for "overflow" in tiles so that I can get tiles of a uniform size, the use if a 2D Array dramatically improves performance and cleans up the code quite a bit. The Metal docs, WWDC videos and Xcode debugging tools are pretty good, but there's still so much to learn if you're not already experienced with low-level graphics.

            – kennyc
            Nov 17 '18 at 22:37
















          0














          You should consider an array texture instead of a texture array. That is, a texture whose type is MTLTextureType2DArray. You use the arrayLength property of the texture descriptor to specify how many 2-D slices the array texture contains.



          To populate the texture, you specify which slice you're writing to with methods such as -replaceRegion:... or -copyFrom{Buffer,Texture}:...toTexture:....



          In a shader, you can specify which element to sample or read from using the array parameter.






          share|improve this answer
























          • I had considered that but then all of the source textures need to be the same size, which is not the case for me. For example, I might have an image that is 21,000 x 5,000 pixels that I'm representing with four textures of size 5,000 x 1,000 and one texture of size 1,000 x 1,000. Using a single texture is not possible because the maximum size is 16384. Smaller textures give me more granularity at determine which textures are "dirty" and who's mipmaps need to be regenerated. These textures are being filled in from an XPC service rendering arbitrary tiles.

            – kennyc
            Nov 17 '18 at 9:19











          • Follow Up: By reworking my tiling engine and allowing for "overflow" in tiles so that I can get tiles of a uniform size, the use if a 2D Array dramatically improves performance and cleans up the code quite a bit. The Metal docs, WWDC videos and Xcode debugging tools are pretty good, but there's still so much to learn if you're not already experienced with low-level graphics.

            – kennyc
            Nov 17 '18 at 22:37














          0












          0








          0







          You should consider an array texture instead of a texture array. That is, a texture whose type is MTLTextureType2DArray. You use the arrayLength property of the texture descriptor to specify how many 2-D slices the array texture contains.



          To populate the texture, you specify which slice you're writing to with methods such as -replaceRegion:... or -copyFrom{Buffer,Texture}:...toTexture:....



          In a shader, you can specify which element to sample or read from using the array parameter.






          share|improve this answer













          You should consider an array texture instead of a texture array. That is, a texture whose type is MTLTextureType2DArray. You use the arrayLength property of the texture descriptor to specify how many 2-D slices the array texture contains.



          To populate the texture, you specify which slice you're writing to with methods such as -replaceRegion:... or -copyFrom{Buffer,Texture}:...toTexture:....



          In a shader, you can specify which element to sample or read from using the array parameter.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 16 '18 at 22:45









          Ken ThomasesKen Thomases

          71.9k673110




          71.9k673110













          • I had considered that but then all of the source textures need to be the same size, which is not the case for me. For example, I might have an image that is 21,000 x 5,000 pixels that I'm representing with four textures of size 5,000 x 1,000 and one texture of size 1,000 x 1,000. Using a single texture is not possible because the maximum size is 16384. Smaller textures give me more granularity at determine which textures are "dirty" and who's mipmaps need to be regenerated. These textures are being filled in from an XPC service rendering arbitrary tiles.

            – kennyc
            Nov 17 '18 at 9:19











          • Follow Up: By reworking my tiling engine and allowing for "overflow" in tiles so that I can get tiles of a uniform size, the use if a 2D Array dramatically improves performance and cleans up the code quite a bit. The Metal docs, WWDC videos and Xcode debugging tools are pretty good, but there's still so much to learn if you're not already experienced with low-level graphics.

            – kennyc
            Nov 17 '18 at 22:37



















          • I had considered that but then all of the source textures need to be the same size, which is not the case for me. For example, I might have an image that is 21,000 x 5,000 pixels that I'm representing with four textures of size 5,000 x 1,000 and one texture of size 1,000 x 1,000. Using a single texture is not possible because the maximum size is 16384. Smaller textures give me more granularity at determine which textures are "dirty" and who's mipmaps need to be regenerated. These textures are being filled in from an XPC service rendering arbitrary tiles.

            – kennyc
            Nov 17 '18 at 9:19











          • Follow Up: By reworking my tiling engine and allowing for "overflow" in tiles so that I can get tiles of a uniform size, the use if a 2D Array dramatically improves performance and cleans up the code quite a bit. The Metal docs, WWDC videos and Xcode debugging tools are pretty good, but there's still so much to learn if you're not already experienced with low-level graphics.

            – kennyc
            Nov 17 '18 at 22:37

















          I had considered that but then all of the source textures need to be the same size, which is not the case for me. For example, I might have an image that is 21,000 x 5,000 pixels that I'm representing with four textures of size 5,000 x 1,000 and one texture of size 1,000 x 1,000. Using a single texture is not possible because the maximum size is 16384. Smaller textures give me more granularity at determine which textures are "dirty" and who's mipmaps need to be regenerated. These textures are being filled in from an XPC service rendering arbitrary tiles.

          – kennyc
          Nov 17 '18 at 9:19





          I had considered that but then all of the source textures need to be the same size, which is not the case for me. For example, I might have an image that is 21,000 x 5,000 pixels that I'm representing with four textures of size 5,000 x 1,000 and one texture of size 1,000 x 1,000. Using a single texture is not possible because the maximum size is 16384. Smaller textures give me more granularity at determine which textures are "dirty" and who's mipmaps need to be regenerated. These textures are being filled in from an XPC service rendering arbitrary tiles.

          – kennyc
          Nov 17 '18 at 9:19













          Follow Up: By reworking my tiling engine and allowing for "overflow" in tiles so that I can get tiles of a uniform size, the use if a 2D Array dramatically improves performance and cleans up the code quite a bit. The Metal docs, WWDC videos and Xcode debugging tools are pretty good, but there's still so much to learn if you're not already experienced with low-level graphics.

          – kennyc
          Nov 17 '18 at 22:37





          Follow Up: By reworking my tiling engine and allowing for "overflow" in tiles so that I can get tiles of a uniform size, the use if a 2D Array dramatically improves performance and cleans up the code quite a bit. The Metal docs, WWDC videos and Xcode debugging tools are pretty good, but there's still so much to learn if you're not already experienced with low-level graphics.

          – kennyc
          Nov 17 '18 at 22:37




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53344214%2fhow-to-pass-a-variable-number-of-mtltextures-to-a-fragment-shader%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Xamarin.iOS Cant Deploy on Iphone

          Glorious Revolution

          Dulmage-Mendelsohn matrix decomposition in Python