Add support for cubemap arrays;

- Cubemaps can have any layer count that is a multiple of 6.
- A cubemap with more than 6 layers will be a cubemap array image view.
  - This isn't perfect because it conflates regular cubemaps with
    6-layer cubemap arrays.
- Enable the vk feature, handle the spv feature, add getPixel helper.
This commit is contained in:
bjorn 2023-11-10 11:15:16 -08:00
parent 67b1929af6
commit e0e1bc68f9
3 changed files with 17 additions and 14 deletions

View File

@ -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

View File

@ -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;

View File

@ -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");