1bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h" 2bf215546Sopenharmony_ci 3bf215546Sopenharmony_ci#include "pipe/p_context.h" 4bf215546Sopenharmony_ci#include "nvc0/nvc0_resource.h" 5bf215546Sopenharmony_ci#include "nouveau_screen.h" 6bf215546Sopenharmony_ci 7bf215546Sopenharmony_ci 8bf215546Sopenharmony_cistatic struct pipe_resource * 9bf215546Sopenharmony_cinvc0_resource_create(struct pipe_screen *screen, 10bf215546Sopenharmony_ci const struct pipe_resource *templ) 11bf215546Sopenharmony_ci{ 12bf215546Sopenharmony_ci switch (templ->target) { 13bf215546Sopenharmony_ci case PIPE_BUFFER: 14bf215546Sopenharmony_ci return nouveau_buffer_create(screen, templ); 15bf215546Sopenharmony_ci default: 16bf215546Sopenharmony_ci return nvc0_miptree_create(screen, templ, NULL, 0); 17bf215546Sopenharmony_ci } 18bf215546Sopenharmony_ci} 19bf215546Sopenharmony_ci 20bf215546Sopenharmony_cistatic struct pipe_resource * 21bf215546Sopenharmony_cinvc0_resource_create_with_modifiers(struct pipe_screen *screen, 22bf215546Sopenharmony_ci const struct pipe_resource *templ, 23bf215546Sopenharmony_ci const uint64_t *modifiers, int count) 24bf215546Sopenharmony_ci{ 25bf215546Sopenharmony_ci switch (templ->target) { 26bf215546Sopenharmony_ci case PIPE_BUFFER: 27bf215546Sopenharmony_ci return nouveau_buffer_create(screen, templ); 28bf215546Sopenharmony_ci default: 29bf215546Sopenharmony_ci return nvc0_miptree_create(screen, templ, modifiers, count); 30bf215546Sopenharmony_ci } 31bf215546Sopenharmony_ci} 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_cistatic void 34bf215546Sopenharmony_cinvc0_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *res) 35bf215546Sopenharmony_ci{ 36bf215546Sopenharmony_ci if (res->target == PIPE_BUFFER) 37bf215546Sopenharmony_ci nouveau_buffer_destroy(pscreen, res); 38bf215546Sopenharmony_ci else 39bf215546Sopenharmony_ci nv50_miptree_destroy(pscreen, res); 40bf215546Sopenharmony_ci} 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_cistatic void 43bf215546Sopenharmony_cinvc0_query_dmabuf_modifiers(struct pipe_screen *screen, 44bf215546Sopenharmony_ci enum pipe_format format, int max, 45bf215546Sopenharmony_ci uint64_t *modifiers, unsigned int *external_only, 46bf215546Sopenharmony_ci int *count) 47bf215546Sopenharmony_ci{ 48bf215546Sopenharmony_ci const int s = nouveau_screen(screen)->tegra_sector_layout ? 0 : 1; 49bf215546Sopenharmony_ci const uint32_t uc_kind = 50bf215546Sopenharmony_ci nvc0_choose_tiled_storage_type(screen, format, 0, false); 51bf215546Sopenharmony_ci const uint32_t num_uc = uc_kind ? 6 : 0; /* max block height = 32 GOBs */ 52bf215546Sopenharmony_ci const int num_supported = num_uc + 1; /* LINEAR is always supported */ 53bf215546Sopenharmony_ci const uint32_t kind_gen = nvc0_get_kind_generation(screen); 54bf215546Sopenharmony_ci int i, num = 0; 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci if (max > num_supported) 57bf215546Sopenharmony_ci max = num_supported; 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci if (!max) { 60bf215546Sopenharmony_ci max = num_supported; 61bf215546Sopenharmony_ci external_only = NULL; 62bf215546Sopenharmony_ci modifiers = NULL; 63bf215546Sopenharmony_ci } 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci#define NVC0_ADD_MOD(m) do { \ 66bf215546Sopenharmony_ci if (modifiers) modifiers[num] = m; \ 67bf215546Sopenharmony_ci if (external_only) external_only[num] = 0; \ 68bf215546Sopenharmony_ci num++; \ 69bf215546Sopenharmony_ci} while (0) 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci for (i = 0; i < max && i < num_uc; i++) 72bf215546Sopenharmony_ci NVC0_ADD_MOD(DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, s, kind_gen, 73bf215546Sopenharmony_ci uc_kind, 5 - i)); 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci if (i < max) 76bf215546Sopenharmony_ci NVC0_ADD_MOD(DRM_FORMAT_MOD_LINEAR); 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci#undef NVC0_ADD_MOD 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci *count = num; 81bf215546Sopenharmony_ci} 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_cistatic bool 84bf215546Sopenharmony_cinvc0_is_dmabuf_modifier_supported(struct pipe_screen *screen, 85bf215546Sopenharmony_ci uint64_t modifier, enum pipe_format format, 86bf215546Sopenharmony_ci bool *external_only) 87bf215546Sopenharmony_ci{ 88bf215546Sopenharmony_ci const int s = nouveau_screen(screen)->tegra_sector_layout ? 0 : 1; 89bf215546Sopenharmony_ci const uint32_t uc_kind = 90bf215546Sopenharmony_ci nvc0_choose_tiled_storage_type(screen, format, 0, false); 91bf215546Sopenharmony_ci const uint32_t num_uc = uc_kind ? 6 : 0; /* max block height = 32 GOBs */ 92bf215546Sopenharmony_ci const uint32_t kind_gen = nvc0_get_kind_generation(screen); 93bf215546Sopenharmony_ci int i; 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci if (modifier == DRM_FORMAT_MOD_LINEAR) { 96bf215546Sopenharmony_ci if (external_only) 97bf215546Sopenharmony_ci *external_only = false; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci return true; 100bf215546Sopenharmony_ci } 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci for (i = 0; i < num_uc; i++) { 103bf215546Sopenharmony_ci if (DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, s, kind_gen, uc_kind, i) == modifier) { 104bf215546Sopenharmony_ci if (external_only) 105bf215546Sopenharmony_ci *external_only = false; 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci return true; 108bf215546Sopenharmony_ci } 109bf215546Sopenharmony_ci } 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci return false; 112bf215546Sopenharmony_ci} 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_cistatic struct pipe_resource * 115bf215546Sopenharmony_cinvc0_resource_from_handle(struct pipe_screen * screen, 116bf215546Sopenharmony_ci const struct pipe_resource *templ, 117bf215546Sopenharmony_ci struct winsys_handle *whandle, 118bf215546Sopenharmony_ci unsigned usage) 119bf215546Sopenharmony_ci{ 120bf215546Sopenharmony_ci if (templ->target == PIPE_BUFFER) { 121bf215546Sopenharmony_ci return NULL; 122bf215546Sopenharmony_ci } else { 123bf215546Sopenharmony_ci struct pipe_resource *res = nv50_miptree_from_handle(screen, 124bf215546Sopenharmony_ci templ, whandle); 125bf215546Sopenharmony_ci return res; 126bf215546Sopenharmony_ci } 127bf215546Sopenharmony_ci} 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_cistatic struct pipe_surface * 130bf215546Sopenharmony_cinvc0_surface_create(struct pipe_context *pipe, 131bf215546Sopenharmony_ci struct pipe_resource *pres, 132bf215546Sopenharmony_ci const struct pipe_surface *templ) 133bf215546Sopenharmony_ci{ 134bf215546Sopenharmony_ci if (unlikely(pres->target == PIPE_BUFFER)) 135bf215546Sopenharmony_ci return nv50_surface_from_buffer(pipe, pres, templ); 136bf215546Sopenharmony_ci return nvc0_miptree_surface_new(pipe, pres, templ); 137bf215546Sopenharmony_ci} 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_cistatic struct pipe_resource * 140bf215546Sopenharmony_cinvc0_resource_from_user_memory(struct pipe_screen *pipe, 141bf215546Sopenharmony_ci const struct pipe_resource *templ, 142bf215546Sopenharmony_ci void *user_memory) 143bf215546Sopenharmony_ci{ 144bf215546Sopenharmony_ci ASSERTED struct nouveau_screen *screen = nouveau_screen(pipe); 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci assert(screen->has_svm); 147bf215546Sopenharmony_ci assert(templ->target == PIPE_BUFFER); 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci return nouveau_buffer_create_from_user(pipe, templ, user_memory); 150bf215546Sopenharmony_ci} 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_civoid 153bf215546Sopenharmony_cinvc0_init_resource_functions(struct pipe_context *pcontext) 154bf215546Sopenharmony_ci{ 155bf215546Sopenharmony_ci pcontext->buffer_map = nouveau_buffer_transfer_map; 156bf215546Sopenharmony_ci pcontext->texture_map = nvc0_miptree_transfer_map; 157bf215546Sopenharmony_ci pcontext->transfer_flush_region = nouveau_buffer_transfer_flush_region; 158bf215546Sopenharmony_ci pcontext->buffer_unmap = nouveau_buffer_transfer_unmap; 159bf215546Sopenharmony_ci pcontext->texture_unmap = nvc0_miptree_transfer_unmap; 160bf215546Sopenharmony_ci pcontext->buffer_subdata = u_default_buffer_subdata; 161bf215546Sopenharmony_ci pcontext->texture_subdata = u_default_texture_subdata; 162bf215546Sopenharmony_ci pcontext->create_surface = nvc0_surface_create; 163bf215546Sopenharmony_ci pcontext->surface_destroy = nv50_surface_destroy; 164bf215546Sopenharmony_ci pcontext->invalidate_resource = nv50_invalidate_resource; 165bf215546Sopenharmony_ci} 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_civoid 168bf215546Sopenharmony_cinvc0_screen_init_resource_functions(struct pipe_screen *pscreen) 169bf215546Sopenharmony_ci{ 170bf215546Sopenharmony_ci pscreen->resource_create = nvc0_resource_create; 171bf215546Sopenharmony_ci pscreen->resource_create_with_modifiers = nvc0_resource_create_with_modifiers; 172bf215546Sopenharmony_ci pscreen->query_dmabuf_modifiers = nvc0_query_dmabuf_modifiers; 173bf215546Sopenharmony_ci pscreen->is_dmabuf_modifier_supported = nvc0_is_dmabuf_modifier_supported; 174bf215546Sopenharmony_ci pscreen->resource_from_handle = nvc0_resource_from_handle; 175bf215546Sopenharmony_ci pscreen->resource_get_handle = nvc0_miptree_get_handle; 176bf215546Sopenharmony_ci pscreen->resource_destroy = nvc0_resource_destroy; 177bf215546Sopenharmony_ci pscreen->resource_from_user_memory = nvc0_resource_from_user_memory; 178bf215546Sopenharmony_ci} 179