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