diff --git a/etc/shaders/lovr.glsl b/etc/shaders/lovr.glsl index 83885742..4928e1ff 100644 --- a/etc/shaders/lovr.glsl +++ b/etc/shaders/lovr.glsl @@ -196,6 +196,7 @@ vec4 getPixel(texture2D t, vec2 uv) { return texture(sampler2D(t, Sampler), uv); vec4 getPixel(texture3D t, vec3 uvw) { return texture(sampler3D(t, Sampler), uvw); } vec4 getPixel(textureCube t, vec3 dir) { return texture(samplerCube(t, Sampler), dir); } vec4 getPixel(texture2DArray t, vec2 uv, float layer) { return texture(sampler2DArray(t, Sampler), vec3(uv, layer)); } +vec4 getPixel(textureCubeArray t, vec4 coord) { return texture(samplerCubeArray(t, Sampler), coord); } #endif #ifdef GL_FRAGMENT_SHADER diff --git a/src/core/gpu_vk.c b/src/core/gpu_vk.c index 1487502b..ded027b4 100644 --- a/src/core/gpu_vk.c +++ b/src/core/gpu_vk.c @@ -649,24 +649,25 @@ bool gpu_texture_init_view(gpu_texture* texture, gpu_texture_view_info* info) { texture->srgb = !info->linear; } - static const VkImageViewType types[] = { - [GPU_TEXTURE_2D] = VK_IMAGE_VIEW_TYPE_2D, - [GPU_TEXTURE_3D] = VK_IMAGE_VIEW_TYPE_3D, - [GPU_TEXTURE_CUBE] = VK_IMAGE_VIEW_TYPE_CUBE, - [GPU_TEXTURE_ARRAY] = VK_IMAGE_VIEW_TYPE_2D_ARRAY - }; + VkImageViewType type; + switch (info->type) { + case GPU_TEXTURE_2D: type = VK_IMAGE_VIEW_TYPE_2D; break; + case GPU_TEXTURE_3D: type = VK_IMAGE_VIEW_TYPE_3D; break; + case GPU_TEXTURE_CUBE: type = texture->layers > 6 ? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY : VK_IMAGE_VIEW_TYPE_CUBE; break; + case GPU_TEXTURE_ARRAY: type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; break; + } VkImageViewCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .image = info->source->handle, - .viewType = types[info->type], + .viewType = type, .format = convertFormat(texture->format, texture->srgb), .subresourceRange = { .aspectMask = texture->aspect, - .baseMipLevel = info ? info->levelIndex : 0, - .levelCount = (info && info->levelCount) ? info->levelCount : VK_REMAINING_MIP_LEVELS, + .baseMipLevel = info->levelIndex, + .levelCount = info->levelCount ? info->levelCount : VK_REMAINING_MIP_LEVELS, .baseArrayLayer = info ? info->layerIndex : 0, - .layerCount = (info && info->layerCount) ? info->layerCount : VK_REMAINING_ARRAY_LAYERS + .layerCount = info->layerCount ? info->layerCount : VK_REMAINING_ARRAY_LAYERS } }; @@ -2175,6 +2176,7 @@ bool gpu_init(gpu_config* config) { // Required features enable->fullDrawIndexUint32 = true; + enable->imageCubeArray = true; enable->independentBlend = true; multiviewFeatures.multiview = true; shaderDrawParameterFeatures.shaderDrawParameters = true; diff --git a/src/modules/graphics/graphics.c b/src/modules/graphics/graphics.c index f8c1a328..9c729c4a 100644 --- a/src/modules/graphics/graphics.c +++ b/src/modules/graphics/graphics.c @@ -2026,9 +2026,9 @@ Texture* lovrTextureCreate(const TextureInfo* info) { lovrCheck(info->width <= limit, "Texture %s exceeds the limit for this texture type (%d)", "width", limit); lovrCheck(info->height <= limit, "Texture %s exceeds the limit for this texture type (%d)", "height", limit); lovrCheck(info->layers <= limit || info->type != TEXTURE_3D, "Texture %s exceeds the limit for this texture type (%d)", "layer count", limit); - lovrCheck(info->layers <= state.limits.textureLayers || info->type != TEXTURE_ARRAY, "Texture %s exceeds the limit for this texture type (%d)", "layer count", limit); + lovrCheck(info->layers <= state.limits.textureLayers || info->type == TEXTURE_3D, "Texture %s exceeds the limit for this texture type (%d)", "layer count", limit); lovrCheck(info->layers == 1 || info->type != TEXTURE_2D, "2D textures must have a layer count of 1"); - lovrCheck(info->layers == 6 || info->type != TEXTURE_CUBE, "Cubemaps must have a layer count of 6"); + lovrCheck(info->layers % 6 == 0 || info->type != TEXTURE_CUBE, "Cubemap layer count must be a multiple of 6"); lovrCheck(info->width == info->height || info->type != TEXTURE_CUBE, "Cubemaps must be square"); lovrCheck(measureTexture(info->format, info->width, info->height, info->layers) < 1 << 30, "Memory for a Texture can not exceed 1GB"); // TODO mip? lovrCheck(info->samples == 1 || info->samples == 4, "Texture multisample count must be 1 or 4...for now"); @@ -2177,7 +2177,7 @@ Texture* lovrTextureCreateView(const TextureViewInfo* view) { lovrCheck(view->levelIndex + view->levelCount <= info->mipmaps, "Texture view mipmap range exceeds mipmap count of parent texture"); lovrCheck(view->layerCount == 1 || view->type != TEXTURE_2D, "2D textures can only have a single layer"); lovrCheck(view->levelCount == 1 || info->type != TEXTURE_3D, "Views of volume textures may only have a single mipmap level"); - lovrCheck(view->layerCount == 6 || view->type != TEXTURE_CUBE, "Cubemaps can only have six layers"); + lovrCheck(view->layerCount % 6 == 0 || view->type != TEXTURE_CUBE, "Cubemap layer count must be a multiple of 6"); Texture* texture = calloc(1, sizeof(Texture) + gpu_sizeof_texture()); lovrAssert(texture, "Out of memory"); @@ -7663,7 +7663,7 @@ static void checkShaderFeatures(uint32_t* features, uint32_t count) { case 42: lovrThrow("Shader uses unsupported feature #%d: %s", features[i], "min LOD"); case 43: lovrThrow("Shader uses unsupported feature #%d: %s", features[i], "1D textures"); case 44: lovrThrow("Shader uses unsupported feature #%d: %s", features[i], "1D textures"); - case 45: lovrThrow("Shader uses unsupported feature #%d: %s", features[i], "cubemap array textures"); + case 45: break; // Cubemap arrays case 46: lovrThrow("Shader uses unsupported feature #%d: %s", features[i], "texel buffers"); case 47: lovrThrow("Shader uses unsupported feature #%d: %s", features[i], "texel buffers"); case 48: lovrThrow("Shader uses unsupported feature #%d: %s", features[i], "multisampled storage textures");