blob: d9619811803507c445b3a131eec8ca60c4445e19 [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 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 Madillb79e7bb2017-10-24 13:55:50 -0400153 mRenderTarget.image = &mImage;
154 mRenderTarget.imageView = &mImageView;
155 mRenderTarget.format = &vkFormat;
156 mRenderTarget.extents = size;
157 mRenderTarget.samples = VK_SAMPLE_COUNT_1_BIT;
158 mRenderTarget.resource = this;
159
Jamie Madill035fd6b2017-10-03 15:43:22 -0400160 // Handle initial data.
161 // TODO(jmadill): Consider re-using staging texture.
162 if (pixels)
163 {
164 vk::StagingImage stagingImage;
165 ANGLE_TRY(renderer->createStagingImage(TextureDimension::TEX_2D, vkFormat, size,
166 vk::StagingUsage::Write, &stagingImage));
167
168 GLuint inputRowPitch = 0;
169 ANGLE_TRY_RESULT(
170 formatInfo.computeRowPitch(type, size.width, unpack.alignment, unpack.rowLength),
171 inputRowPitch);
172
173 GLuint inputDepthPitch = 0;
174 ANGLE_TRY_RESULT(
175 formatInfo.computeDepthPitch(size.height, unpack.imageHeight, inputRowPitch),
176 inputDepthPitch);
177
178 // TODO(jmadill): skip images for 3D Textures.
179 bool applySkipImages = false;
180
181 GLuint inputSkipBytes = 0;
182 ANGLE_TRY_RESULT(
183 formatInfo.computeSkipBytes(inputRowPitch, inputDepthPitch, unpack, applySkipImages),
184 inputSkipBytes);
185
186 auto loadFunction = vkFormat.getLoadFunctions()(type);
187
188 uint8_t *mapPointer = nullptr;
Jamie Madill815a6c92017-10-21 14:33:04 -0400189 ANGLE_TRY(stagingImage.getDeviceMemory().map(device, 0, VK_WHOLE_SIZE, 0, &mapPointer));
Jamie Madill035fd6b2017-10-03 15:43:22 -0400190
191 const uint8_t *source = pixels + inputSkipBytes;
192
Jamie Madill815a6c92017-10-21 14:33:04 -0400193 // Get the subresource layout. This has important parameters like row pitch.
194 // TODO(jmadill): Fill out this structure based on input parameters.
195 VkImageSubresource subresource;
196 subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
197 subresource.mipLevel = 0;
198 subresource.arrayLayer = 0;
199
200 VkSubresourceLayout subresourceLayout;
201 vkGetImageSubresourceLayout(device, stagingImage.getImage().getHandle(), &subresource,
202 &subresourceLayout);
203
Jamie Madill035fd6b2017-10-03 15:43:22 -0400204 loadFunction.loadFunction(size.width, size.height, size.depth, source, inputRowPitch,
Jamie Madill815a6c92017-10-21 14:33:04 -0400205 inputDepthPitch, mapPointer,
206 static_cast<size_t>(subresourceLayout.rowPitch),
207 static_cast<size_t>(subresourceLayout.depthPitch));
Jamie Madill035fd6b2017-10-03 15:43:22 -0400208
209 stagingImage.getDeviceMemory().unmap(device);
210
211 vk::CommandBuffer *commandBuffer = nullptr;
212 ANGLE_TRY(contextVk->getStartedCommandBuffer(&commandBuffer));
213 setQueueSerial(renderer->getCurrentQueueSerial());
214
215 stagingImage.getImage().changeLayoutTop(
216 VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, commandBuffer);
217 mImage.changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
218 commandBuffer);
219
220 gl::Box wholeRegion(0, 0, 0, size.width, size.height, size.depth);
221 commandBuffer->copySingleImage(stagingImage.getImage(), mImage, wholeRegion,
222 VK_IMAGE_ASPECT_COLOR_BIT);
223
224 // TODO(jmadill): Re-use staging images.
Jamie Madille88ec8e2017-10-31 17:18:14 -0400225 renderer->releaseObject(renderer->getCurrentQueueSerial(), &stagingImage);
Jamie Madill035fd6b2017-10-03 15:43:22 -0400226 }
227
228 return gl::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400229}
230
Jamie Madillc564c072017-06-01 12:45:42 -0400231gl::Error TextureVk::setSubImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500232 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400233 size_t level,
234 const gl::Box &area,
235 GLenum format,
236 GLenum type,
237 const gl::PixelUnpackState &unpack,
238 const uint8_t *pixels)
239{
240 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500241 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400242}
243
Jamie Madillc564c072017-06-01 12:45:42 -0400244gl::Error TextureVk::setCompressedImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500245 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400246 size_t level,
247 GLenum internalFormat,
248 const gl::Extents &size,
249 const gl::PixelUnpackState &unpack,
250 size_t imageSize,
251 const uint8_t *pixels)
252{
253 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500254 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400255}
256
Jamie Madillc564c072017-06-01 12:45:42 -0400257gl::Error TextureVk::setCompressedSubImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500258 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400259 size_t level,
260 const gl::Box &area,
261 GLenum format,
262 const gl::PixelUnpackState &unpack,
263 size_t imageSize,
264 const uint8_t *pixels)
265{
266 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500267 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400268}
269
Jamie Madillc564c072017-06-01 12:45:42 -0400270gl::Error TextureVk::copyImage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500271 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400272 size_t level,
273 const gl::Rectangle &sourceArea,
274 GLenum internalFormat,
275 const gl::Framebuffer *source)
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::copySubImage(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::Offset &destOffset,
285 const gl::Rectangle &sourceArea,
286 const gl::Framebuffer *source)
287{
288 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500289 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400290}
291
Jamie Madillc564c072017-06-01 12:45:42 -0400292gl::Error TextureVk::setStorage(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500293 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400294 size_t levels,
295 GLenum internalFormat,
296 const gl::Extents &size)
297{
298 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500299 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400300}
301
Jamie Madill4928b7c2017-06-20 12:57:39 -0400302gl::Error TextureVk::setEGLImageTarget(const gl::Context *context, GLenum target, egl::Image *image)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400303{
304 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500305 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400306}
307
Jamie Madill4928b7c2017-06-20 12:57:39 -0400308gl::Error TextureVk::setImageExternal(const gl::Context *context,
309 GLenum target,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400310 egl::Stream *stream,
311 const egl::Stream::GLTextureDescription &desc)
312{
313 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500314 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400315}
316
Jamie Madillc564c072017-06-01 12:45:42 -0400317gl::Error TextureVk::generateMipmap(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400318{
319 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500320 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400321}
322
Jamie Madill4928b7c2017-06-20 12:57:39 -0400323gl::Error TextureVk::setBaseLevel(const gl::Context *context, GLuint baseLevel)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400324{
325 UNIMPLEMENTED();
Jamie Madill4928b7c2017-06-20 12:57:39 -0400326 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400327}
328
Jamie Madill4928b7c2017-06-20 12:57:39 -0400329gl::Error TextureVk::bindTexImage(const gl::Context *context, egl::Surface *surface)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400330{
331 UNIMPLEMENTED();
Jamie Madill4928b7c2017-06-20 12:57:39 -0400332 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400333}
334
Jamie Madill4928b7c2017-06-20 12:57:39 -0400335gl::Error TextureVk::releaseTexImage(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400336{
337 UNIMPLEMENTED();
Jamie Madill4928b7c2017-06-20 12:57:39 -0400338 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400339}
340
Jamie Madill4928b7c2017-06-20 12:57:39 -0400341gl::Error TextureVk::getAttachmentRenderTarget(const gl::Context *context,
342 GLenum binding,
Jamie Madill4fd95d52017-04-05 11:22:18 -0400343 const gl::ImageIndex &imageIndex,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400344 FramebufferAttachmentRenderTarget **rtOut)
345{
Jamie Madillb79e7bb2017-10-24 13:55:50 -0400346 ASSERT(imageIndex.type == GL_TEXTURE_2D);
347 ASSERT(imageIndex.mipIndex == 0 && imageIndex.layerIndex == gl::ImageIndex::ENTIRE_LEVEL);
348 *rtOut = &mRenderTarget;
349 return gl::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400350}
351
Geoff Lang22416862016-06-08 16:14:36 -0700352void TextureVk::syncState(const gl::Texture::DirtyBits &dirtyBits)
353{
Jamie Madill5547b382017-10-23 18:16:01 -0400354 // TODO(jmadill): Texture sync state.
Geoff Lang22416862016-06-08 16:14:36 -0700355}
356
Jamie Madillc564c072017-06-01 12:45:42 -0400357gl::Error TextureVk::setStorageMultisample(const gl::Context *context,
Jamie Madill8897afa2017-02-06 17:17:23 -0500358 GLenum target,
JiangYizhoubddc46b2016-12-09 09:50:51 +0800359 GLsizei samples,
360 GLint internalformat,
361 const gl::Extents &size,
362 GLboolean fixedSampleLocations)
363{
364 UNIMPLEMENTED();
365 return gl::InternalError() << "setStorageMultisample is unimplemented.";
366}
367
Jamie Madill05b35b22017-10-03 09:01:44 -0400368gl::Error TextureVk::initializeContents(const gl::Context *context,
369 const gl::ImageIndex &imageIndex)
370{
371 UNIMPLEMENTED();
372 return gl::NoError();
373}
374
Jamie Madill5547b382017-10-23 18:16:01 -0400375const vk::Image &TextureVk::getImage() const
376{
377 ASSERT(mImage.valid());
378 return mImage;
379}
380
381const vk::ImageView &TextureVk::getImageView() const
382{
383 ASSERT(mImageView.valid());
384 return mImageView;
385}
386
387const vk::Sampler &TextureVk::getSampler() const
388{
389 ASSERT(mSampler.valid());
390 return mSampler;
391}
392
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400393} // namespace rx