1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © Microsoft Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21bf215546Sopenharmony_ci * IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#include "d3d12_context.h"
25bf215546Sopenharmony_ci#include "d3d12_format.h"
26bf215546Sopenharmony_ci#include "d3d12_resource.h"
27bf215546Sopenharmony_ci#include "d3d12_screen.h"
28bf215546Sopenharmony_ci#include "d3d12_surface.h"
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci#include "util/format/u_format.h"
31bf215546Sopenharmony_ci#include "util/u_inlines.h"
32bf215546Sopenharmony_ci#include "util/u_memory.h"
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_cistatic D3D12_DSV_DIMENSION
35bf215546Sopenharmony_ciview_dsv_dimension(enum pipe_texture_target target, unsigned samples)
36bf215546Sopenharmony_ci{
37bf215546Sopenharmony_ci   switch (target) {
38bf215546Sopenharmony_ci   case PIPE_TEXTURE_1D: return D3D12_DSV_DIMENSION_TEXTURE1D;
39bf215546Sopenharmony_ci   case PIPE_TEXTURE_1D_ARRAY: return D3D12_DSV_DIMENSION_TEXTURE1DARRAY;
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_ci   case PIPE_TEXTURE_2D:
42bf215546Sopenharmony_ci   case PIPE_TEXTURE_RECT:
43bf215546Sopenharmony_ci      return samples > 1 ? D3D12_DSV_DIMENSION_TEXTURE2DMS :
44bf215546Sopenharmony_ci                           D3D12_DSV_DIMENSION_TEXTURE2D;
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_ci   case PIPE_TEXTURE_2D_ARRAY:
47bf215546Sopenharmony_ci   case PIPE_TEXTURE_CUBE:
48bf215546Sopenharmony_ci   case PIPE_TEXTURE_CUBE_ARRAY:
49bf215546Sopenharmony_ci      return samples > 1 ? D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY :
50bf215546Sopenharmony_ci                           D3D12_DSV_DIMENSION_TEXTURE2DARRAY;
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci   default:
53bf215546Sopenharmony_ci      unreachable("unexpected target");
54bf215546Sopenharmony_ci   }
55bf215546Sopenharmony_ci}
56bf215546Sopenharmony_ci
57bf215546Sopenharmony_cistatic D3D12_RTV_DIMENSION
58bf215546Sopenharmony_ciview_rtv_dimension(enum pipe_texture_target target, unsigned samples)
59bf215546Sopenharmony_ci{
60bf215546Sopenharmony_ci   switch (target) {
61bf215546Sopenharmony_ci   case PIPE_BUFFER: return D3D12_RTV_DIMENSION_BUFFER;
62bf215546Sopenharmony_ci   case PIPE_TEXTURE_1D: return D3D12_RTV_DIMENSION_TEXTURE1D;
63bf215546Sopenharmony_ci   case PIPE_TEXTURE_1D_ARRAY: return D3D12_RTV_DIMENSION_TEXTURE1DARRAY;
64bf215546Sopenharmony_ci
65bf215546Sopenharmony_ci   case PIPE_TEXTURE_2D:
66bf215546Sopenharmony_ci   case PIPE_TEXTURE_RECT:
67bf215546Sopenharmony_ci      return samples > 1 ? D3D12_RTV_DIMENSION_TEXTURE2DMS :
68bf215546Sopenharmony_ci                           D3D12_RTV_DIMENSION_TEXTURE2D;
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ci   case PIPE_TEXTURE_2D_ARRAY:
71bf215546Sopenharmony_ci   case PIPE_TEXTURE_CUBE:
72bf215546Sopenharmony_ci   case PIPE_TEXTURE_CUBE_ARRAY:
73bf215546Sopenharmony_ci      return samples > 1 ? D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY :
74bf215546Sopenharmony_ci                           D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_ci   case PIPE_TEXTURE_3D: return D3D12_RTV_DIMENSION_TEXTURE3D;
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_ci   default:
79bf215546Sopenharmony_ci      unreachable("unexpected target");
80bf215546Sopenharmony_ci   }
81bf215546Sopenharmony_ci}
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_cistatic void
84bf215546Sopenharmony_ciinitialize_dsv(struct pipe_context *pctx,
85bf215546Sopenharmony_ci               struct pipe_resource *pres,
86bf215546Sopenharmony_ci               const struct pipe_surface *tpl,
87bf215546Sopenharmony_ci               struct d3d12_descriptor_handle *handle,
88bf215546Sopenharmony_ci               DXGI_FORMAT dxgi_format)
89bf215546Sopenharmony_ci{
90bf215546Sopenharmony_ci   struct d3d12_resource *res = d3d12_resource(pres);
91bf215546Sopenharmony_ci   struct d3d12_screen *screen = d3d12_screen(pctx->screen);
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci   D3D12_DEPTH_STENCIL_VIEW_DESC desc;
94bf215546Sopenharmony_ci   desc.Format = dxgi_format;
95bf215546Sopenharmony_ci   desc.Flags = D3D12_DSV_FLAG_NONE;
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci   desc.ViewDimension = view_dsv_dimension(pres->target, pres->nr_samples);
98bf215546Sopenharmony_ci   switch (desc.ViewDimension) {
99bf215546Sopenharmony_ci   case D3D12_DSV_DIMENSION_TEXTURE1D:
100bf215546Sopenharmony_ci      if (tpl->u.tex.first_layer > 0)
101bf215546Sopenharmony_ci         debug_printf("D3D12: can't create 1D DSV from layer %d\n",
102bf215546Sopenharmony_ci                      tpl->u.tex.first_layer);
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci      desc.Texture1D.MipSlice = tpl->u.tex.level;
105bf215546Sopenharmony_ci      break;
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci   case D3D12_DSV_DIMENSION_TEXTURE1DARRAY:
108bf215546Sopenharmony_ci      desc.Texture1DArray.MipSlice = tpl->u.tex.level;
109bf215546Sopenharmony_ci      desc.Texture1DArray.FirstArraySlice = tpl->u.tex.first_layer;
110bf215546Sopenharmony_ci      desc.Texture1DArray.ArraySize = tpl->u.tex.last_layer - tpl->u.tex.first_layer + 1;
111bf215546Sopenharmony_ci      break;
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci   case D3D12_DSV_DIMENSION_TEXTURE2DMS:
114bf215546Sopenharmony_ci      if (tpl->u.tex.first_layer > 0)
115bf215546Sopenharmony_ci         debug_printf("D3D12: can't create 2DMS DSV from layer %d\n",
116bf215546Sopenharmony_ci                      tpl->u.tex.first_layer);
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_ci      break;
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_ci   case D3D12_DSV_DIMENSION_TEXTURE2D:
121bf215546Sopenharmony_ci      if (tpl->u.tex.first_layer > 0)
122bf215546Sopenharmony_ci         debug_printf("D3D12: can't create 2D DSV from layer %d\n",
123bf215546Sopenharmony_ci                      tpl->u.tex.first_layer);
124bf215546Sopenharmony_ci
125bf215546Sopenharmony_ci      desc.Texture2D.MipSlice = tpl->u.tex.level;
126bf215546Sopenharmony_ci      break;
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci   case D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY:
129bf215546Sopenharmony_ci      desc.Texture2DMSArray.FirstArraySlice = tpl->u.tex.first_layer;
130bf215546Sopenharmony_ci      desc.Texture2DMSArray.ArraySize = tpl->u.tex.last_layer - tpl->u.tex.first_layer + 1;
131bf215546Sopenharmony_ci      break;
132bf215546Sopenharmony_ci
133bf215546Sopenharmony_ci   case D3D12_DSV_DIMENSION_TEXTURE2DARRAY:
134bf215546Sopenharmony_ci      desc.Texture2DArray.MipSlice = tpl->u.tex.level;
135bf215546Sopenharmony_ci      desc.Texture2DArray.FirstArraySlice = tpl->u.tex.first_layer;
136bf215546Sopenharmony_ci      desc.Texture2DArray.ArraySize = tpl->u.tex.last_layer - tpl->u.tex.first_layer + 1;
137bf215546Sopenharmony_ci      break;
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci   default:
140bf215546Sopenharmony_ci      unreachable("Unhandled DSV dimension");
141bf215546Sopenharmony_ci   }
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ci   mtx_lock(&screen->descriptor_pool_mutex);
144bf215546Sopenharmony_ci   d3d12_descriptor_pool_alloc_handle(screen->dsv_pool, handle);
145bf215546Sopenharmony_ci   mtx_unlock(&screen->descriptor_pool_mutex);
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci   screen->dev->CreateDepthStencilView(d3d12_resource_resource(res), &desc,
148bf215546Sopenharmony_ci                                       handle->cpu_handle);
149bf215546Sopenharmony_ci}
150bf215546Sopenharmony_ci
151bf215546Sopenharmony_cistatic void
152bf215546Sopenharmony_ciinitialize_rtv(struct pipe_context *pctx,
153bf215546Sopenharmony_ci               struct pipe_resource *pres,
154bf215546Sopenharmony_ci               const struct pipe_surface *tpl,
155bf215546Sopenharmony_ci               struct d3d12_descriptor_handle *handle,
156bf215546Sopenharmony_ci               DXGI_FORMAT dxgi_format)
157bf215546Sopenharmony_ci{
158bf215546Sopenharmony_ci   struct d3d12_resource *res = d3d12_resource(pres);
159bf215546Sopenharmony_ci   struct d3d12_screen *screen = d3d12_screen(pctx->screen);
160bf215546Sopenharmony_ci
161bf215546Sopenharmony_ci   D3D12_RENDER_TARGET_VIEW_DESC desc;
162bf215546Sopenharmony_ci   desc.Format = dxgi_format;
163bf215546Sopenharmony_ci
164bf215546Sopenharmony_ci   desc.ViewDimension = view_rtv_dimension(pres->target, pres->nr_samples);
165bf215546Sopenharmony_ci   switch (desc.ViewDimension) {
166bf215546Sopenharmony_ci   case D3D12_RTV_DIMENSION_BUFFER:
167bf215546Sopenharmony_ci      desc.Buffer.FirstElement = 0;
168bf215546Sopenharmony_ci      desc.Buffer.NumElements = pres->width0 / util_format_get_blocksize(tpl->format);
169bf215546Sopenharmony_ci      break;
170bf215546Sopenharmony_ci
171bf215546Sopenharmony_ci   case D3D12_RTV_DIMENSION_TEXTURE1D:
172bf215546Sopenharmony_ci      if (tpl->u.tex.first_layer > 0)
173bf215546Sopenharmony_ci         debug_printf("D3D12: can't create 1D RTV from layer %d\n",
174bf215546Sopenharmony_ci                      tpl->u.tex.first_layer);
175bf215546Sopenharmony_ci
176bf215546Sopenharmony_ci      desc.Texture1D.MipSlice = tpl->u.tex.level;
177bf215546Sopenharmony_ci      break;
178bf215546Sopenharmony_ci
179bf215546Sopenharmony_ci   case D3D12_RTV_DIMENSION_TEXTURE1DARRAY:
180bf215546Sopenharmony_ci      desc.Texture1DArray.MipSlice = tpl->u.tex.level;
181bf215546Sopenharmony_ci      desc.Texture1DArray.FirstArraySlice = tpl->u.tex.first_layer;
182bf215546Sopenharmony_ci      desc.Texture1DArray.ArraySize = tpl->u.tex.last_layer - tpl->u.tex.first_layer + 1;
183bf215546Sopenharmony_ci      break;
184bf215546Sopenharmony_ci
185bf215546Sopenharmony_ci   case D3D12_RTV_DIMENSION_TEXTURE2DMS:
186bf215546Sopenharmony_ci      if (tpl->u.tex.first_layer > 0)
187bf215546Sopenharmony_ci         debug_printf("D3D12: can't create 2DMS RTV from layer %d\n",
188bf215546Sopenharmony_ci                      tpl->u.tex.first_layer);
189bf215546Sopenharmony_ci      break;
190bf215546Sopenharmony_ci
191bf215546Sopenharmony_ci   case D3D12_RTV_DIMENSION_TEXTURE2D:
192bf215546Sopenharmony_ci      if (tpl->u.tex.first_layer > 0)
193bf215546Sopenharmony_ci         debug_printf("D3D12: can't create 2D RTV from layer %d\n",
194bf215546Sopenharmony_ci                      tpl->u.tex.first_layer);
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_ci      desc.Texture2D.MipSlice = tpl->u.tex.level;
197bf215546Sopenharmony_ci      desc.Texture2D.PlaneSlice = res->plane_slice;
198bf215546Sopenharmony_ci      break;
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_ci   case D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY:
201bf215546Sopenharmony_ci      desc.Texture2DMSArray.FirstArraySlice = tpl->u.tex.first_layer;
202bf215546Sopenharmony_ci      desc.Texture2DMSArray.ArraySize = tpl->u.tex.last_layer - tpl->u.tex.first_layer + 1;
203bf215546Sopenharmony_ci      break;
204bf215546Sopenharmony_ci
205bf215546Sopenharmony_ci   case D3D12_RTV_DIMENSION_TEXTURE2DARRAY:
206bf215546Sopenharmony_ci      desc.Texture2DArray.MipSlice = tpl->u.tex.level;
207bf215546Sopenharmony_ci      desc.Texture2DArray.FirstArraySlice = tpl->u.tex.first_layer;
208bf215546Sopenharmony_ci      desc.Texture2DArray.ArraySize = tpl->u.tex.last_layer - tpl->u.tex.first_layer + 1;
209bf215546Sopenharmony_ci      desc.Texture2DArray.PlaneSlice = 0;
210bf215546Sopenharmony_ci      break;
211bf215546Sopenharmony_ci
212bf215546Sopenharmony_ci   case D3D12_RTV_DIMENSION_TEXTURE3D:
213bf215546Sopenharmony_ci      desc.Texture3D.MipSlice = tpl->u.tex.level;
214bf215546Sopenharmony_ci      desc.Texture3D.FirstWSlice = tpl->u.tex.first_layer;
215bf215546Sopenharmony_ci      desc.Texture3D.WSize = tpl->u.tex.last_layer - tpl->u.tex.first_layer + 1;
216bf215546Sopenharmony_ci      break;
217bf215546Sopenharmony_ci
218bf215546Sopenharmony_ci   default:
219bf215546Sopenharmony_ci      unreachable("Unhandled RTV dimension");
220bf215546Sopenharmony_ci   }
221bf215546Sopenharmony_ci
222bf215546Sopenharmony_ci   mtx_lock(&screen->descriptor_pool_mutex);
223bf215546Sopenharmony_ci   d3d12_descriptor_pool_alloc_handle(screen->rtv_pool, handle);
224bf215546Sopenharmony_ci   mtx_unlock(&screen->descriptor_pool_mutex);
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci   screen->dev->CreateRenderTargetView(d3d12_resource_resource(res), &desc,
227bf215546Sopenharmony_ci                                       handle->cpu_handle);
228bf215546Sopenharmony_ci}
229bf215546Sopenharmony_ci
230bf215546Sopenharmony_cistatic struct pipe_surface *
231bf215546Sopenharmony_cid3d12_create_surface(struct pipe_context *pctx,
232bf215546Sopenharmony_ci                     struct pipe_resource *pres,
233bf215546Sopenharmony_ci                     const struct pipe_surface *tpl)
234bf215546Sopenharmony_ci{
235bf215546Sopenharmony_ci   bool is_depth_or_stencil = util_format_is_depth_or_stencil(tpl->format);
236bf215546Sopenharmony_ci   unsigned bind = is_depth_or_stencil ? PIPE_BIND_DEPTH_STENCIL : PIPE_BIND_RENDER_TARGET;
237bf215546Sopenharmony_ci
238bf215546Sopenharmony_ci   /* Don't bother if we don't support the requested format as RT or DS */
239bf215546Sopenharmony_ci   if (!pctx->screen->is_format_supported(pctx->screen, tpl->format, PIPE_TEXTURE_2D,
240bf215546Sopenharmony_ci                                          tpl->nr_samples, tpl->nr_samples,bind))
241bf215546Sopenharmony_ci      return NULL;
242bf215546Sopenharmony_ci
243bf215546Sopenharmony_ci   struct d3d12_surface *surface = CALLOC_STRUCT(d3d12_surface);
244bf215546Sopenharmony_ci   if (!surface)
245bf215546Sopenharmony_ci      return NULL;
246bf215546Sopenharmony_ci
247bf215546Sopenharmony_ci   pipe_resource_reference(&surface->base.texture, pres);
248bf215546Sopenharmony_ci   pipe_reference_init(&surface->base.reference, 1);
249bf215546Sopenharmony_ci   surface->base.context = pctx;
250bf215546Sopenharmony_ci   surface->base.format = tpl->format;
251bf215546Sopenharmony_ci   surface->base.width = u_minify(pres->width0, tpl->u.tex.level);
252bf215546Sopenharmony_ci   surface->base.height = u_minify(pres->height0, tpl->u.tex.level);
253bf215546Sopenharmony_ci   surface->base.u.tex.level = tpl->u.tex.level;
254bf215546Sopenharmony_ci   surface->base.u.tex.first_layer = tpl->u.tex.first_layer;
255bf215546Sopenharmony_ci   surface->base.u.tex.last_layer = tpl->u.tex.last_layer;
256bf215546Sopenharmony_ci
257bf215546Sopenharmony_ci   DXGI_FORMAT dxgi_format = d3d12_get_resource_rt_format(tpl->format);
258bf215546Sopenharmony_ci   if (is_depth_or_stencil)
259bf215546Sopenharmony_ci      initialize_dsv(pctx, pres, tpl, &surface->desc_handle, dxgi_format);
260bf215546Sopenharmony_ci   else
261bf215546Sopenharmony_ci      initialize_rtv(pctx, pres, tpl, &surface->desc_handle, dxgi_format);
262bf215546Sopenharmony_ci
263bf215546Sopenharmony_ci   return &surface->base;
264bf215546Sopenharmony_ci}
265bf215546Sopenharmony_ci
266bf215546Sopenharmony_cistatic void
267bf215546Sopenharmony_cid3d12_surface_destroy(struct pipe_context *pctx,
268bf215546Sopenharmony_ci                      struct pipe_surface *psurf)
269bf215546Sopenharmony_ci{
270bf215546Sopenharmony_ci   struct d3d12_surface *surface = (struct d3d12_surface*) psurf;
271bf215546Sopenharmony_ci   struct d3d12_screen *screen = d3d12_screen(pctx->screen);
272bf215546Sopenharmony_ci
273bf215546Sopenharmony_ci   mtx_lock(&screen->descriptor_pool_mutex);
274bf215546Sopenharmony_ci   d3d12_descriptor_handle_free(&surface->desc_handle);
275bf215546Sopenharmony_ci   if (d3d12_descriptor_handle_is_allocated(&surface->uint_rtv_handle))
276bf215546Sopenharmony_ci      d3d12_descriptor_handle_free(&surface->uint_rtv_handle);
277bf215546Sopenharmony_ci   mtx_unlock(&screen->descriptor_pool_mutex);
278bf215546Sopenharmony_ci
279bf215546Sopenharmony_ci   pipe_resource_reference(&psurf->texture, NULL);
280bf215546Sopenharmony_ci   pipe_resource_reference(&surface->rgba_texture, NULL);
281bf215546Sopenharmony_ci   FREE(surface);
282bf215546Sopenharmony_ci}
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_cistatic void
285bf215546Sopenharmony_ciblit_surface(struct pipe_context *pctx, struct d3d12_surface *surface, bool pre)
286bf215546Sopenharmony_ci{
287bf215546Sopenharmony_ci   struct pipe_blit_info info = {};
288bf215546Sopenharmony_ci
289bf215546Sopenharmony_ci   info.src.resource = pre ? surface->base.texture : surface->rgba_texture;
290bf215546Sopenharmony_ci   info.dst.resource = pre ? surface->rgba_texture : surface->base.texture;
291bf215546Sopenharmony_ci   info.src.format = pre ? surface->base.texture->format : PIPE_FORMAT_R8G8B8A8_UNORM;
292bf215546Sopenharmony_ci   info.dst.format = pre ? PIPE_FORMAT_R8G8B8A8_UNORM : surface->base.texture->format;
293bf215546Sopenharmony_ci   info.src.level = info.dst.level = 0;
294bf215546Sopenharmony_ci   info.src.box.x = info.dst.box.x = 0;
295bf215546Sopenharmony_ci   info.src.box.y = info.dst.box.y = 0;
296bf215546Sopenharmony_ci   info.src.box.z = info.dst.box.z = 0;
297bf215546Sopenharmony_ci   info.src.box.width = info.dst.box.width = surface->base.width;
298bf215546Sopenharmony_ci   info.src.box.height = info.dst.box.height = surface->base.height;
299bf215546Sopenharmony_ci   info.src.box.depth = info.dst.box.depth = 0;
300bf215546Sopenharmony_ci   info.mask = PIPE_MASK_RGBA;
301bf215546Sopenharmony_ci
302bf215546Sopenharmony_ci   d3d12_blit(pctx, &info);
303bf215546Sopenharmony_ci}
304bf215546Sopenharmony_ci
305bf215546Sopenharmony_cienum d3d12_surface_conversion_mode
306bf215546Sopenharmony_cid3d12_surface_update_pre_draw(struct pipe_context *pctx,
307bf215546Sopenharmony_ci                              struct d3d12_surface *surface,
308bf215546Sopenharmony_ci                              DXGI_FORMAT format)
309bf215546Sopenharmony_ci{
310bf215546Sopenharmony_ci   struct d3d12_screen *screen = d3d12_screen(surface->base.context->screen);
311bf215546Sopenharmony_ci   struct d3d12_resource *res = d3d12_resource(surface->base.texture);
312bf215546Sopenharmony_ci   DXGI_FORMAT dxgi_format = d3d12_get_resource_rt_format(surface->base.format);
313bf215546Sopenharmony_ci   enum d3d12_surface_conversion_mode mode;
314bf215546Sopenharmony_ci
315bf215546Sopenharmony_ci   if (dxgi_format == format)
316bf215546Sopenharmony_ci      return D3D12_SURFACE_CONVERSION_NONE;
317bf215546Sopenharmony_ci
318bf215546Sopenharmony_ci   if (dxgi_format == DXGI_FORMAT_B8G8R8A8_UNORM ||
319bf215546Sopenharmony_ci       dxgi_format == DXGI_FORMAT_B8G8R8X8_UNORM)
320bf215546Sopenharmony_ci      mode = D3D12_SURFACE_CONVERSION_BGRA_UINT;
321bf215546Sopenharmony_ci   else
322bf215546Sopenharmony_ci      mode = D3D12_SURFACE_CONVERSION_RGBA_UINT;
323bf215546Sopenharmony_ci
324bf215546Sopenharmony_ci   if (mode == D3D12_SURFACE_CONVERSION_BGRA_UINT) {
325bf215546Sopenharmony_ci      if (!surface->rgba_texture) {
326bf215546Sopenharmony_ci         struct pipe_resource templ = {};
327bf215546Sopenharmony_ci         struct pipe_resource *src = surface->base.texture;
328bf215546Sopenharmony_ci
329bf215546Sopenharmony_ci         templ.format = PIPE_FORMAT_R8G8B8A8_UNORM;
330bf215546Sopenharmony_ci         templ.width0 = src->width0;
331bf215546Sopenharmony_ci         templ.height0 = src->height0;
332bf215546Sopenharmony_ci         templ.depth0 = src->depth0;
333bf215546Sopenharmony_ci         templ.array_size = src->array_size;
334bf215546Sopenharmony_ci         templ.nr_samples = src->nr_samples;
335bf215546Sopenharmony_ci         templ.nr_storage_samples = src->nr_storage_samples;
336bf215546Sopenharmony_ci         templ.usage = PIPE_USAGE_DEFAULT | PIPE_USAGE_STAGING;
337bf215546Sopenharmony_ci         templ.bind = src->bind;
338bf215546Sopenharmony_ci         templ.target = src->target;
339bf215546Sopenharmony_ci
340bf215546Sopenharmony_ci         surface->rgba_texture = screen->base.resource_create(&screen->base, &templ);
341bf215546Sopenharmony_ci      }
342bf215546Sopenharmony_ci
343bf215546Sopenharmony_ci      blit_surface(pctx, surface, true);
344bf215546Sopenharmony_ci      res = d3d12_resource(surface->rgba_texture);
345bf215546Sopenharmony_ci   }
346bf215546Sopenharmony_ci
347bf215546Sopenharmony_ci   if (!d3d12_descriptor_handle_is_allocated(&surface->uint_rtv_handle)) {
348bf215546Sopenharmony_ci      initialize_rtv(surface->base.context, &res->base.b, &surface->base,
349bf215546Sopenharmony_ci                     &surface->uint_rtv_handle, DXGI_FORMAT_R8G8B8A8_UINT);
350bf215546Sopenharmony_ci   }
351bf215546Sopenharmony_ci
352bf215546Sopenharmony_ci   return mode;
353bf215546Sopenharmony_ci}
354bf215546Sopenharmony_ci
355bf215546Sopenharmony_civoid
356bf215546Sopenharmony_cid3d12_surface_update_post_draw(struct pipe_context *pctx,
357bf215546Sopenharmony_ci                               struct d3d12_surface *surface,
358bf215546Sopenharmony_ci                               enum d3d12_surface_conversion_mode mode)
359bf215546Sopenharmony_ci{
360bf215546Sopenharmony_ci   if (mode == D3D12_SURFACE_CONVERSION_BGRA_UINT)
361bf215546Sopenharmony_ci      blit_surface(pctx, surface, false);
362bf215546Sopenharmony_ci}
363bf215546Sopenharmony_ci
364bf215546Sopenharmony_ciD3D12_CPU_DESCRIPTOR_HANDLE
365bf215546Sopenharmony_cid3d12_surface_get_handle(struct d3d12_surface *surface,
366bf215546Sopenharmony_ci                         enum d3d12_surface_conversion_mode mode)
367bf215546Sopenharmony_ci{
368bf215546Sopenharmony_ci   if (mode != D3D12_SURFACE_CONVERSION_NONE)
369bf215546Sopenharmony_ci      return surface->uint_rtv_handle.cpu_handle;
370bf215546Sopenharmony_ci   return surface->desc_handle.cpu_handle;
371bf215546Sopenharmony_ci}
372bf215546Sopenharmony_ci
373bf215546Sopenharmony_civoid
374bf215546Sopenharmony_cid3d12_context_surface_init(struct pipe_context *context)
375bf215546Sopenharmony_ci{
376bf215546Sopenharmony_ci   context->create_surface = d3d12_create_surface;
377bf215546Sopenharmony_ci   context->surface_destroy = d3d12_surface_destroy;
378bf215546Sopenharmony_ci}
379