summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv50/nv50_screen.c
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2010-09-15 17:34:40 +0200
committerChristoph Bumiller <[email protected]>2010-09-15 17:34:40 +0200
commit26fe16a99b762d27e8f499c2e02116e9c4b7a6bb (patch)
tree153d15f0e24f349d2ba6ec736ed5e4b8b961e824 /src/gallium/drivers/nv50/nv50_screen.c
parent59ca1ae84b2c15c8a94211da158f563e45560bcd (diff)
parent84d170bbcef8e26017ac8e2f3bacbaeb20f889d3 (diff)
Merge remote branch 'origin/nv50-compiler'
Conflicts: src/gallium/drivers/nouveau/nouveau_class.h src/gallium/drivers/nv50/nv50_screen.c
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_screen.c')
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c138
1 files changed, 74 insertions, 64 deletions
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index f37dd079acb..49af9b59beb 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -26,6 +26,7 @@
#include "nv50_context.h"
#include "nv50_screen.h"
#include "nv50_resource.h"
+#include "nv50_program.h"
#include "nouveau/nouveau_stateobj.h"
@@ -34,75 +35,38 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned tex_usage, unsigned geom_flags)
+ unsigned usage, unsigned geom_flags)
{
if (sample_count > 1)
return FALSE;
- if (tex_usage & PIPE_BIND_RENDER_TARGET) {
+ if (!util_format_s3tc_enabled) {
switch (format) {
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B5G6R5_UNORM:
- case PIPE_FORMAT_R16G16B16A16_SNORM:
- case PIPE_FORMAT_R16G16B16A16_UNORM:
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- case PIPE_FORMAT_R16G16_SNORM:
- case PIPE_FORMAT_R16G16_UNORM:
- return TRUE;
- default:
- break;
- }
- } else
- if (tex_usage & PIPE_BIND_DEPTH_STENCIL) {
- switch (format) {
- case PIPE_FORMAT_Z32_FLOAT:
- case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
- case PIPE_FORMAT_Z24X8_UNORM:
- case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
- return TRUE;
- default:
- break;
- }
- } else {
- if (tex_usage & PIPE_BIND_SAMPLER_VIEW) {
- switch (format) {
- case PIPE_FORMAT_DXT1_RGB:
- case PIPE_FORMAT_DXT1_RGBA:
- case PIPE_FORMAT_DXT3_RGBA:
- case PIPE_FORMAT_DXT5_RGBA:
- return util_format_s3tc_enabled;
- default:
- break;
- }
- }
- switch (format) {
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- case PIPE_FORMAT_B8G8R8A8_SRGB:
- case PIPE_FORMAT_B8G8R8X8_SRGB:
- case PIPE_FORMAT_B5G5R5A1_UNORM:
- case PIPE_FORMAT_B4G4R4A4_UNORM:
- case PIPE_FORMAT_B5G6R5_UNORM:
- case PIPE_FORMAT_L8_UNORM:
- case PIPE_FORMAT_A8_UNORM:
- case PIPE_FORMAT_I8_UNORM:
- case PIPE_FORMAT_L8A8_UNORM:
- case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
- case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
- case PIPE_FORMAT_Z32_FLOAT:
- case PIPE_FORMAT_R16G16B16A16_SNORM:
- case PIPE_FORMAT_R16G16B16A16_UNORM:
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- case PIPE_FORMAT_R16G16_SNORM:
- case PIPE_FORMAT_R16G16_UNORM:
- return TRUE;
+ case PIPE_FORMAT_DXT1_RGB:
+ case PIPE_FORMAT_DXT1_RGBA:
+ case PIPE_FORMAT_DXT3_RGBA:
+ case PIPE_FORMAT_DXT5_RGBA:
+ return FALSE;
default:
break;
}
}
- return FALSE;
+ switch (format) {
+ case PIPE_FORMAT_Z16_UNORM:
+ if ((nouveau_screen(pscreen)->device->chipset & 0xf0) != 0xa0)
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+
+ /* transfers & shared are always supported */
+ usage &= ~(PIPE_BIND_TRANSFER_READ |
+ PIPE_BIND_TRANSFER_WRITE |
+ PIPE_BIND_SHARED);
+
+ return (nv50_format_table[format].usage & usage) == usage;
}
static int
@@ -142,6 +106,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
return 1;
+ case PIPE_CAP_TEXTURE_SWIZZLE:
+ return 1;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
return 1;
case PIPE_CAP_INDEP_BLEND_ENABLE:
@@ -165,10 +131,10 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
}
static int
-nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum pipe_shader_cap param)
+nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
+ enum pipe_shader_cap param)
{
- switch(shader)
- {
+ switch(shader) {
case PIPE_SHADER_FRAGMENT:
case PIPE_SHADER_VERTEX:
case PIPE_SHADER_GEOMETRY:
@@ -186,7 +152,7 @@ nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum
case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: /* need stack bo */
return 4;
case PIPE_SHADER_CAP_MAX_INPUTS: /* 128 / 4 with GP */
- if(shader == PIPE_SHADER_GEOMETRY)
+ if (shader == PIPE_SHADER_GEOMETRY)
return 128 / 4;
else
return 64 / 4;
@@ -197,7 +163,7 @@ nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum
case PIPE_SHADER_CAP_MAX_PREDS: /* not yet handled */
return 0;
case PIPE_SHADER_CAP_MAX_TEMPS: /* no spilling atm */
- return 128 / 4;
+ return NV50_CAP_MAX_PROGRAM_TEMPS;
case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
return 1;
default:
@@ -301,14 +267,23 @@ nv50_screen_relocs(struct nv50_screen *screen)
}
}
+#ifndef NOUVEAU_GETPARAM_GRAPH_UNITS
+# define NOUVEAU_GETPARAM_GRAPH_UNITS 13
+#endif
+
+extern int nouveau_device_get_param(struct nouveau_device *dev,
+ uint64_t param, uint64_t *value);
+
struct pipe_screen *
nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
{
struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen);
struct nouveau_channel *chan;
struct pipe_screen *pscreen;
+ uint64_t value;
unsigned chipset = dev->chipset;
unsigned tesla_class = 0;
+ unsigned stack_size, local_size, max_warps;
int ret, i;
const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
@@ -527,6 +502,41 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
OUT_RING (chan, 0x121 | (NV50_CB_PGP << 12));
OUT_RING (chan, 0x131 | (NV50_CB_PFP << 12));
+ /* shader stack */
+ nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
+
+ max_warps = util_bitcount(value & 0xffff);
+ max_warps *= util_bitcount((value >> 24) & 0xf) * 32;
+
+ stack_size = max_warps * 64 * 8;
+
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
+ stack_size, &screen->stack_bo);
+ if (ret) {
+ nv50_screen_destroy(pscreen);
+ return NULL;
+ }
+ BEGIN_RING(chan, screen->tesla, NV50TCL_STACK_ADDRESS_HIGH, 3);
+ OUT_RELOCh(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCl(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RING (chan, 4);
+
+ local_size = (NV50_CAP_MAX_PROGRAM_TEMPS * 16) * max_warps * 32;
+
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
+ local_size, &screen->local_bo);
+ if (ret) {
+ nv50_screen_destroy(pscreen);
+ return NULL;
+ }
+
+ local_size = NV50_CAP_MAX_PROGRAM_TEMPS * 16;
+
+ BEGIN_RING(chan, screen->tesla, NV50TCL_LOCAL_ADDRESS_HIGH, 3);
+ OUT_RELOCh(chan, screen->local_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCl(chan, screen->local_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RING (chan, util_unsigned_logbase2(local_size / 8));
+
/* Vertex array limits - max them out */
for (i = 0; i < 16; i++) {
BEGIN_RING(chan, screen->tesla,