예제 #1
0
        internal CubeTexture(
            IInternalTexture left,
            IInternalTexture right,
            IInternalTexture up,
            IInternalTexture down,
            IInternalTexture front,
            IInternalTexture back)
        {
            if (left == null)
            {
                throw new ArgumentNullException(nameof(left));
            }
            if (right == null)
            {
                throw new ArgumentNullException(nameof(right));
            }
            if (up == null)
            {
                throw new ArgumentNullException(nameof(up));
            }
            if (down == null)
            {
                throw new ArgumentNullException(nameof(down));
            }
            if (front == null)
            {
                throw new ArgumentNullException(nameof(front));
            }
            if (back == null)
            {
                throw new ArgumentNullException(nameof(back));
            }
            size = left.Size;
            if (right.Size != size || up.Size != size || down.Size != size || front.Size != size || back.Size != size)
            {
                throw new ArgumentException(
                          $"[{nameof(CubeTexture)}] All faces of the cube-map need to have the same size",
                          nameof(size));
            }
            Format format = left.Format;

            if (right.Format != format ||
                up.Format != format || down.Format != format ||
                front.Format != format || back.Format != format)
            {
                throw new ArgumentException(
                          $"[{nameof(CubeTexture)}] All faces of the cube-map need to have the same format",
                          nameof(size));
            }
            faces    = new IInternalTexture[6];
            faces[0] = left;
            faces[1] = right;
            faces[2] = up;
            faces[3] = down;
            faces[4] = front;
            faces[5] = back;
        }
 internal static DeviceTexture UploadTexture(
     IInternalTexture texture, RenderScene scene, bool generateMipMaps = false)
 {
     return(UploadTexture(
                texture,
                scene.LogicalDevice,
                scene.MemoryPool,
                scene.StagingBuffer,
                scene.Executor,
                generateMipMaps));
 }
        internal static DeviceTexture UploadTexture(
            IInternalTexture texture,
            Device logicalDevice,
            Memory.Pool memoryPool,
            Memory.HostBuffer stagingBuffer,
            TransientExecutor executor,
            bool generateMipMaps = false)
        {
            if (texture == null)
            {
                throw new ArgumentNullException(nameof(texture));
            }
            if (logicalDevice == null)
            {
                throw new ArgumentNullException(nameof(logicalDevice));
            }
            if (memoryPool == null)
            {
                throw new ArgumentNullException(nameof(memoryPool));
            }
            if (stagingBuffer == null)
            {
                throw new ArgumentNullException(nameof(stagingBuffer));
            }
            if (executor == null)
            {
                throw new ArgumentNullException(nameof(executor));
            }

            int mipLevels = generateMipMaps ? CalculateMipLevels(texture.Size) : 1;
            int layers    = texture.IsCubeMap ? 6 : 1;
            var aspects   = ImageAspects.Color;
            var image     = CreateImage(
                logicalDevice,
                texture.Format,
                texture.Size,
                mipLevels,
                //Also include 'TransferSrc' because we read from the image to generate the mip-maps
                ImageUsages.TransferSrc | ImageUsages.TransferDst | ImageUsages.Sampled,
                cubeMap: texture.IsCubeMap);
            var memory = memoryPool.AllocateAndBind(image, Chunk.Location.Device);

            //Transition the entire image (all mip-levels and layers) to 'TransferDstOptimal'
            TransitionImageLayout(image, aspects,
                                  baseMipLevel: 0, mipLevels, baseLayer: 0, layers,
                                  oldLayout: ImageLayout.Undefined,
                                  newLayout: ImageLayout.TransferDstOptimal,
                                  executor: executor);

            //Upload the data to mipmap 0
            texture.Upload(stagingBuffer, executor, image, aspects);

            //Create the other mipmap levels
            Int2 prevMipSize = texture.Size;

            for (int i = 1; i < mipLevels; i++)
            {
                Int2 curMipSize = new Int2(
                    prevMipSize.X > 1 ? prevMipSize.X / 2 : 1,
                    prevMipSize.Y > 1 ? prevMipSize.Y / 2 : 1);

                //Move the previous mip-level to a transfer source layout
                TransitionImageLayout(image, aspects,
                                      baseMipLevel: i - 1, mipLevels: 1,
                                      baseLayer: 0, layers,
                                      oldLayout: ImageLayout.TransferDstOptimal,
                                      newLayout: ImageLayout.TransferSrcOptimal,
                                      executor: executor);

                //Blit the previous mip-level to the current at half the size
                BlitImage(aspects,
                          fromImage: image,
                          fromRegion: new IntRect(min: Int2.Zero, max: prevMipSize),
                          fromMipLevel: i - 1,
                          fromLayerCount: layers,
                          toImage: image,
                          toRegion: new IntRect(min: Int2.Zero, max: curMipSize),
                          toMipLevel: i,
                          toLayerCount: layers,
                          executor);

                //Transition the previous mip-level to the shader-read layout
                TransitionImageLayout(image, aspects,
                                      baseMipLevel: i - 1, mipLevels: 1,
                                      baseLayer: 0, layers,
                                      oldLayout: ImageLayout.TransferSrcOptimal,
                                      newLayout: ImageLayout.ShaderReadOnlyOptimal,
                                      executor: executor);

                //Update the prev mip-size
                prevMipSize = curMipSize;
            }

            //Transition the last mip-level to the shader-read layout
            TransitionImageLayout(image, aspects,
                                  baseMipLevel: mipLevels - 1, mipLevels: 1,
                                  baseLayer: 0, layers,
                                  oldLayout: ImageLayout.TransferDstOptimal,
                                  newLayout: ImageLayout.ShaderReadOnlyOptimal,
                                  executor: executor);

            var view = CreateView(
                image, texture.Format, mipLevels, aspects, cubeMap: texture.IsCubeMap);

            return(new DeviceTexture(
                       texture.Size,
                       texture.Format,
                       ImageLayout.ShaderReadOnlyOptimal, //Used for shader reading,
                       mipLevels,
                       aspects,
                       image,
                       memory,
                       view));
        }