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_video_buffer.h" 25bf215546Sopenharmony_ci#include "d3d12_resource.h" 26bf215546Sopenharmony_ci#include "d3d12_video_dec.h" 27bf215546Sopenharmony_ci#include "d3d12_residency.h" 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "util/format/u_format.h" 30bf215546Sopenharmony_ci#include "util/u_inlines.h" 31bf215546Sopenharmony_ci#include "util/u_memory.h" 32bf215546Sopenharmony_ci#include "util/u_video.h" 33bf215546Sopenharmony_ci#include "vl/vl_video_buffer.h" 34bf215546Sopenharmony_ci#include "util/u_sampler.h" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci/** 37bf215546Sopenharmony_ci * creates a video buffer 38bf215546Sopenharmony_ci */ 39bf215546Sopenharmony_cistruct pipe_video_buffer * 40bf215546Sopenharmony_cid3d12_video_buffer_create(struct pipe_context *pipe, const struct pipe_video_buffer *tmpl) 41bf215546Sopenharmony_ci{ 42bf215546Sopenharmony_ci assert(pipe); 43bf215546Sopenharmony_ci assert(tmpl); 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci /// 46bf215546Sopenharmony_ci /// Initialize d3d12_video_buffer 47bf215546Sopenharmony_ci /// 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci if (!(tmpl->buffer_format == PIPE_FORMAT_NV12)) { 51bf215546Sopenharmony_ci debug_printf("[d3d12_video_buffer] buffer_format is only supported as PIPE_FORMAT_NV12.\n"); 52bf215546Sopenharmony_ci return nullptr; 53bf215546Sopenharmony_ci } 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci if (!(pipe_format_to_chroma_format(tmpl->buffer_format) == PIPE_VIDEO_CHROMA_FORMAT_420)) { 56bf215546Sopenharmony_ci debug_printf( 57bf215546Sopenharmony_ci "[d3d12_video_buffer] tmpl->buffer_format only supported as a PIPE_VIDEO_CHROMA_FORMAT_420 format.\n"); 58bf215546Sopenharmony_ci return nullptr; 59bf215546Sopenharmony_ci } 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci // Not using new doesn't call ctor and the initializations in the class declaration are lost 62bf215546Sopenharmony_ci struct d3d12_video_buffer *pD3D12VideoBuffer = new d3d12_video_buffer; 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci // Fill base template 65bf215546Sopenharmony_ci pD3D12VideoBuffer->base = *tmpl; 66bf215546Sopenharmony_ci pD3D12VideoBuffer->base.buffer_format = tmpl->buffer_format; 67bf215546Sopenharmony_ci pD3D12VideoBuffer->base.context = pipe; 68bf215546Sopenharmony_ci pD3D12VideoBuffer->base.width = tmpl->width; 69bf215546Sopenharmony_ci pD3D12VideoBuffer->base.height = tmpl->height; 70bf215546Sopenharmony_ci pD3D12VideoBuffer->base.interlaced = tmpl->interlaced; 71bf215546Sopenharmony_ci pD3D12VideoBuffer->base.associated_data = nullptr; 72bf215546Sopenharmony_ci pD3D12VideoBuffer->base.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET; 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci // Fill vtable 75bf215546Sopenharmony_ci pD3D12VideoBuffer->base.destroy = d3d12_video_buffer_destroy; 76bf215546Sopenharmony_ci pD3D12VideoBuffer->base.get_sampler_view_planes = d3d12_video_buffer_get_sampler_view_planes; 77bf215546Sopenharmony_ci pD3D12VideoBuffer->base.get_sampler_view_components = d3d12_video_buffer_get_sampler_view_components; 78bf215546Sopenharmony_ci pD3D12VideoBuffer->base.get_surfaces = d3d12_video_buffer_get_surfaces; 79bf215546Sopenharmony_ci pD3D12VideoBuffer->base.destroy_associated_data = d3d12_video_buffer_destroy_associated_data; 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci struct pipe_resource templ; 82bf215546Sopenharmony_ci memset(&templ, 0, sizeof(templ)); 83bf215546Sopenharmony_ci templ.target = PIPE_TEXTURE_2D; 84bf215546Sopenharmony_ci templ.bind = pD3D12VideoBuffer->base.bind; 85bf215546Sopenharmony_ci templ.format = pD3D12VideoBuffer->base.buffer_format; 86bf215546Sopenharmony_ci // YUV 4:2:0 formats in D3D12 need to have multiple of 2 dimensions 87bf215546Sopenharmony_ci templ.width0 = align(pD3D12VideoBuffer->base.width, 2); 88bf215546Sopenharmony_ci templ.height0 = align(pD3D12VideoBuffer->base.height, 2); 89bf215546Sopenharmony_ci templ.depth0 = 1; 90bf215546Sopenharmony_ci templ.array_size = 1; 91bf215546Sopenharmony_ci templ.flags = 0; 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci // This calls d3d12_create_resource as the function ptr is set in d3d12_screen.resource_create 94bf215546Sopenharmony_ci pD3D12VideoBuffer->texture = (struct d3d12_resource *) pipe->screen->resource_create(pipe->screen, &templ); 95bf215546Sopenharmony_ci d3d12_promote_to_permanent_residency((struct d3d12_screen*) pipe->screen, pD3D12VideoBuffer->texture); 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci if (pD3D12VideoBuffer->texture == nullptr) { 98bf215546Sopenharmony_ci debug_printf("[d3d12_video_buffer] d3d12_video_buffer_create - Call to resource_create() to create " 99bf215546Sopenharmony_ci "d3d12_resource failed\n"); 100bf215546Sopenharmony_ci goto failed; 101bf215546Sopenharmony_ci } 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci pD3D12VideoBuffer->num_planes = util_format_get_num_planes(pD3D12VideoBuffer->texture->overall_format); 104bf215546Sopenharmony_ci assert(pD3D12VideoBuffer->num_planes == 2); 105bf215546Sopenharmony_ci return &pD3D12VideoBuffer->base; 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_cifailed: 108bf215546Sopenharmony_ci d3d12_video_buffer_destroy((struct pipe_video_buffer *) pD3D12VideoBuffer); 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci return nullptr; 111bf215546Sopenharmony_ci} 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci/** 114bf215546Sopenharmony_ci * destroy this video buffer 115bf215546Sopenharmony_ci */ 116bf215546Sopenharmony_civoid 117bf215546Sopenharmony_cid3d12_video_buffer_destroy(struct pipe_video_buffer *buffer) 118bf215546Sopenharmony_ci{ 119bf215546Sopenharmony_ci struct d3d12_video_buffer *pD3D12VideoBuffer = (struct d3d12_video_buffer *) buffer; 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci // Destroy pD3D12VideoBuffer->texture (if any) 122bf215546Sopenharmony_ci if (pD3D12VideoBuffer->texture) { 123bf215546Sopenharmony_ci pipe_resource *pBaseResource = &pD3D12VideoBuffer->texture->base.b; 124bf215546Sopenharmony_ci pipe_resource_reference(&pBaseResource, NULL); 125bf215546Sopenharmony_ci } 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci // Destroy associated data (if any) 128bf215546Sopenharmony_ci if (pD3D12VideoBuffer->base.associated_data != nullptr) { 129bf215546Sopenharmony_ci d3d12_video_buffer_destroy_associated_data(pD3D12VideoBuffer->base.associated_data); 130bf215546Sopenharmony_ci // Set to nullptr after cleanup, no dangling pointers 131bf215546Sopenharmony_ci pD3D12VideoBuffer->base.associated_data = nullptr; 132bf215546Sopenharmony_ci } 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci // Destroy (if any) codec where the associated data came from 135bf215546Sopenharmony_ci if (pD3D12VideoBuffer->base.codec != nullptr) { 136bf215546Sopenharmony_ci d3d12_video_decoder_destroy(pD3D12VideoBuffer->base.codec); 137bf215546Sopenharmony_ci // Set to nullptr after cleanup, no dangling pointers 138bf215546Sopenharmony_ci pD3D12VideoBuffer->base.codec = nullptr; 139bf215546Sopenharmony_ci } 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci for (uint i = 0; i < pD3D12VideoBuffer->surfaces.size(); ++i) { 142bf215546Sopenharmony_ci if (pD3D12VideoBuffer->surfaces[i] != NULL) { 143bf215546Sopenharmony_ci pipe_surface_reference(&pD3D12VideoBuffer->surfaces[i], NULL); 144bf215546Sopenharmony_ci } 145bf215546Sopenharmony_ci } 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci for (uint i = 0; i < pD3D12VideoBuffer->sampler_view_planes.size(); ++i) { 148bf215546Sopenharmony_ci if (pD3D12VideoBuffer->sampler_view_planes[i] != NULL) { 149bf215546Sopenharmony_ci pipe_sampler_view_reference(&pD3D12VideoBuffer->sampler_view_planes[i], NULL); 150bf215546Sopenharmony_ci } 151bf215546Sopenharmony_ci } 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci for (uint i = 0; i < pD3D12VideoBuffer->sampler_view_components.size(); ++i) { 154bf215546Sopenharmony_ci if (pD3D12VideoBuffer->sampler_view_components[i] != NULL) { 155bf215546Sopenharmony_ci pipe_sampler_view_reference(&pD3D12VideoBuffer->sampler_view_components[i], NULL); 156bf215546Sopenharmony_ci } 157bf215546Sopenharmony_ci } 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci delete pD3D12VideoBuffer; 160bf215546Sopenharmony_ci} 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci/* 163bf215546Sopenharmony_ci * destroy the associated data 164bf215546Sopenharmony_ci */ 165bf215546Sopenharmony_civoid 166bf215546Sopenharmony_cid3d12_video_buffer_destroy_associated_data(void *associated_data) 167bf215546Sopenharmony_ci{ } 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci/** 170bf215546Sopenharmony_ci * get an individual surfaces for each plane 171bf215546Sopenharmony_ci */ 172bf215546Sopenharmony_cistruct pipe_surface ** 173bf215546Sopenharmony_cid3d12_video_buffer_get_surfaces(struct pipe_video_buffer *buffer) 174bf215546Sopenharmony_ci{ 175bf215546Sopenharmony_ci assert(buffer); 176bf215546Sopenharmony_ci struct d3d12_video_buffer *pD3D12VideoBuffer = (struct d3d12_video_buffer *) buffer; 177bf215546Sopenharmony_ci struct pipe_context * pipe = pD3D12VideoBuffer->base.context; 178bf215546Sopenharmony_ci struct pipe_surface surface_template = {}; 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci // Some video frameworks iterate over [0..VL_MAX_SURFACES) and ignore the nullptr entries 181bf215546Sopenharmony_ci // So we have to null initialize the other surfaces not used from [num_planes..VL_MAX_SURFACES) 182bf215546Sopenharmony_ci // Like in src/gallium/frontends/va/surface.c 183bf215546Sopenharmony_ci pD3D12VideoBuffer->surfaces.resize(VL_MAX_SURFACES, nullptr); 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci // pCurPlaneResource refers to the planar resource, not the overall resource. 186bf215546Sopenharmony_ci // in d3d12_resource this is handled by having a linked list of planes with 187bf215546Sopenharmony_ci // d3dRes->base.next ptr to next plane resource 188bf215546Sopenharmony_ci // starting with the plane 0 being the overall resource 189bf215546Sopenharmony_ci struct pipe_resource *pCurPlaneResource = &pD3D12VideoBuffer->texture->base.b; 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci for (uint PlaneSlice = 0; PlaneSlice < pD3D12VideoBuffer->num_planes; ++PlaneSlice) { 192bf215546Sopenharmony_ci if (!pD3D12VideoBuffer->surfaces[PlaneSlice]) { 193bf215546Sopenharmony_ci memset(&surface_template, 0, sizeof(surface_template)); 194bf215546Sopenharmony_ci surface_template.format = 195bf215546Sopenharmony_ci util_format_get_plane_format(pD3D12VideoBuffer->texture->overall_format, PlaneSlice); 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci pD3D12VideoBuffer->surfaces[PlaneSlice] = 198bf215546Sopenharmony_ci pipe->create_surface(pipe, pCurPlaneResource, &surface_template); 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci if (!pD3D12VideoBuffer->surfaces[PlaneSlice]) { 201bf215546Sopenharmony_ci goto error; 202bf215546Sopenharmony_ci } 203bf215546Sopenharmony_ci } 204bf215546Sopenharmony_ci pCurPlaneResource = pCurPlaneResource->next; 205bf215546Sopenharmony_ci } 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci return pD3D12VideoBuffer->surfaces.data(); 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_cierror: 210bf215546Sopenharmony_ci for (uint PlaneSlice = 0; PlaneSlice < pD3D12VideoBuffer->num_planes; ++PlaneSlice) { 211bf215546Sopenharmony_ci pipe_surface_reference(&pD3D12VideoBuffer->surfaces[PlaneSlice], NULL); 212bf215546Sopenharmony_ci } 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci return nullptr; 215bf215546Sopenharmony_ci} 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci/** 218bf215546Sopenharmony_ci * get an individual sampler view for each plane 219bf215546Sopenharmony_ci */ 220bf215546Sopenharmony_cistruct pipe_sampler_view ** 221bf215546Sopenharmony_cid3d12_video_buffer_get_sampler_view_planes(struct pipe_video_buffer *buffer) 222bf215546Sopenharmony_ci{ 223bf215546Sopenharmony_ci assert(buffer); 224bf215546Sopenharmony_ci struct d3d12_video_buffer *pD3D12VideoBuffer = (struct d3d12_video_buffer *) buffer; 225bf215546Sopenharmony_ci struct pipe_context * pipe = pD3D12VideoBuffer->base.context; 226bf215546Sopenharmony_ci struct pipe_sampler_view samplerViewTemplate; 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci // Some video frameworks iterate over [0..VL_MAX_SURFACES) and ignore the nullptr entries 229bf215546Sopenharmony_ci // So we have to null initialize the other surfaces not used from [num_planes..VL_MAX_SURFACES) 230bf215546Sopenharmony_ci // Like in src/gallium/frontends/vdpau/surface.c 231bf215546Sopenharmony_ci pD3D12VideoBuffer->sampler_view_planes.resize(VL_MAX_SURFACES, nullptr); 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci // pCurPlaneResource refers to the planar resource, not the overall resource. 234bf215546Sopenharmony_ci // in d3d12_resource this is handled by having a linked list of planes with 235bf215546Sopenharmony_ci // d3dRes->base.next ptr to next plane resource 236bf215546Sopenharmony_ci // starting with the plane 0 being the overall resource 237bf215546Sopenharmony_ci struct pipe_resource *pCurPlaneResource = &pD3D12VideoBuffer->texture->base.b; 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci for (uint i = 0; i < pD3D12VideoBuffer->num_planes; ++i) { 240bf215546Sopenharmony_ci if (!pD3D12VideoBuffer->sampler_view_planes[i]) { 241bf215546Sopenharmony_ci assert(pCurPlaneResource); // the d3d12_resource has a linked list with the exact name of number of elements 242bf215546Sopenharmony_ci // as planes 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci memset(&samplerViewTemplate, 0, sizeof(samplerViewTemplate)); 245bf215546Sopenharmony_ci u_sampler_view_default_template(&samplerViewTemplate, pCurPlaneResource, pCurPlaneResource->format); 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci pD3D12VideoBuffer->sampler_view_planes[i] = 248bf215546Sopenharmony_ci pipe->create_sampler_view(pipe, pCurPlaneResource, &samplerViewTemplate); 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci if (!pD3D12VideoBuffer->sampler_view_planes[i]) { 251bf215546Sopenharmony_ci goto error; 252bf215546Sopenharmony_ci } 253bf215546Sopenharmony_ci } 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci pCurPlaneResource = pCurPlaneResource->next; 256bf215546Sopenharmony_ci } 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci return pD3D12VideoBuffer->sampler_view_planes.data(); 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_cierror: 261bf215546Sopenharmony_ci for (uint i = 0; i < pD3D12VideoBuffer->num_planes; ++i) { 262bf215546Sopenharmony_ci pipe_sampler_view_reference(&pD3D12VideoBuffer->sampler_view_planes[i], NULL); 263bf215546Sopenharmony_ci } 264bf215546Sopenharmony_ci 265bf215546Sopenharmony_ci return nullptr; 266bf215546Sopenharmony_ci} 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci/** 269bf215546Sopenharmony_ci * get an individual sampler view for each component 270bf215546Sopenharmony_ci */ 271bf215546Sopenharmony_cistruct pipe_sampler_view ** 272bf215546Sopenharmony_cid3d12_video_buffer_get_sampler_view_components(struct pipe_video_buffer *buffer) 273bf215546Sopenharmony_ci{ 274bf215546Sopenharmony_ci assert(buffer); 275bf215546Sopenharmony_ci struct d3d12_video_buffer *pD3D12VideoBuffer = (struct d3d12_video_buffer *) buffer; 276bf215546Sopenharmony_ci struct pipe_context * pipe = pD3D12VideoBuffer->base.context; 277bf215546Sopenharmony_ci struct pipe_sampler_view samplerViewTemplate; 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci // pCurPlaneResource refers to the planar resource, not the overall resource. 280bf215546Sopenharmony_ci // in d3d12_resource this is handled by having a linked list of planes with 281bf215546Sopenharmony_ci // d3dRes->base.next ptr to next plane resource 282bf215546Sopenharmony_ci // starting with the plane 0 being the overall resource 283bf215546Sopenharmony_ci struct pipe_resource *pCurPlaneResource = &pD3D12VideoBuffer->texture->base.b; 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ci // At the end of the loop, "component" will have the total number of items valid in sampler_view_components 286bf215546Sopenharmony_ci // since component can end up being <= VL_NUM_COMPONENTS, we assume VL_NUM_COMPONENTS first and then resize/adjust to 287bf215546Sopenharmony_ci // fit the container size pD3D12VideoBuffer->sampler_view_components to the actual components number 288bf215546Sopenharmony_ci pD3D12VideoBuffer->sampler_view_components.resize(VL_NUM_COMPONENTS, nullptr); 289bf215546Sopenharmony_ci uint component = 0; 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci for (uint i = 0; i < pD3D12VideoBuffer->num_planes; ++i) { 292bf215546Sopenharmony_ci // For example num_components would be 1 for the Y plane (R8 in NV12), 2 for the UV plane (R8G8 in NV12) 293bf215546Sopenharmony_ci unsigned num_components = util_format_get_nr_components(pCurPlaneResource->format); 294bf215546Sopenharmony_ci 295bf215546Sopenharmony_ci for (uint j = 0; j < num_components; ++j, ++component) { 296bf215546Sopenharmony_ci assert(component < VL_NUM_COMPONENTS); 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci if (!pD3D12VideoBuffer->sampler_view_components[component]) { 299bf215546Sopenharmony_ci memset(&samplerViewTemplate, 0, sizeof(samplerViewTemplate)); 300bf215546Sopenharmony_ci u_sampler_view_default_template(&samplerViewTemplate, pCurPlaneResource, pCurPlaneResource->format); 301bf215546Sopenharmony_ci samplerViewTemplate.swizzle_r = samplerViewTemplate.swizzle_g = samplerViewTemplate.swizzle_b = 302bf215546Sopenharmony_ci PIPE_SWIZZLE_X + j; 303bf215546Sopenharmony_ci samplerViewTemplate.swizzle_a = PIPE_SWIZZLE_1; 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci pD3D12VideoBuffer->sampler_view_components[component] = 306bf215546Sopenharmony_ci pipe->create_sampler_view(pipe, pCurPlaneResource, &samplerViewTemplate); 307bf215546Sopenharmony_ci if (!pD3D12VideoBuffer->sampler_view_components[component]) { 308bf215546Sopenharmony_ci goto error; 309bf215546Sopenharmony_ci } 310bf215546Sopenharmony_ci } 311bf215546Sopenharmony_ci } 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci pCurPlaneResource = pCurPlaneResource->next; 314bf215546Sopenharmony_ci } 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_ci // Adjust size to fit component <= VL_NUM_COMPONENTS 317bf215546Sopenharmony_ci pD3D12VideoBuffer->sampler_view_components.resize(component); 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci return pD3D12VideoBuffer->sampler_view_components.data(); 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_cierror: 322bf215546Sopenharmony_ci for (uint i = 0; i < pD3D12VideoBuffer->num_planes; ++i) { 323bf215546Sopenharmony_ci pipe_sampler_view_reference(&pD3D12VideoBuffer->sampler_view_components[i], NULL); 324bf215546Sopenharmony_ci } 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci return nullptr; 327bf215546Sopenharmony_ci} 328