• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 Collabora Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * on the rights to use, copy, modify, merge, publish, distribute, sub
8  * license, and/or sell copies of the Software, and to permit persons to whom
9  * the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21  * USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include "zink_context.h"
25 #include "zink_resource.h"
26 #include "zink_screen.h"
27 #include "zink_surface.h"
28 
29 #include "util/format/u_format.h"
30 #include "util/u_inlines.h"
31 #include "util/u_memory.h"
32 
33 static struct pipe_surface *
zink_create_surface(struct pipe_context * pctx,struct pipe_resource * pres,const struct pipe_surface * templ)34 zink_create_surface(struct pipe_context *pctx,
35                     struct pipe_resource *pres,
36                     const struct pipe_surface *templ)
37 {
38    struct zink_screen *screen = zink_screen(pctx->screen);
39    unsigned int level = templ->u.tex.level;
40 
41    struct zink_surface *surface = CALLOC_STRUCT(zink_surface);
42    if (!surface)
43       return NULL;
44 
45    pipe_resource_reference(&surface->base.texture, pres);
46    pipe_reference_init(&surface->base.reference, 1);
47    surface->base.context = pctx;
48    surface->base.format = templ->format;
49    surface->base.width = u_minify(pres->width0, level);
50    surface->base.height = u_minify(pres->height0, level);
51    surface->base.nr_samples = templ->nr_samples;
52    surface->base.u.tex.level = level;
53    surface->base.u.tex.first_layer = templ->u.tex.first_layer;
54    surface->base.u.tex.last_layer = templ->u.tex.last_layer;
55 
56    struct zink_resource *res = zink_resource(pres);
57 
58    VkImageViewCreateInfo ivci = {};
59    ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
60    ivci.image = res->image;
61 
62    switch (pres->target) {
63    case PIPE_TEXTURE_1D:
64       ivci.viewType = VK_IMAGE_VIEW_TYPE_1D;
65       break;
66 
67    case PIPE_TEXTURE_1D_ARRAY:
68       ivci.viewType = VK_IMAGE_VIEW_TYPE_1D_ARRAY;
69       break;
70 
71    case PIPE_TEXTURE_2D:
72    case PIPE_TEXTURE_RECT:
73       ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
74       break;
75 
76    case PIPE_TEXTURE_2D_ARRAY:
77       ivci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
78       break;
79 
80    case PIPE_TEXTURE_CUBE:
81       ivci.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
82       break;
83 
84    case PIPE_TEXTURE_CUBE_ARRAY:
85       ivci.viewType = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
86       break;
87 
88    case PIPE_TEXTURE_3D:
89       ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
90       break;
91 
92    default:
93       unreachable("unsupported target");
94    }
95 
96    ivci.format = zink_get_format(screen, templ->format);
97    assert(ivci.format != VK_FORMAT_UNDEFINED);
98 
99    // TODO: format swizzles
100    ivci.components.r = VK_COMPONENT_SWIZZLE_R;
101    ivci.components.g = VK_COMPONENT_SWIZZLE_G;
102    ivci.components.b = VK_COMPONENT_SWIZZLE_B;
103    ivci.components.a = VK_COMPONENT_SWIZZLE_A;
104 
105    ivci.subresourceRange.aspectMask = res->aspect;
106    ivci.subresourceRange.baseMipLevel = templ->u.tex.level;
107    ivci.subresourceRange.levelCount = 1;
108    ivci.subresourceRange.baseArrayLayer = templ->u.tex.first_layer;
109    ivci.subresourceRange.layerCount = 1 + templ->u.tex.last_layer - templ->u.tex.first_layer;
110 
111    if (pres->target == PIPE_TEXTURE_CUBE ||
112        pres->target == PIPE_TEXTURE_CUBE_ARRAY)
113       ivci.subresourceRange.layerCount *= 6;
114 
115    if (vkCreateImageView(screen->dev, &ivci, NULL,
116                          &surface->image_view) != VK_SUCCESS) {
117       FREE(surface);
118       return NULL;
119    }
120 
121    return &surface->base;
122 }
123 
124 static void
zink_surface_destroy(struct pipe_context * pctx,struct pipe_surface * psurface)125 zink_surface_destroy(struct pipe_context *pctx,
126                      struct pipe_surface *psurface)
127 {
128    struct zink_screen *screen = zink_screen(pctx->screen);
129    struct zink_surface *surface = zink_surface(psurface);
130    pipe_resource_reference(&psurface->texture, NULL);
131    vkDestroyImageView(screen->dev, surface->image_view, NULL);
132    FREE(surface);
133 }
134 
135 void
zink_context_surface_init(struct pipe_context * context)136 zink_context_surface_init(struct pipe_context *context)
137 {
138    context->create_surface = zink_create_surface;
139    context->surface_destroy = zink_surface_destroy;
140 }
141