X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fgallium%2Fdrivers%2Fnv50%2Fnv50_screen.c;h=e4ca72c717123ecade6bbd5386cd4e063e86f574;hb=32ed02bcfbe7a2132929658b1a73708ab16af006;hp=f091779e3b028ed19dff6bcbfba316a4d8c5786b;hpb=a414173105a18a0c6ed3b03ef986eb6eb30f7a58;p=mesa.git diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index f091779e3b0..e4ca72c7171 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -4,10 +4,40 @@ #include "nv50_context.h" #include "nv50_screen.h" +#include "nouveau/nouveau_stateobj.h" + +#define NV5X_GRCLASS5097_CHIPSETS 0x00000001 +#define NV8X_GRCLASS8297_CHIPSETS 0x00000010 +#define NV9X_GRCLASS8297_CHIPSETS 0x00000004 + static boolean nv50_screen_is_format_supported(struct pipe_screen *pscreen, enum pipe_format format, uint type) { + switch (type) { + case PIPE_SURFACE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z16_UNORM: + return TRUE; + default: + break; + } + break; + case PIPE_TEXTURE: + switch (format) { + case PIPE_FORMAT_I8_UNORM: + return TRUE; + default: + break; + } + break; + default: + assert(0); + } + return FALSE; } @@ -57,6 +87,9 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param) return 10; case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 13; + case NOUVEAU_CAP_HW_VTXBUF: + case NOUVEAU_CAP_HW_IDXBUF: + return 0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; @@ -94,13 +127,77 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, unsigned chipset) { struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen); + struct nouveau_stateobj *so; + unsigned tesla_class = 0, ret; + int i; if (!screen) return NULL; - screen->chipset = chipset; screen->nvws = nvws; + /* 3D object */ + if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) { + NOUVEAU_ERR("Not a G8x chipset\n"); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + + switch (chipset & 0xf0) { + case 0x50: + if (NV5X_GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f))) + tesla_class = 0x5097; + break; + case 0x80: + if (NV8X_GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) + tesla_class = 0x8297; + break; + case 0x90: + if (NV9X_GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) + tesla_class = 0x8297; + break; + default: + break; + } + + if (tesla_class == 0) { + NOUVEAU_ERR("Unknown G8x chipset: NV%02x\n", chipset); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + + ret = nvws->grobj_alloc(nvws, tesla_class, &screen->tesla); + if (ret) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + + /* Sync notifier */ + ret = nvws->notifier_alloc(nvws, 1, &screen->sync); + if (ret) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + + /* Static tesla init */ + so = so_new(128, 0); + so_method(so, screen->tesla, NV50TCL_DMA_NOTIFY, 1); + so_data (so, screen->sync->handle); + so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY0(0), + NV50TCL_DMA_IN_MEMORY0__SIZE); + for (i = 0; i < NV50TCL_DMA_IN_MEMORY0__SIZE; i++) + so_data(so, nvws->channel->vram->handle); + so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY1(0), + NV50TCL_DMA_IN_MEMORY1__SIZE); + for (i = 0; i < NV50TCL_DMA_IN_MEMORY1__SIZE; i++) + so_data(so, nvws->channel->vram->handle); + + so_emit(nvws, so); + so_ref(NULL, &so); + nvws->push_flush(nvws, 0, NULL); + screen->pipe.winsys = ws; screen->pipe.destroy = nv50_screen_destroy;