blob: 58c0626add03b87699330e269b590750b6347727 [file] [log] [blame]
Jamie Madill9e54b5a2016-05-25 12:57:39 -04001//
2// Copyright 2016 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// TextureVk.cpp:
7// Implements the class methods for TextureVk.
8//
9
10#include "libANGLE/renderer/vulkan/TextureVk.h"
11
12#include "common/debug.h"
Jamie Madill035fd6b2017-10-03 15:43:22 -040013#include "libANGLE/Context.h"
14#include "libANGLE/renderer/vulkan/ContextVk.h"
15#include "libANGLE/renderer/vulkan/RendererVk.h"
16#include "libANGLE/renderer/vulkan/formatutilsvk.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040017
18namespace rx
19{
20
21TextureVk::TextureVk(const gl::TextureState &state) : TextureImpl(state)
22{
23}
24
25TextureVk::~TextureVk()
26{
27}
28
Jamie Madill035fd6b2017-10-03 15:43:22 -040029gl::Error TextureVk::onDestroy(const gl::Context *context)
30{
31 ContextVk *contextVk = GetImplAs<ContextVk>(context);
32 RendererVk *renderer = contextVk->getRenderer();
33
34 renderer->enqueueGarbageOrDeleteNow(*this, std::move(mImage));
35 renderer->enqueueGarbageOrDeleteNow(*this, std::move(mDeviceMemory));
36 renderer->enqueueGarbageOrDeleteNow(*this, std::move(mImageView));
Jamie Madill5547b382017-10-23 18:16:01 -040037 renderer->enqueueGarbageOrDeleteNow(*this, std::move(mSampler));
Jamie Madill035fd6b2017-10-03 15:43:22 -040038
39 return gl::NoError();
40}
41
Jamie Madillc564c072017-06-01 12:45:42 -040042gl::Error TextureVk::setImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -050043 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -040044 size_t level,
45 GLenum internalFormat,
46 const gl::Extents &size,
47 GLenum format,
48 GLenum type,
49 const gl::PixelUnpackState &unpack,
50 const uint8_t *pixels)
51{
Jamie Madill035fd6b2017-10-03 15:43:22 -040052 // TODO(jmadill): support multi-level textures.
53 ASSERT(level == 0);
54
55 // TODO(jmadill): support texture re-definition.
56 ASSERT(!mImage.valid());
57
58 // TODO(jmadill): support other types of textures.
59 ASSERT(target == GL_TEXTURE_2D);
60
61 // Convert internalFormat to sized internal format.
62 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
63 const vk::Format &vkFormat = vk::Format::Get(formatInfo.sizedInternalFormat);
64
65 VkImageCreateInfo imageInfo;
66 imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
67 imageInfo.pNext = nullptr;
68 imageInfo.flags = 0;
69 imageInfo.imageType = VK_IMAGE_TYPE_2D;
70 imageInfo.format = vkFormat.native;
71 imageInfo.extent.width = size.width;
72 imageInfo.extent.height = size.height;
73 imageInfo.extent.depth = size.depth;
74 imageInfo.mipLevels = 1;
75 imageInfo.arrayLayers = 1;
76 imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
77 imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
78
79 // TODO(jmadill): Are all these image transfer bits necessary?
80 imageInfo.usage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
Jamie Madill5547b382017-10-23 18:16:01 -040081 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
Jamie Madill035fd6b2017-10-03 15:43:22 -040082 imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
83 imageInfo.queueFamilyIndexCount = 0;
84 imageInfo.pQueueFamilyIndices = nullptr;
85 imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
86
87 ContextVk *contextVk = GetImplAs<ContextVk>(context);
88 VkDevice device = contextVk->getDevice();
89 ANGLE_TRY(mImage.init(device, imageInfo));
90
91 // Allocate the device memory for the image.
92 // TODO(jmadill): Use more intelligent device memory allocation.
93 VkMemoryRequirements memoryRequirements;
94 mImage.getMemoryRequirements(device, &memoryRequirements);
95
96 RendererVk *renderer = contextVk->getRenderer();
97
98 uint32_t memoryIndex = renderer->getMemoryProperties().findCompatibleMemoryIndex(
99 memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
100
101 VkMemoryAllocateInfo allocateInfo;
102 allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
103 allocateInfo.pNext = nullptr;
104 allocateInfo.allocationSize = memoryRequirements.size;
105 allocateInfo.memoryTypeIndex = memoryIndex;
106
107 ANGLE_TRY(mDeviceMemory.allocate(device, allocateInfo));
108 ANGLE_TRY(mImage.bindMemory(device, mDeviceMemory));
109
110 VkImageViewCreateInfo viewInfo;
111 viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
112 viewInfo.pNext = nullptr;
113 viewInfo.flags = 0;
114 viewInfo.image = mImage.getHandle();
115 viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
116 viewInfo.format = vkFormat.native;
117 viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
118 viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
119 viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
120 viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
121 viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
122 viewInfo.subresourceRange.baseMipLevel = 0;
123 viewInfo.subresourceRange.levelCount = 1;
124 viewInfo.subresourceRange.baseArrayLayer = 0;
125 viewInfo.subresourceRange.layerCount = 1;
126
127 ANGLE_TRY(mImageView.init(device, viewInfo));
128
Jamie Madill5547b382017-10-23 18:16:01 -0400129 // Create a simple sampler. Force basic parameter settings.
130 // TODO(jmadill): Sampler parameters.
131 VkSamplerCreateInfo samplerInfo;
132 samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
133 samplerInfo.pNext = nullptr;
134 samplerInfo.flags = 0;
135 samplerInfo.magFilter = VK_FILTER_NEAREST;
136 samplerInfo.minFilter = VK_FILTER_NEAREST;
137 samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
138 samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
139 samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
140 samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
141 samplerInfo.mipLodBias = 0.0f;
142 samplerInfo.anisotropyEnable = VK_FALSE;
143 samplerInfo.maxAnisotropy = 1.0f;
144 samplerInfo.compareEnable = VK_FALSE;
145 samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
146 samplerInfo.minLod = 0.0f;
147 samplerInfo.maxLod = 1.0f;
148 samplerInfo.borderColor = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
149 samplerInfo.unnormalizedCoordinates = VK_FALSE;
150
151 ANGLE_TRY(mSampler.init(device, samplerInfo));
152
Jamie Madill035fd6b2017-10-03 15:43:22 -0400153 // Handle initial data.
154 // TODO(jmadill): Consider re-using staging texture.
155 if (pixels)
156 {
157 vk::StagingImage stagingImage;
158 ANGLE_TRY(renderer->createStagingImage(TextureDimension::TEX_2D, vkFormat, size,
159 vk::StagingUsage::Write, &stagingImage));
160
161 GLuint inputRowPitch = 0;
162 ANGLE_TRY_RESULT(
163 formatInfo.computeRowPitch(type, size.width, unpack.alignment, unpack.rowLength),
164 inputRowPitch);
165
166 GLuint inputDepthPitch = 0;
167 ANGLE_TRY_RESULT(
168 formatInfo.computeDepthPitch(size.height, unpack.imageHeight, inputRowPitch),
169 inputDepthPitch);
170
171 // TODO(jmadill): skip images for 3D Textures.
172 bool applySkipImages = false;
173
174 GLuint inputSkipBytes = 0;
175 ANGLE_TRY_RESULT(
176 formatInfo.computeSkipBytes(inputRowPitch, inputDepthPitch, unpack, applySkipImages),
177 inputSkipBytes);
178
179 auto loadFunction = vkFormat.getLoadFunctions()(type);
180
181 uint8_t *mapPointer = nullptr;
Jamie Madill815a6c92017-10-21 14:33:04 -0400182 ANGLE_TRY(stagingImage.getDeviceMemory().map(device, 0, VK_WHOLE_SIZE, 0, &mapPointer));
Jamie Madill035fd6b2017-10-03 15:43:22 -0400183
184 const uint8_t *source = pixels + inputSkipBytes;
185
Jamie Madill815a6c92017-10-21 14:33:04 -0400186 // Get the subresource layout. This has important parameters like row pitch.
187 // TODO(jmadill): Fill out this structure based on input parameters.
188 VkImageSubresource subresource;
189 subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
190 subresource.mipLevel = 0;
191 subresource.arrayLayer = 0;
192
193 VkSubresourceLayout subresourceLayout;
194 vkGetImageSubresourceLayout(device, stagingImage.getImage().getHandle(), &subresource,
195 &subresourceLayout);
196
Jamie Madill035fd6b2017-10-03 15:43:22 -0400197 loadFunction.loadFunction(size.width, size.height, size.depth, source, inputRowPitch,
Jamie Madill815a6c92017-10-21 14:33:04 -0400198 inputDepthPitch, mapPointer,
199 static_cast<size_t>(subresourceLayout.rowPitch),
200 static_cast<size_t>(subresourceLayout.depthPitch));
Jamie Madill035fd6b2017-10-03 15:43:22 -0400201
202 stagingImage.getDeviceMemory().unmap(device);
203
204 vk::CommandBuffer *commandBuffer = nullptr;
205 ANGLE_TRY(contextVk->getStartedCommandBuffer(&commandBuffer));
206 setQueueSerial(renderer->getCurrentQueueSerial());
207
208 stagingImage.getImage().changeLayoutTop(
209 VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, commandBuffer);
210 mImage.changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
211 commandBuffer);
212
213 gl::Box wholeRegion(0, 0, 0, size.width, size.height, size.depth);
214 commandBuffer->copySingleImage(stagingImage.getImage(), mImage, wholeRegion,
215 VK_IMAGE_ASPECT_COLOR_BIT);
216
217 // TODO(jmadill): Re-use staging images.
218 renderer->enqueueGarbage(renderer->getCurrentQueueSerial(), std::move(stagingImage));
219 }
220
221 return gl::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400222}
223
Jamie Madillc564c072017-06-01 12:45:42 -0400224gl::Error TextureVk::setSubImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500225 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400226 size_t level,
227 const gl::Box &area,
228 GLenum format,
229 GLenum type,
230 const gl::PixelUnpackState &unpack,
231 const uint8_t *pixels)
232{
233 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500234 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400235}
236
Jamie Madillc564c072017-06-01 12:45:42 -0400237gl::Error TextureVk::setCompressedImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500238 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400239 size_t level,
240 GLenum internalFormat,
241 const gl::Extents &size,
242 const gl::PixelUnpackState &unpack,
243 size_t imageSize,
244 const uint8_t *pixels)
245{
246 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500247 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400248}
249
Jamie Madillc564c072017-06-01 12:45:42 -0400250gl::Error TextureVk::setCompressedSubImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500251 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400252 size_t level,
253 const gl::Box &area,
254 GLenum format,
255 const gl::PixelUnpackState &unpack,
256 size_t imageSize,
257 const uint8_t *pixels)
258{
259 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500260 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400261}
262
Jamie Madillc564c072017-06-01 12:45:42 -0400263gl::Error TextureVk::copyImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500264 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400265 size_t level,
266 const gl::Rectangle &sourceArea,
267 GLenum internalFormat,
268 const gl::Framebuffer *source)
269{
270 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500271 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400272}
273
Jamie Madillc564c072017-06-01 12:45:42 -0400274gl::Error TextureVk::copySubImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500275 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400276 size_t level,
277 const gl::Offset &destOffset,
278 const gl::Rectangle &sourceArea,
279 const gl::Framebuffer *source)
280{
281 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500282 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400283}
284
Jamie Madillc564c072017-06-01 12:45:42 -0400285gl::Error TextureVk::setStorage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500286 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400287 size_t levels,
288 GLenum internalFormat,
289 const gl::Extents &size)
290{
291 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500292 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400293}
294
Jamie Madill4928b7c2017-06-20 12:57:39 -0400295gl::Error TextureVk::setEGLImageTarget(const gl::Context *context, GLenum target, egl::Image *image)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400296{
297 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500298 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400299}
300
Jamie Madill4928b7c2017-06-20 12:57:39 -0400301gl::Error TextureVk::setImageExternal(const gl::Context *context,
302 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400303 egl::Stream *stream,
304 const egl::Stream::GLTextureDescription &desc)
305{
306 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500307 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400308}
309
Jamie Madillc564c072017-06-01 12:45:42 -0400310gl::Error TextureVk::generateMipmap(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400311{
312 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500313 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400314}
315
Jamie Madill4928b7c2017-06-20 12:57:39 -0400316gl::Error TextureVk::setBaseLevel(const gl::Context *context, GLuint baseLevel)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400317{
318 UNIMPLEMENTED();
Jamie Madill4928b7c2017-06-20 12:57:39 -0400319 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400320}
321
Jamie Madill4928b7c2017-06-20 12:57:39 -0400322gl::Error TextureVk::bindTexImage(const gl::Context *context, egl::Surface *surface)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400323{
324 UNIMPLEMENTED();
Jamie Madill4928b7c2017-06-20 12:57:39 -0400325 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400326}
327
Jamie Madill4928b7c2017-06-20 12:57:39 -0400328gl::Error TextureVk::releaseTexImage(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400329{
330 UNIMPLEMENTED();
Jamie Madill4928b7c2017-06-20 12:57:39 -0400331 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400332}
333
Jamie Madill4928b7c2017-06-20 12:57:39 -0400334gl::Error TextureVk::getAttachmentRenderTarget(const gl::Context *context,
335 GLenum binding,
Jamie Madill4fd95d52017-04-05 11:22:18 -0400336 const gl::ImageIndex &imageIndex,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400337 FramebufferAttachmentRenderTarget **rtOut)
338{
339 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500340 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400341}
342
Geoff Lang22416862016-06-08 16:14:36 -0700343void TextureVk::syncState(const gl::Texture::DirtyBits &dirtyBits)
344{
Jamie Madill5547b382017-10-23 18:16:01 -0400345 // TODO(jmadill): Texture sync state.
Geoff Lang22416862016-06-08 16:14:36 -0700346}
347
Jamie Madillc564c072017-06-01 12:45:42 -0400348gl::Error TextureVk::setStorageMultisample(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500349 GLenum target,
JiangYizhoubddc46b2016-12-09 09:50:51 +0800350 GLsizei samples,
351 GLint internalformat,
352 const gl::Extents &size,
353 GLboolean fixedSampleLocations)
354{
355 UNIMPLEMENTED();
356 return gl::InternalError() << "setStorageMultisample is unimplemented.";
357}
358
Jamie Madill05b35b22017-10-03 09:01:44 -0400359gl::Error TextureVk::initializeContents(const gl::Context *context,
360 const gl::ImageIndex &imageIndex)
361{
362 UNIMPLEMENTED();
363 return gl::NoError();
364}
365
Jamie Madill5547b382017-10-23 18:16:01 -0400366const vk::Image &TextureVk::getImage() const
367{
368 ASSERT(mImage.valid());
369 return mImage;
370}
371
372const vk::ImageView &TextureVk::getImageView() const
373{
374 ASSERT(mImageView.valid());
375 return mImageView;
376}
377
378const vk::Sampler &TextureVk::getSampler() const
379{
380 ASSERT(mSampler.valid());
381 return mSampler;
382}
383
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400384} // namespace rx