summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvc0/nvc0_screen.c
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2013-02-23 19:40:23 +0100
committerChristoph Bumiller <[email protected]>2013-03-12 12:55:37 +0100
commite066f2f62f6043d43385bcdce4e7fa07ffa3ecbe (patch)
tree6f49b99571ffd3b93727988b635d74b0c397857e /src/gallium/drivers/nvc0/nvc0_screen.c
parent75f1f852b00ad0d766684d01695322b93a2acd55 (diff)
nvc0: implement compute support for nve4
Diffstat (limited to 'src/gallium/drivers/nvc0/nvc0_screen.c')
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.c84
1 files changed, 79 insertions, 5 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index 077f89efef9..7d034797eef 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -88,12 +88,12 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
switch (param) {
case PIPE_CAP_MAX_COMBINED_SAMPLERS:
- return 16 * PIPE_SHADER_TYPES; /* NOTE: should not count COMPUTE */
+ return 16 * 5;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
return 15;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 12;
+ return (class_3d >= NVE4_3D_CLASS) ? 13 : 12;
case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
return 2048;
case PIPE_CAP_MIN_TEXEL_OFFSET:
@@ -176,6 +176,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_TEXTURE_MULTISAMPLE:
return 0;
+ case PIPE_CAP_COMPUTE:
+ return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
default:
NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
return 0;
@@ -186,6 +188,8 @@ static int
nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
enum pipe_shader_cap param)
{
+ const uint16_t class_3d = nouveau_screen(pscreen)->class_3d;
+
switch (shader) {
case PIPE_SHADER_VERTEX:
/*
@@ -195,11 +199,17 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
case PIPE_SHADER_GEOMETRY:
case PIPE_SHADER_FRAGMENT:
break;
+ case PIPE_SHADER_COMPUTE:
+ if (class_3d < NVE4_3D_CLASS)
+ return 0;
+ break;
default:
return 0;
}
switch (param) {
+ case PIPE_SHADER_CAP_PREFERRED_IR:
+ return PIPE_SHADER_IR_TGSI;
case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
@@ -216,6 +226,8 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
case PIPE_SHADER_CAP_MAX_CONSTS:
return 65536 / 16;
case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+ if (shader == PIPE_SHADER_COMPUTE && class_3d >= NVE4_3D_CLASS)
+ return NVE4_MAX_PIPE_CONSTBUFS_COMPUTE;
return NVC0_MAX_PIPE_CONSTBUFS;
case PIPE_SHADER_CAP_MAX_ADDRS:
return 1;
@@ -234,7 +246,7 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
return 0;
case PIPE_SHADER_CAP_SUBROUTINES:
- return 1; /* but inlining everything, we need function declarations */
+ return 1;
case PIPE_SHADER_CAP_INTEGERS:
return 1;
case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
@@ -270,6 +282,47 @@ nvc0_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
}
}
+static int
+nvc0_screen_get_compute_param(struct pipe_screen *pscreen,
+ enum pipe_compute_cap param, void *data)
+{
+ uint64_t *data64 = (uint64_t *)data;
+ const uint16_t obj_class = nvc0_screen(pscreen)->compute->oclass;
+
+ switch (param) {
+ case PIPE_COMPUTE_CAP_GRID_DIMENSION:
+ data64[0] = 3;
+ return 8;
+ case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
+ data64[0] = (obj_class >= NVE4_COMPUTE_CLASS) ? 0x7fffffff : 65535;
+ data64[1] = 65535;
+ data64[2] = 65535;
+ return 24;
+ case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
+ data64[0] = 1024;
+ data64[1] = 1024;
+ data64[2] = 64;
+ return 24;
+ case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
+ data64[0] = 1024;
+ return 8;
+ case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE: /* g[] */
+ data64[0] = (uint64_t)1 << 40;
+ return 8;
+ case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE: /* s[] */
+ data64[0] = 48 << 10;
+ return 8;
+ case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE: /* l[] */
+ data64[0] = 512 << 10;
+ return 8;
+ case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE: /* c[], arbitrary limit */
+ data64[0] = 4096;
+ return 8;
+ default:
+ return 0;
+ }
+}
+
static void
nvc0_screen_destroy(struct pipe_screen *pscreen)
{
@@ -291,6 +344,7 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
nouveau_bo_ref(NULL, &screen->txc);
nouveau_bo_ref(NULL, &screen->fence.bo);
nouveau_bo_ref(NULL, &screen->poly_cache);
+ nouveau_bo_ref(NULL, &screen->parm);
nouveau_heap_destroy(&screen->lib_code);
nouveau_heap_destroy(&screen->text_heap);
@@ -412,6 +466,23 @@ nvc0_screen_fence_update(struct pipe_screen *pscreen)
return screen->fence.map[0];
}
+static int
+nvc0_screen_init_compute(struct nvc0_screen *screen)
+{
+ screen->base.base.get_compute_param = nvc0_screen_get_compute_param;
+
+ switch (screen->base.device->chipset & 0xf0) {
+ case 0xc0:
+ case 0xd0:
+ return 0;
+ case 0xe0:
+ case 0xf0:
+ return nve4_screen_compute_setup(screen, screen->base.pushbuf);
+ default:
+ return -1;
+ }
+}
+
#define FAIL_SCREEN_INIT(str, err) \
do { \
NOUVEAU_ERR(str, err); \
@@ -653,9 +724,9 @@ nvc0_screen_create(struct nouveau_device *dev)
/* max MPs * max warps per MP (TODO: ask kernel) */
if (screen->eng3d->oclass >= NVE4_3D_CLASS)
- screen->tls_size = 8 * 64;
+ screen->tls_size = 8 * 64 * 32;
else
- screen->tls_size = 16 * 48;
+ screen->tls_size = 16 * 48 * 32;
screen->tls_size *= NVC0_CAP_MAX_PROGRAM_TEMPS * 16;
screen->tls_size = align(screen->tls_size, 1 << 17);
@@ -775,6 +846,9 @@ nvc0_screen_create(struct nouveau_device *dev)
IMMED_NVC0(push, NVC0_3D(EDGEFLAG), 1);
+ if (nvc0_screen_init_compute(screen))
+ goto fail;
+
PUSH_KICK (push);
screen->tic.entries = CALLOC(4096, sizeof(void *));