blob: 1bd784f8e671c4755c8b09c35928802d5dac0e2e [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));
37
38 return gl::NoError();
39}
40
Jamie Madillc564c072017-06-01 12:45:42 -040041gl::Error TextureVk::setImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -050042 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -040043 size_t level,
44 GLenum internalFormat,
45 const gl::Extents &size,
46 GLenum format,
47 GLenum type,
48 const gl::PixelUnpackState &unpack,
49 const uint8_t *pixels)
50{
Jamie Madill035fd6b2017-10-03 15:43:22 -040051 // TODO(jmadill): support multi-level textures.
52 ASSERT(level == 0);
53
54 // TODO(jmadill): support texture re-definition.
55 ASSERT(!mImage.valid());
56
57 // TODO(jmadill): support other types of textures.
58 ASSERT(target == GL_TEXTURE_2D);
59
60 // Convert internalFormat to sized internal format.
61 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
62 const vk::Format &vkFormat = vk::Format::Get(formatInfo.sizedInternalFormat);
63
64 VkImageCreateInfo imageInfo;
65 imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
66 imageInfo.pNext = nullptr;
67 imageInfo.flags = 0;
68 imageInfo.imageType = VK_IMAGE_TYPE_2D;
69 imageInfo.format = vkFormat.native;
70 imageInfo.extent.width = size.width;
71 imageInfo.extent.height = size.height;
72 imageInfo.extent.depth = size.depth;
73 imageInfo.mipLevels = 1;
74 imageInfo.arrayLayers = 1;
75 imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
76 imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
77
78 // TODO(jmadill): Are all these image transfer bits necessary?
79 imageInfo.usage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
80 VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
81 imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
82 imageInfo.queueFamilyIndexCount = 0;
83 imageInfo.pQueueFamilyIndices = nullptr;
84 imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
85
86 ContextVk *contextVk = GetImplAs<ContextVk>(context);
87 VkDevice device = contextVk->getDevice();
88 ANGLE_TRY(mImage.init(device, imageInfo));
89
90 // Allocate the device memory for the image.
91 // TODO(jmadill): Use more intelligent device memory allocation.
92 VkMemoryRequirements memoryRequirements;
93 mImage.getMemoryRequirements(device, &memoryRequirements);
94
95 RendererVk *renderer = contextVk->getRenderer();
96
97 uint32_t memoryIndex = renderer->getMemoryProperties().findCompatibleMemoryIndex(
98 memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
99
100 VkMemoryAllocateInfo allocateInfo;
101 allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
102 allocateInfo.pNext = nullptr;
103 allocateInfo.allocationSize = memoryRequirements.size;
104 allocateInfo.memoryTypeIndex = memoryIndex;
105
106 ANGLE_TRY(mDeviceMemory.allocate(device, allocateInfo));
107 ANGLE_TRY(mImage.bindMemory(device, mDeviceMemory));
108
109 VkImageViewCreateInfo viewInfo;
110 viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
111 viewInfo.pNext = nullptr;
112 viewInfo.flags = 0;
113 viewInfo.image = mImage.getHandle();
114 viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
115 viewInfo.format = vkFormat.native;
116 viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
117 viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
118 viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
119 viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
120 viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
121 viewInfo.subresourceRange.baseMipLevel = 0;
122 viewInfo.subresourceRange.levelCount = 1;
123 viewInfo.subresourceRange.baseArrayLayer = 0;
124 viewInfo.subresourceRange.layerCount = 1;
125
126 ANGLE_TRY(mImageView.init(device, viewInfo));
127
128 // Handle initial data.
129 // TODO(jmadill): Consider re-using staging texture.
130 if (pixels)
131 {
132 vk::StagingImage stagingImage;
133 ANGLE_TRY(renderer->createStagingImage(TextureDimension::TEX_2D, vkFormat, size,
134 vk::StagingUsage::Write, &stagingImage));
135
136 GLuint inputRowPitch = 0;
137 ANGLE_TRY_RESULT(
138 formatInfo.computeRowPitch(type, size.width, unpack.alignment, unpack.rowLength),
139 inputRowPitch);
140
141 GLuint inputDepthPitch = 0;
142 ANGLE_TRY_RESULT(
143 formatInfo.computeDepthPitch(size.height, unpack.imageHeight, inputRowPitch),
144 inputDepthPitch);
145
146 // TODO(jmadill): skip images for 3D Textures.
147 bool applySkipImages = false;
148
149 GLuint inputSkipBytes = 0;
150 ANGLE_TRY_RESULT(
151 formatInfo.computeSkipBytes(inputRowPitch, inputDepthPitch, unpack, applySkipImages),
152 inputSkipBytes);
153
154 auto loadFunction = vkFormat.getLoadFunctions()(type);
155
156 uint8_t *mapPointer = nullptr;
Jamie Madill815a6c92017-10-21 14:33:04 -0400157 ANGLE_TRY(stagingImage.getDeviceMemory().map(device, 0, VK_WHOLE_SIZE, 0, &mapPointer));
Jamie Madill035fd6b2017-10-03 15:43:22 -0400158
159 const uint8_t *source = pixels + inputSkipBytes;
160
Jamie Madill815a6c92017-10-21 14:33:04 -0400161 // Get the subresource layout. This has important parameters like row pitch.
162 // TODO(jmadill): Fill out this structure based on input parameters.
163 VkImageSubresource subresource;
164 subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
165 subresource.mipLevel = 0;
166 subresource.arrayLayer = 0;
167
168 VkSubresourceLayout subresourceLayout;
169 vkGetImageSubresourceLayout(device, stagingImage.getImage().getHandle(), &subresource,
170 &subresourceLayout);
171
Jamie Madill035fd6b2017-10-03 15:43:22 -0400172 loadFunction.loadFunction(size.width, size.height, size.depth, source, inputRowPitch,
Jamie Madill815a6c92017-10-21 14:33:04 -0400173 inputDepthPitch, mapPointer,
174 static_cast<size_t>(subresourceLayout.rowPitch),
175 static_cast<size_t>(subresourceLayout.depthPitch));
Jamie Madill035fd6b2017-10-03 15:43:22 -0400176
177 stagingImage.getDeviceMemory().unmap(device);
178
179 vk::CommandBuffer *commandBuffer = nullptr;
180 ANGLE_TRY(contextVk->getStartedCommandBuffer(&commandBuffer));
181 setQueueSerial(renderer->getCurrentQueueSerial());
182
183 stagingImage.getImage().changeLayoutTop(
184 VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, commandBuffer);
185 mImage.changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
186 commandBuffer);
187
188 gl::Box wholeRegion(0, 0, 0, size.width, size.height, size.depth);
189 commandBuffer->copySingleImage(stagingImage.getImage(), mImage, wholeRegion,
190 VK_IMAGE_ASPECT_COLOR_BIT);
191
192 // TODO(jmadill): Re-use staging images.
193 renderer->enqueueGarbage(renderer->getCurrentQueueSerial(), std::move(stagingImage));
194 }
195
196 return gl::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400197}
198
Jamie Madillc564c072017-06-01 12:45:42 -0400199gl::Error TextureVk::setSubImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500200 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400201 size_t level,
202 const gl::Box &area,
203 GLenum format,
204 GLenum type,
205 const gl::PixelUnpackState &unpack,
206 const uint8_t *pixels)
207{
208 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500209 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400210}
211
Jamie Madillc564c072017-06-01 12:45:42 -0400212gl::Error TextureVk::setCompressedImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500213 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400214 size_t level,
215 GLenum internalFormat,
216 const gl::Extents &size,
217 const gl::PixelUnpackState &unpack,
218 size_t imageSize,
219 const uint8_t *pixels)
220{
221 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500222 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400223}
224
Jamie Madillc564c072017-06-01 12:45:42 -0400225gl::Error TextureVk::setCompressedSubImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500226 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400227 size_t level,
228 const gl::Box &area,
229 GLenum format,
230 const gl::PixelUnpackState &unpack,
231 size_t imageSize,
232 const uint8_t *pixels)
233{
234 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500235 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400236}
237
Jamie Madillc564c072017-06-01 12:45:42 -0400238gl::Error TextureVk::copyImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500239 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400240 size_t level,
241 const gl::Rectangle &sourceArea,
242 GLenum internalFormat,
243 const gl::Framebuffer *source)
244{
245 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500246 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400247}
248
Jamie Madillc564c072017-06-01 12:45:42 -0400249gl::Error TextureVk::copySubImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500250 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400251 size_t level,
252 const gl::Offset &destOffset,
253 const gl::Rectangle &sourceArea,
254 const gl::Framebuffer *source)
255{
256 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500257 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400258}
259
Jamie Madillc564c072017-06-01 12:45:42 -0400260gl::Error TextureVk::setStorage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500261 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400262 size_t levels,
263 GLenum internalFormat,
264 const gl::Extents &size)
265{
266 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500267 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400268}
269
Jamie Madill4928b7c2017-06-20 12:57:39 -0400270gl::Error TextureVk::setEGLImageTarget(const gl::Context *context, GLenum target, egl::Image *image)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400271{
272 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500273 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400274}
275
Jamie Madill4928b7c2017-06-20 12:57:39 -0400276gl::Error TextureVk::setImageExternal(const gl::Context *context,
277 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400278 egl::Stream *stream,
279 const egl::Stream::GLTextureDescription &desc)
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::generateMipmap(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400286{
287 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500288 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400289}
290
Jamie Madill4928b7c2017-06-20 12:57:39 -0400291gl::Error TextureVk::setBaseLevel(const gl::Context *context, GLuint baseLevel)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400292{
293 UNIMPLEMENTED();
Jamie Madill4928b7c2017-06-20 12:57:39 -0400294 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400295}
296
Jamie Madill4928b7c2017-06-20 12:57:39 -0400297gl::Error TextureVk::bindTexImage(const gl::Context *context, egl::Surface *surface)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400298{
299 UNIMPLEMENTED();
Jamie Madill4928b7c2017-06-20 12:57:39 -0400300 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400301}
302
Jamie Madill4928b7c2017-06-20 12:57:39 -0400303gl::Error TextureVk::releaseTexImage(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400304{
305 UNIMPLEMENTED();
Jamie Madill4928b7c2017-06-20 12:57:39 -0400306 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400307}
308
Jamie Madill4928b7c2017-06-20 12:57:39 -0400309gl::Error TextureVk::getAttachmentRenderTarget(const gl::Context *context,
310 GLenum binding,
Jamie Madill4fd95d52017-04-05 11:22:18 -0400311 const gl::ImageIndex &imageIndex,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400312 FramebufferAttachmentRenderTarget **rtOut)
313{
314 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500315 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400316}
317
Geoff Lang22416862016-06-08 16:14:36 -0700318void TextureVk::syncState(const gl::Texture::DirtyBits &dirtyBits)
319{
320 UNIMPLEMENTED();
321}
322
Jamie Madillc564c072017-06-01 12:45:42 -0400323gl::Error TextureVk::setStorageMultisample(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500324 GLenum target,
JiangYizhoubddc46b2016-12-09 09:50:51 +0800325 GLsizei samples,
326 GLint internalformat,
327 const gl::Extents &size,
328 GLboolean fixedSampleLocations)
329{
330 UNIMPLEMENTED();
331 return gl::InternalError() << "setStorageMultisample is unimplemented.";
332}
333
Jamie Madill05b35b22017-10-03 09:01:44 -0400334gl::Error TextureVk::initializeContents(const gl::Context *context,
335 const gl::ImageIndex &imageIndex)
336{
337 UNIMPLEMENTED();
338 return gl::NoError();
339}
340
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400341} // namespace rx