nv50_screen.c revision fa4b2439d4f240a5e573d4ea198b829791d614f4
1#include "pipe/p_screen.h" 2#include "pipe/p_util.h" 3 4#include "nv50_context.h" 5#include "nv50_screen.h" 6 7#include "nouveau/nouveau_stateobj.h" 8 9#define NV5X_GRCLASS5097_CHIPSETS 0x00000001 10#define NV8X_GRCLASS8297_CHIPSETS 0x00000010 11#define NV9X_GRCLASS8297_CHIPSETS 0x00000004 12 13static boolean 14nv50_screen_is_format_supported(struct pipe_screen *pscreen, 15 enum pipe_format format, uint type) 16{ 17 switch (type) { 18 case PIPE_SURFACE: 19 switch (format) { 20 case PIPE_FORMAT_A8R8G8B8_UNORM: 21 case PIPE_FORMAT_R5G6B5_UNORM: 22 case PIPE_FORMAT_Z24S8_UNORM: 23 case PIPE_FORMAT_Z16_UNORM: 24 return TRUE; 25 default: 26 break; 27 } 28 break; 29 case PIPE_TEXTURE: 30 switch (format) { 31 case PIPE_FORMAT_I8_UNORM: 32 return TRUE; 33 default: 34 break; 35 } 36 break; 37 default: 38 assert(0); 39 } 40 41 return FALSE; 42} 43 44static const char * 45nv50_screen_get_name(struct pipe_screen *pscreen) 46{ 47 struct nv50_screen *screen = nv50_screen(pscreen); 48 struct nouveau_device *dev = screen->nvws->channel->device; 49 static char buffer[128]; 50 51 snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); 52 return buffer; 53} 54 55static const char * 56nv50_screen_get_vendor(struct pipe_screen *pscreen) 57{ 58 return "nouveau"; 59} 60 61static int 62nv50_screen_get_param(struct pipe_screen *pscreen, int param) 63{ 64 switch (param) { 65 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: 66 return 32; 67 case PIPE_CAP_NPOT_TEXTURES: 68 return 0; 69 case PIPE_CAP_TWO_SIDED_STENCIL: 70 return 1; 71 case PIPE_CAP_GLSL: 72 return 0; 73 case PIPE_CAP_S3TC: 74 return 0; 75 case PIPE_CAP_ANISOTROPIC_FILTER: 76 return 0; 77 case PIPE_CAP_POINT_SPRITE: 78 return 0; 79 case PIPE_CAP_MAX_RENDER_TARGETS: 80 return 8; 81 case PIPE_CAP_OCCLUSION_QUERY: 82 return 0; 83 case PIPE_CAP_TEXTURE_SHADOW_MAP: 84 return 0; 85 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 86 return 13; 87 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 88 return 10; 89 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 90 return 13; 91 case NOUVEAU_CAP_HW_VTXBUF: 92 case NOUVEAU_CAP_HW_IDXBUF: 93 return 0; 94 default: 95 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); 96 return 0; 97 } 98} 99 100static float 101nv50_screen_get_paramf(struct pipe_screen *pscreen, int param) 102{ 103 switch (param) { 104 case PIPE_CAP_MAX_LINE_WIDTH: 105 case PIPE_CAP_MAX_LINE_WIDTH_AA: 106 return 10.0; 107 case PIPE_CAP_MAX_POINT_WIDTH: 108 case PIPE_CAP_MAX_POINT_WIDTH_AA: 109 return 64.0; 110 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: 111 return 16.0; 112 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: 113 return 4.0; 114 default: 115 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); 116 return 0.0; 117 } 118} 119 120static void * 121nv50_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, 122 unsigned flags ) 123{ 124 struct pipe_winsys *ws = screen->winsys; 125 void *map; 126 127 map = ws->buffer_map(ws, surface->buffer, flags); 128 if (!map) 129 return NULL; 130 131 return map + surface->offset; 132} 133 134static void 135nv50_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) 136{ 137 struct pipe_winsys *ws = screen->winsys; 138 139 ws->buffer_unmap(ws, surface->buffer); 140} 141 142static void 143nv50_screen_destroy(struct pipe_screen *pscreen) 144{ 145 FREE(pscreen); 146} 147 148struct pipe_screen * 149nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) 150{ 151 struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen); 152 struct nouveau_stateobj *so; 153 unsigned tesla_class = 0, ret; 154 unsigned chipset = nvws->channel->device->chipset; 155 int i; 156 157 if (!screen) 158 return NULL; 159 screen->nvws = nvws; 160 161 /* 3D object */ 162 if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) { 163 NOUVEAU_ERR("Not a G8x chipset\n"); 164 nv50_screen_destroy(&screen->pipe); 165 return NULL; 166 } 167 168 switch (chipset & 0xf0) { 169 case 0x50: 170 if (NV5X_GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f))) 171 tesla_class = 0x5097; 172 break; 173 case 0x80: 174 if (NV8X_GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) 175 tesla_class = 0x8297; 176 break; 177 case 0x90: 178 if (NV9X_GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) 179 tesla_class = 0x8297; 180 break; 181 default: 182 break; 183 } 184 185 if (tesla_class == 0) { 186 NOUVEAU_ERR("Unknown G8x chipset: NV%02x\n", chipset); 187 nv50_screen_destroy(&screen->pipe); 188 return NULL; 189 } 190 191 ret = nvws->grobj_alloc(nvws, tesla_class, &screen->tesla); 192 if (ret) { 193 NOUVEAU_ERR("Error creating 3D object: %d\n", ret); 194 nv50_screen_destroy(&screen->pipe); 195 return NULL; 196 } 197 198 /* Sync notifier */ 199 ret = nvws->notifier_alloc(nvws, 1, &screen->sync); 200 if (ret) { 201 NOUVEAU_ERR("Error creating notifier object: %d\n", ret); 202 nv50_screen_destroy(&screen->pipe); 203 return NULL; 204 } 205 206 /* Static tesla init */ 207 so = so_new(128, 0); 208 so_method(so, screen->tesla, NV50TCL_DMA_NOTIFY, 1); 209 so_data (so, screen->sync->handle); 210 so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY0(0), 211 NV50TCL_DMA_IN_MEMORY0__SIZE); 212 for (i = 0; i < NV50TCL_DMA_IN_MEMORY0__SIZE; i++) 213 so_data(so, nvws->channel->vram->handle); 214 so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY1(0), 215 NV50TCL_DMA_IN_MEMORY1__SIZE); 216 for (i = 0; i < NV50TCL_DMA_IN_MEMORY1__SIZE; i++) 217 so_data(so, nvws->channel->vram->handle); 218 219 so_emit(nvws, so); 220 so_ref(NULL, &so); 221 nvws->push_flush(nvws, 0, NULL); 222 223 screen->pipe.winsys = ws; 224 225 screen->pipe.destroy = nv50_screen_destroy; 226 227 screen->pipe.get_name = nv50_screen_get_name; 228 screen->pipe.get_vendor = nv50_screen_get_vendor; 229 screen->pipe.get_param = nv50_screen_get_param; 230 screen->pipe.get_paramf = nv50_screen_get_paramf; 231 232 screen->pipe.is_format_supported = nv50_screen_is_format_supported; 233 234 screen->pipe.surface_map = nv50_surface_map; 235 screen->pipe.surface_unmap = nv50_surface_unmap; 236 237 nv50_screen_init_miptree_functions(&screen->pipe); 238 239 return &screen->pipe; 240} 241 242