1 /*
2 * Copyright (c) 2008-2024 Broadcom. All Rights Reserved.
3 * The term “Broadcom” refers to Broadcom Inc.
4 * and/or its subsidiaries.
5 * SPDX-License-Identifier: MIT
6 */
7
8 #include <inttypes.h>
9 #include "util/u_debug.h"
10
11 #include "svga_resource.h"
12 #include "svga_resource_buffer.h"
13 #include "svga_resource_texture.h"
14 #include "svga_context.h"
15 #include "svga_screen.h"
16 #include "svga_format.h"
17
18
19 /**
20 * This is the primary driver entrypoint for allocating graphics memory
21 * (vertex/index/constant buffers, textures, etc)
22 */
23 static struct pipe_resource *
svga_resource_create(struct pipe_screen * screen,const struct pipe_resource * template)24 svga_resource_create(struct pipe_screen *screen,
25 const struct pipe_resource *template)
26 {
27 struct pipe_resource *r;
28
29 if (template->target == PIPE_BUFFER)
30 r = svga_buffer_create(screen, template);
31 else
32 r = svga_texture_create(screen, template);
33
34 if (!r) {
35 struct svga_screen *svgascreen = svga_screen(screen);
36 svgascreen->hud.num_failed_allocations++;
37 }
38
39 return r;
40 }
41
42
43 static struct pipe_resource *
svga_resource_from_handle(struct pipe_screen * screen,const struct pipe_resource * template,struct winsys_handle * whandle,unsigned usage)44 svga_resource_from_handle(struct pipe_screen * screen,
45 const struct pipe_resource *template,
46 struct winsys_handle *whandle,
47 unsigned usage)
48 {
49 if (template->target == PIPE_BUFFER)
50 return NULL;
51 else
52 return svga_texture_from_handle(screen, template, whandle);
53 }
54
55
56 static struct pipe_resource *
svga_resource_create_with_modifiers(struct pipe_screen * screen,const struct pipe_resource * templat,const uint64_t * modifiers,int count)57 svga_resource_create_with_modifiers(struct pipe_screen *screen,
58 const struct pipe_resource *templat,
59 const uint64_t *modifiers, int count)
60 {
61 /* Not sure, but it seems there's no format modifiers
62 * to deal with here.
63 */
64 if (count > 0 && modifiers != NULL && modifiers[0] != 0) {
65 debug_printf("vmware: unexpected format modifier 0x%" PRIx64 "\n",
66 modifiers[0]);
67 }
68 return svga_resource_create(screen, templat);
69 }
70
71
72 /**
73 * Check if a resource (texture, buffer) of the given size
74 * and format can be created.
75 * \Return TRUE if OK, FALSE if too large.
76 */
77 static bool
svga_can_create_resource(struct pipe_screen * screen,const struct pipe_resource * res)78 svga_can_create_resource(struct pipe_screen *screen,
79 const struct pipe_resource *res)
80 {
81 struct svga_screen *svgascreen = svga_screen(screen);
82 struct svga_winsys_screen *sws = svgascreen->sws;
83 SVGA3dSurfaceFormat format;
84 SVGA3dSize base_level_size;
85 uint32 numMipLevels;
86 uint32 arraySize;
87 uint32 numSamples;
88
89 if (res->target == PIPE_BUFFER) {
90 format = SVGA3D_BUFFER;
91 base_level_size.width = res->width0;
92 base_level_size.height = 1;
93 base_level_size.depth = 1;
94 numMipLevels = 1;
95 arraySize = 1;
96 numSamples = 0;
97
98 } else {
99 if (res->target == PIPE_TEXTURE_CUBE)
100 assert(res->array_size == 6);
101
102 format = svga_translate_format(svgascreen, res->format, res->bind);
103 if (format == SVGA3D_FORMAT_INVALID)
104 return false;
105
106 base_level_size.width = res->width0;
107 base_level_size.height = res->height0;
108 base_level_size.depth = res->depth0;
109 numMipLevels = res->last_level + 1;
110 arraySize = res->array_size;
111 numSamples = res->nr_samples;
112 }
113
114 return sws->surface_can_create(sws, format, base_level_size,
115 arraySize, numMipLevels, numSamples);
116 }
117
118
119 void
svga_init_resource_functions(struct svga_context * svga)120 svga_init_resource_functions(struct svga_context *svga)
121 {
122 svga->pipe.buffer_map = svga_buffer_transfer_map;
123 svga->pipe.texture_map = svga_texture_transfer_map;
124 svga->pipe.transfer_flush_region = svga_buffer_transfer_flush_region;
125 svga->pipe.buffer_unmap = svga_buffer_transfer_unmap;
126 svga->pipe.texture_unmap = svga_texture_transfer_unmap;
127 svga->pipe.buffer_subdata = u_default_buffer_subdata;
128 svga->pipe.texture_subdata = u_default_texture_subdata;
129
130 if (svga_have_vgpu10(svga)) {
131 svga->pipe.generate_mipmap = svga_texture_generate_mipmap;
132 } else {
133 svga->pipe.generate_mipmap = NULL;
134 }
135 }
136
137 void
svga_init_screen_resource_functions(struct svga_screen * is)138 svga_init_screen_resource_functions(struct svga_screen *is)
139 {
140 is->screen.resource_create = svga_resource_create;
141 is->screen.resource_create_with_modifiers = svga_resource_create_with_modifiers;
142 is->screen.resource_from_handle = svga_resource_from_handle;
143 is->screen.resource_get_handle = svga_resource_get_handle;
144 is->screen.resource_destroy = svga_resource_destroy;
145 is->screen.can_create_resource = svga_can_create_resource;
146 }
147