blob: 0b15df55fae625427136c972a4863b50f7230bb6 [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
Jamie Madille88ec8e2017-10-31 17:18:14 -040034 renderer->releaseResource(*this, &mImage);
35 renderer->releaseResource(*this, &mDeviceMemory);
36 renderer->releaseResource(*this, &mImageView);
37 renderer->releaseResource(*this, &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 Madill1b038242017-11-01 15:14:36 -040052 ContextVk *contextVk = GetImplAs<ContextVk>(context);
53 RendererVk *renderer = contextVk->getRenderer();
54
Jamie Madill035fd6b2017-10-03 15:43:22 -040055 // TODO(jmadill): support multi-level textures.
56 ASSERT(level == 0);
57
Jamie Madill1b038242017-11-01 15:14:36 -040058 if (mImage.valid())
59 {
60 const gl::ImageDesc &desc = mState.getImageDesc(target, level);
61
62 // TODO(jmadill): Consider comparing stored vk::Format.
63 if (desc.size != size ||
64 !gl::Format::SameSized(desc.format, gl::Format(internalFormat, type)))
65 {
66 renderer->releaseResource(*this, &mImage);
67 renderer->releaseResource(*this, &mDeviceMemory);
68 renderer->releaseResource(*this, &mImageView);
69 }
70 }
Jamie Madill035fd6b2017-10-03 15:43:22 -040071
72 // TODO(jmadill): support other types of textures.
73 ASSERT(target == GL_TEXTURE_2D);
74
75 // Convert internalFormat to sized internal format.
76 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
77 const vk::Format &vkFormat = vk::Format::Get(formatInfo.sizedInternalFormat);
78
Jamie Madill1b038242017-11-01 15:14:36 -040079 VkDevice device = contextVk->getDevice();
Jamie Madill035fd6b2017-10-03 15:43:22 -040080
Jamie Madill1b038242017-11-01 15:14:36 -040081 if (!mImage.valid())
82 {
83 ASSERT(!mDeviceMemory.valid() && !mImageView.valid());
Jamie Madill035fd6b2017-10-03 15:43:22 -040084
Jamie Madill1b038242017-11-01 15:14:36 -040085 VkImageCreateInfo imageInfo;
86 imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
87 imageInfo.pNext = nullptr;
88 imageInfo.flags = 0;
89 imageInfo.imageType = VK_IMAGE_TYPE_2D;
90 imageInfo.format = vkFormat.native;
91 imageInfo.extent.width = size.width;
92 imageInfo.extent.height = size.height;
93 imageInfo.extent.depth = size.depth;
94 imageInfo.mipLevels = 1;
95 imageInfo.arrayLayers = 1;
96 imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
97 imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
Jamie Madill035fd6b2017-10-03 15:43:22 -040098
Jamie Madill1b038242017-11-01 15:14:36 -040099 // TODO(jmadill): Are all these image transfer bits necessary?
100 imageInfo.usage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
101 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
102 imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
103 imageInfo.queueFamilyIndexCount = 0;
104 imageInfo.pQueueFamilyIndices = nullptr;
105 imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
Jamie Madill035fd6b2017-10-03 15:43:22 -0400106
Jamie Madill1b038242017-11-01 15:14:36 -0400107 ANGLE_TRY(mImage.init(device, imageInfo));
Jamie Madill035fd6b2017-10-03 15:43:22 -0400108
Jamie Madill1b038242017-11-01 15:14:36 -0400109 // Allocate the device memory for the image.
110 // TODO(jmadill): Use more intelligent device memory allocation.
111 VkMemoryRequirements memoryRequirements;
112 mImage.getMemoryRequirements(device, &memoryRequirements);
Jamie Madill035fd6b2017-10-03 15:43:22 -0400113
Jamie Madill1b038242017-11-01 15:14:36 -0400114 uint32_t memoryIndex = renderer->getMemoryProperties().findCompatibleMemoryIndex(
115 memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
Jamie Madill035fd6b2017-10-03 15:43:22 -0400116
Jamie Madill1b038242017-11-01 15:14:36 -0400117 VkMemoryAllocateInfo allocateInfo;
118 allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
119 allocateInfo.pNext = nullptr;
120 allocateInfo.allocationSize = memoryRequirements.size;
121 allocateInfo.memoryTypeIndex = memoryIndex;
Jamie Madill035fd6b2017-10-03 15:43:22 -0400122
Jamie Madill1b038242017-11-01 15:14:36 -0400123 ANGLE_TRY(mDeviceMemory.allocate(device, allocateInfo));
124 ANGLE_TRY(mImage.bindMemory(device, mDeviceMemory));
Jamie Madill035fd6b2017-10-03 15:43:22 -0400125
Jamie Madill1b038242017-11-01 15:14:36 -0400126 VkImageViewCreateInfo viewInfo;
127 viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
128 viewInfo.pNext = nullptr;
129 viewInfo.flags = 0;
130 viewInfo.image = mImage.getHandle();
131 viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
132 viewInfo.format = vkFormat.native;
133 viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
134 viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
135 viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
136 viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
137 viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
138 viewInfo.subresourceRange.baseMipLevel = 0;
139 viewInfo.subresourceRange.levelCount = 1;
140 viewInfo.subresourceRange.baseArrayLayer = 0;
141 viewInfo.subresourceRange.layerCount = 1;
Jamie Madill035fd6b2017-10-03 15:43:22 -0400142
Jamie Madill1b038242017-11-01 15:14:36 -0400143 ANGLE_TRY(mImageView.init(device, viewInfo));
144 }
Jamie Madill5547b382017-10-23 18:16:01 -0400145
Jamie Madill1b038242017-11-01 15:14:36 -0400146 if (!mSampler.valid())
147 {
148 // Create a simple sampler. Force basic parameter settings.
149 // TODO(jmadill): Sampler parameters.
150 VkSamplerCreateInfo samplerInfo;
151 samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
152 samplerInfo.pNext = nullptr;
153 samplerInfo.flags = 0;
154 samplerInfo.magFilter = VK_FILTER_NEAREST;
155 samplerInfo.minFilter = VK_FILTER_NEAREST;
156 samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
157 samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
158 samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
159 samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
160 samplerInfo.mipLodBias = 0.0f;
161 samplerInfo.anisotropyEnable = VK_FALSE;
162 samplerInfo.maxAnisotropy = 1.0f;
163 samplerInfo.compareEnable = VK_FALSE;
164 samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
165 samplerInfo.minLod = 0.0f;
166 samplerInfo.maxLod = 1.0f;
167 samplerInfo.borderColor = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
168 samplerInfo.unnormalizedCoordinates = VK_FALSE;
169
170 ANGLE_TRY(mSampler.init(device, samplerInfo));
171 }
Jamie Madill5547b382017-10-23 18:16:01 -0400172
Jamie Madillb79e7bb2017-10-24 13:55:50 -0400173 mRenderTarget.image = &mImage;
174 mRenderTarget.imageView = &mImageView;
175 mRenderTarget.format = &vkFormat;
176 mRenderTarget.extents = size;
177 mRenderTarget.samples = VK_SAMPLE_COUNT_1_BIT;
178 mRenderTarget.resource = this;
179
Jamie Madill035fd6b2017-10-03 15:43:22 -0400180 // Handle initial data.
181 // TODO(jmadill): Consider re-using staging texture.
182 if (pixels)
183 {
184 vk::StagingImage stagingImage;
185 ANGLE_TRY(renderer->createStagingImage(TextureDimension::TEX_2D, vkFormat, size,
186 vk::StagingUsage::Write, &stagingImage));
187
188 GLuint inputRowPitch = 0;
189 ANGLE_TRY_RESULT(
190 formatInfo.computeRowPitch(type, size.width, unpack.alignment, unpack.rowLength),
191 inputRowPitch);
192
193 GLuint inputDepthPitch = 0;
194 ANGLE_TRY_RESULT(
195 formatInfo.computeDepthPitch(size.height, unpack.imageHeight, inputRowPitch),
196 inputDepthPitch);
197
198 // TODO(jmadill): skip images for 3D Textures.
199 bool applySkipImages = false;
200
201 GLuint inputSkipBytes = 0;
202 ANGLE_TRY_RESULT(
203 formatInfo.computeSkipBytes(inputRowPitch, inputDepthPitch, unpack, applySkipImages),
204 inputSkipBytes);
205
206 auto loadFunction = vkFormat.getLoadFunctions()(type);
207
208 uint8_t *mapPointer = nullptr;
Jamie Madill815a6c92017-10-21 14:33:04 -0400209 ANGLE_TRY(stagingImage.getDeviceMemory().map(device, 0, VK_WHOLE_SIZE, 0, &mapPointer));
Jamie Madill035fd6b2017-10-03 15:43:22 -0400210
211 const uint8_t *source = pixels + inputSkipBytes;
212
Jamie Madill815a6c92017-10-21 14:33:04 -0400213 // Get the subresource layout. This has important parameters like row pitch.
214 // TODO(jmadill): Fill out this structure based on input parameters.
215 VkImageSubresource subresource;
216 subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
217 subresource.mipLevel = 0;
218 subresource.arrayLayer = 0;
219
220 VkSubresourceLayout subresourceLayout;
221 vkGetImageSubresourceLayout(device, stagingImage.getImage().getHandle(), &subresource,
222 &subresourceLayout);
223
Jamie Madill035fd6b2017-10-03 15:43:22 -0400224 loadFunction.loadFunction(size.width, size.height, size.depth, source, inputRowPitch,
Jamie Madill815a6c92017-10-21 14:33:04 -0400225 inputDepthPitch, mapPointer,
226 static_cast<size_t>(subresourceLayout.rowPitch),
227 static_cast<size_t>(subresourceLayout.depthPitch));
Jamie Madill035fd6b2017-10-03 15:43:22 -0400228
229 stagingImage.getDeviceMemory().unmap(device);
230
231 vk::CommandBuffer *commandBuffer = nullptr;
232 ANGLE_TRY(contextVk->getStartedCommandBuffer(&commandBuffer));
233 setQueueSerial(renderer->getCurrentQueueSerial());
234
Jamie Madill1b038242017-11-01 15:14:36 -0400235 // Ensure we aren't in a render pass.
236 // TODO(jmadill): Command reordering.
237 renderer->endRenderPass();
238
Jamie Madill035fd6b2017-10-03 15:43:22 -0400239 stagingImage.getImage().changeLayoutTop(
240 VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, commandBuffer);
241 mImage.changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
242 commandBuffer);
243
244 gl::Box wholeRegion(0, 0, 0, size.width, size.height, size.depth);
245 commandBuffer->copySingleImage(stagingImage.getImage(), mImage, wholeRegion,
246 VK_IMAGE_ASPECT_COLOR_BIT);
247
248 // TODO(jmadill): Re-use staging images.
Jamie Madille88ec8e2017-10-31 17:18:14 -0400249 renderer->releaseObject(renderer->getCurrentQueueSerial(), &stagingImage);
Jamie Madill035fd6b2017-10-03 15:43:22 -0400250 }
251
252 return gl::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400253}
254
Jamie Madillc564c072017-06-01 12:45:42 -0400255gl::Error TextureVk::setSubImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500256 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400257 size_t level,
258 const gl::Box &area,
259 GLenum format,
260 GLenum type,
261 const gl::PixelUnpackState &unpack,
262 const uint8_t *pixels)
263{
264 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500265 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400266}
267
Jamie Madillc564c072017-06-01 12:45:42 -0400268gl::Error TextureVk::setCompressedImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500269 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400270 size_t level,
271 GLenum internalFormat,
272 const gl::Extents &size,
273 const gl::PixelUnpackState &unpack,
274 size_t imageSize,
275 const uint8_t *pixels)
276{
277 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500278 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400279}
280
Jamie Madillc564c072017-06-01 12:45:42 -0400281gl::Error TextureVk::setCompressedSubImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500282 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400283 size_t level,
284 const gl::Box &area,
285 GLenum format,
286 const gl::PixelUnpackState &unpack,
287 size_t imageSize,
288 const uint8_t *pixels)
289{
290 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500291 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400292}
293
Jamie Madillc564c072017-06-01 12:45:42 -0400294gl::Error TextureVk::copyImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500295 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400296 size_t level,
297 const gl::Rectangle &sourceArea,
298 GLenum internalFormat,
299 const gl::Framebuffer *source)
300{
301 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500302 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400303}
304
Jamie Madillc564c072017-06-01 12:45:42 -0400305gl::Error TextureVk::copySubImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500306 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400307 size_t level,
308 const gl::Offset &destOffset,
309 const gl::Rectangle &sourceArea,
310 const gl::Framebuffer *source)
311{
312 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500313 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400314}
315
Jamie Madillc564c072017-06-01 12:45:42 -0400316gl::Error TextureVk::setStorage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500317 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400318 size_t levels,
319 GLenum internalFormat,
320 const gl::Extents &size)
321{
322 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500323 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400324}
325
Jamie Madill4928b7c2017-06-20 12:57:39 -0400326gl::Error TextureVk::setEGLImageTarget(const gl::Context *context, GLenum target, egl::Image *image)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400327{
328 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500329 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400330}
331
Jamie Madill4928b7c2017-06-20 12:57:39 -0400332gl::Error TextureVk::setImageExternal(const gl::Context *context,
333 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400334 egl::Stream *stream,
335 const egl::Stream::GLTextureDescription &desc)
336{
337 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500338 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400339}
340
Jamie Madillc564c072017-06-01 12:45:42 -0400341gl::Error TextureVk::generateMipmap(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400342{
343 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500344 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400345}
346
Jamie Madill4928b7c2017-06-20 12:57:39 -0400347gl::Error TextureVk::setBaseLevel(const gl::Context *context, GLuint baseLevel)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400348{
349 UNIMPLEMENTED();
Jamie Madill4928b7c2017-06-20 12:57:39 -0400350 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400351}
352
Jamie Madill4928b7c2017-06-20 12:57:39 -0400353gl::Error TextureVk::bindTexImage(const gl::Context *context, egl::Surface *surface)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400354{
355 UNIMPLEMENTED();
Jamie Madill4928b7c2017-06-20 12:57:39 -0400356 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400357}
358
Jamie Madill4928b7c2017-06-20 12:57:39 -0400359gl::Error TextureVk::releaseTexImage(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400360{
361 UNIMPLEMENTED();
Jamie Madill4928b7c2017-06-20 12:57:39 -0400362 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400363}
364
Jamie Madill4928b7c2017-06-20 12:57:39 -0400365gl::Error TextureVk::getAttachmentRenderTarget(const gl::Context *context,
366 GLenum binding,
Jamie Madill4fd95d52017-04-05 11:22:18 -0400367 const gl::ImageIndex &imageIndex,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400368 FramebufferAttachmentRenderTarget **rtOut)
369{
Jamie Madillb79e7bb2017-10-24 13:55:50 -0400370 ASSERT(imageIndex.type == GL_TEXTURE_2D);
371 ASSERT(imageIndex.mipIndex == 0 && imageIndex.layerIndex == gl::ImageIndex::ENTIRE_LEVEL);
372 *rtOut = &mRenderTarget;
373 return gl::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400374}
375
Geoff Lang22416862016-06-08 16:14:36 -0700376void TextureVk::syncState(const gl::Texture::DirtyBits &dirtyBits)
377{
Jamie Madill5547b382017-10-23 18:16:01 -0400378 // TODO(jmadill): Texture sync state.
Geoff Lang22416862016-06-08 16:14:36 -0700379}
380
Jamie Madillc564c072017-06-01 12:45:42 -0400381gl::Error TextureVk::setStorageMultisample(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500382 GLenum target,
JiangYizhoubddc46b2016-12-09 09:50:51 +0800383 GLsizei samples,
384 GLint internalformat,
385 const gl::Extents &size,
386 GLboolean fixedSampleLocations)
387{
388 UNIMPLEMENTED();
389 return gl::InternalError() << "setStorageMultisample is unimplemented.";
390}
391
Jamie Madill05b35b22017-10-03 09:01:44 -0400392gl::Error TextureVk::initializeContents(const gl::Context *context,
393 const gl::ImageIndex &imageIndex)
394{
395 UNIMPLEMENTED();
396 return gl::NoError();
397}
398
Jamie Madill5547b382017-10-23 18:16:01 -0400399const vk::Image &TextureVk::getImage() const
400{
401 ASSERT(mImage.valid());
402 return mImage;
403}
404
405const vk::ImageView &TextureVk::getImageView() const
406{
407 ASSERT(mImageView.valid());
408 return mImageView;
409}
410
411const vk::Sampler &TextureVk::getSampler() const
412{
413 ASSERT(mSampler.valid());
414 return mSampler;
415}
416
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400417} // namespace rx