r300g: only check for an empty shader if there are no compile errors
[mesa.git] / src / gallium / drivers / r600 / r600_screen.c
index db17b88e9ac0966d76ef1904b8ff3ed480e64797..a047a49a6c55cd7d55e4f5dfd90b54dedf4fb8bb 100644 (file)
  *      Jerome Glisse
  *      Corbin Simpson
  */
-#include <util/u_inlines.h>
-#include <util/u_format.h>
-#include <util/u_memory.h>
+#include <stdio.h>
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_memory.h"
 #include "r600_screen.h"
-#include "r600_texture.h"
 #include "r600_context.h"
+#include "r600_public.h"
+#include "r600_resource.h"
+#include "r600_state_inlines.h"
 
 static const char* r600_get_vendor(struct pipe_screen* pscreen)
 {
@@ -38,70 +41,119 @@ static const char* r600_get_vendor(struct pipe_screen* pscreen)
 
 static const char* r600_get_name(struct pipe_screen* pscreen)
 {
-       return "R600";
+       struct r600_screen *screen = r600_screen(pscreen);
+       enum radeon_family family = radeon_get_family(screen->rw);
+
+       if (family >= CHIP_R600 && family < CHIP_RV770)
+               return "R600 (HD2XXX,HD3XXX)";
+       else
+               return "R700 (HD4XXX)";
 }
 
-static int r600_get_param(struct pipe_screen* pscreen, int param)
+static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 {
        switch (param) {
-       case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
-       case PIPE_CAP_MAX_COMBINED_SAMPLERS:
-               return 16;
+       /* Supported features (boolean caps). */
        case PIPE_CAP_NPOT_TEXTURES:
-               return 1;
        case PIPE_CAP_TWO_SIDED_STENCIL:
-               return 1;
        case PIPE_CAP_GLSL:
-               return 1;
        case PIPE_CAP_DUAL_SOURCE_BLEND:
-               return 1;
        case PIPE_CAP_ANISOTROPIC_FILTER:
-               return 1;
        case PIPE_CAP_POINT_SPRITE:
-               return 1;
-       case PIPE_CAP_MAX_RENDER_TARGETS:
-               /* FIXME some r6xx are buggy and can only do 4 */
-               return 8;
        case PIPE_CAP_OCCLUSION_QUERY:
-               return 1;
        case PIPE_CAP_TEXTURE_SHADOW_MAP:
-               return 1;
-       case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
-       case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
-       case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
-               /* FIXME not sure here */
-               return 13;
        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
-               return 1;
        case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
-               return 1;
-       case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
-               /* FIXME allow this once infrastructure is there */
-               return 0;
-       case PIPE_CAP_TGSI_CONT_SUPPORTED:
-               return 0;
        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
-               return 1;
        case PIPE_CAP_SM3:
-               return 1;
+       case PIPE_CAP_TEXTURE_SWIZZLE:
        case PIPE_CAP_INDEP_BLEND_ENABLE:
+       case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
+       case PIPE_CAP_DEPTH_CLAMP:
                return 1;
-       case PIPE_CAP_INDEP_BLEND_FUNC:
-               /* FIXME allow this */
+
+       /* Unsupported features (boolean caps). */
+       case PIPE_CAP_TIMER_QUERY:
+       case PIPE_CAP_TGSI_CONT_SUPPORTED:
+       case PIPE_CAP_STREAM_OUTPUT:
+       case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */
+       case PIPE_CAP_GEOMETRY_SHADER4:
                return 0;
+
+       /* Texturing. */
+       case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+       case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+       case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+               return 14;
+       case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
+               /* FIXME allow this once infrastructure is there */
+               return 0;
+       case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+       case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+               return 16;
+
+       /* Render targets. */
+       case PIPE_CAP_MAX_RENDER_TARGETS:
+               /* FIXME some r6xx are buggy and can only do 4 */
+               return 8;
+
+       /* Fragment coordinate conventions. */
        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
        case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
                return 1;
        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
        case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
                return 0;
+
+       /* Shader limits. */
+       case PIPE_CAP_MAX_VS_INSTRUCTIONS:
+               return 16384;  //max native instructions, not greater than max instructions
+       case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS:
+       case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS:
+       case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS:
+               return 16384;
+       case PIPE_CAP_MAX_FS_INSTRUCTIONS:
+               return 16384; //max program native instructions
+       case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS:
+               return 16384; //max program native ALU instructions
+       case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS:
+               return 16384; //max program native texture instructions
+       case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS:
+               return 2048; //max program native texture indirections
+       case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH:
+       case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH:
+               return 8; /* FIXME */
+       case PIPE_CAP_MAX_VS_INPUTS:
+               return 16; //max native attributes
+       case PIPE_CAP_MAX_FS_INPUTS:
+               return 10; //max native attributes
+       case PIPE_CAP_MAX_VS_TEMPS:
+               return 256; //max native temporaries
+       case PIPE_CAP_MAX_FS_TEMPS:
+               return 256; //max native temporaries
+       case PIPE_CAP_MAX_VS_ADDRS:
+       case PIPE_CAP_MAX_FS_ADDRS:
+               return 1; //max native address registers/* FIXME Isn't this equal to TEMPS? */
+       case PIPE_CAP_MAX_VS_CONSTS:
+               return 256; //max native parameters
+       case PIPE_CAP_MAX_FS_CONSTS:
+               return 256; //max program native parameters
+       case PIPE_CAP_MAX_CONST_BUFFERS:
+               return 1;
+       case PIPE_CAP_MAX_CONST_BUFFER_SIZE: /* in bytes */
+               return 4096;
+       case PIPE_CAP_MAX_PREDICATE_REGISTERS:
+       case PIPE_CAP_MAX_VS_PREDS:
+       case PIPE_CAP_MAX_FS_PREDS:
+               return 0; /* FIXME */
+
        default:
-               debug_printf("r600: unknown param %d\n", param);
+               R600_ERR("r600: unknown param %d\n", param);
                return 0;
        }
 }
 
-static float r600_get_paramf(struct pipe_screen* pscreen, int param)
+static float r600_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param)
 {
        switch (param) {
        case PIPE_CAP_MAX_LINE_WIDTH:
@@ -114,7 +166,7 @@ static float r600_get_paramf(struct pipe_screen* pscreen, int param)
        case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
                return 16.0f;
        default:
-               debug_printf("r600: unsupported paramf %d\n", param);
+               R600_ERR("r600: unsupported paramf %d\n", param);
                return 0.0f;
        }
 }
@@ -122,87 +174,52 @@ static float r600_get_paramf(struct pipe_screen* pscreen, int param)
 static boolean r600_is_format_supported(struct pipe_screen* screen,
                                        enum pipe_format format,
                                        enum pipe_texture_target target,
+                                       unsigned sample_count,
                                        unsigned usage,
                                        unsigned geom_flags)
 {
+       unsigned retval = 0;
        if (target >= PIPE_MAX_TEXTURE_TYPES) {
-               debug_printf("r600: unsupported texture type %d\n", target);
+               R600_ERR("r600: unsupported texture type %d\n", target);
                return FALSE;
        }
-       switch (format) {
-       case PIPE_FORMAT_A4R4G4B4_UNORM:
-       case PIPE_FORMAT_R5G6B5_UNORM:
-       case PIPE_FORMAT_A1R5G5B5_UNORM:
-       case PIPE_FORMAT_A8_UNORM:
-       case PIPE_FORMAT_L8_UNORM:
-       case PIPE_FORMAT_A8R8G8B8_SRGB:
-       case PIPE_FORMAT_R8G8B8A8_SRGB:
-       case PIPE_FORMAT_DXT1_RGB:
-       case PIPE_FORMAT_DXT1_RGBA:
-       case PIPE_FORMAT_DXT3_RGBA:
-       case PIPE_FORMAT_DXT5_RGBA:
-       case PIPE_FORMAT_YCBCR:
-       case PIPE_FORMAT_L8_SRGB:
-       case PIPE_FORMAT_A8L8_SRGB:
-       case PIPE_FORMAT_A8L8_UNORM:
-       case PIPE_FORMAT_A8R8G8B8_UNORM:
-       case PIPE_FORMAT_X8R8G8B8_UNORM:
-       case PIPE_FORMAT_R8G8B8A8_UNORM:
-       case PIPE_FORMAT_R8G8B8X8_UNORM:
-       case PIPE_FORMAT_I8_UNORM:
-       case PIPE_FORMAT_Z16_UNORM:
-       case PIPE_FORMAT_Z24X8_UNORM:
-       case PIPE_FORMAT_Z24S8_UNORM:
-       case PIPE_FORMAT_Z32_UNORM:
-       case PIPE_FORMAT_S8Z24_UNORM:
-       case PIPE_FORMAT_X8Z24_UNORM:
-               return TRUE;
-       default:
-               /* Unknown format... */
-               break;
+
+       /* Multisample */
+       if (sample_count > 1)
+               return FALSE;
+
+       if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
+           r600_is_sampler_format_supported(format)) {
+               retval |= PIPE_BIND_SAMPLER_VIEW;
        }
-       return FALSE;
-}
 
-static struct pipe_transfer* r600_get_tex_transfer(struct pipe_screen *screen,
-                                               struct pipe_texture *texture,
-                                               unsigned face, unsigned level,
-                                               unsigned zslice,
-                                               enum pipe_transfer_usage usage,
-                                               unsigned x, unsigned y,
-                                               unsigned w, unsigned h)
-{
-       struct r600_texture *rtex = (struct r600_texture*)texture;
-       struct r600_transfer *trans;
+       if ((usage & (PIPE_BIND_RENDER_TARGET |
+                  PIPE_BIND_DISPLAY_TARGET |
+                  PIPE_BIND_SCANOUT |
+                  PIPE_BIND_SHARED)) &&
+           r600_is_colorbuffer_format_supported(format)) {
+               retval |= usage &
+                       (PIPE_BIND_RENDER_TARGET |
+                        PIPE_BIND_DISPLAY_TARGET |
+                        PIPE_BIND_SCANOUT |
+                        PIPE_BIND_SHARED);
+       }
 
-       trans = CALLOC_STRUCT(r600_transfer);
-       if (trans == NULL)
-               return NULL;
-       pipe_texture_reference(&trans->transfer.texture, texture);
-       trans->transfer.x = x;
-       trans->transfer.y = y;
-       trans->transfer.width = w;
-       trans->transfer.height = h;
-       trans->transfer.stride = rtex->stride[level];
-       trans->transfer.usage = usage;
-       trans->transfer.zslice = zslice;
-       trans->transfer.face = face;
-       trans->offset = r600_texture_get_offset(rtex, level, zslice, face);
-       return &trans->transfer;
-}
+       if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
+           r600_is_zs_format_supported(format)) {
+               retval |= PIPE_BIND_DEPTH_STENCIL;
+       }
 
-static void r600_tex_transfer_destroy(struct pipe_transfer *trans)
-{
-}
+       if ((usage & PIPE_BIND_VERTEX_BUFFER) &&
+           r600_is_vertex_format_supported(format))
+               retval |= PIPE_BIND_VERTEX_BUFFER;
 
-static void* r600_transfer_map(struct pipe_screen* screen, struct pipe_transfer* transfer)
-{
-       /* FIXME implement */
-       return NULL;
-}
+       if (usage & PIPE_BIND_TRANSFER_READ)
+               retval |= PIPE_BIND_TRANSFER_READ;
+       if (usage & PIPE_BIND_TRANSFER_WRITE)
+               retval |= PIPE_BIND_TRANSFER_WRITE;
 
-static void r600_transfer_unmap(struct pipe_screen* screen, struct pipe_transfer* transfer)
-{
+       return retval == usage;
 }
 
 static void r600_destroy_screen(struct pipe_screen* pscreen)
@@ -214,14 +231,37 @@ static void r600_destroy_screen(struct pipe_screen* pscreen)
        FREE(rscreen);
 }
 
-struct pipe_screen *radeon_create_screen(struct radeon *rw)
+struct pipe_screen *r600_screen_create(struct radeon *rw)
 {
        struct r600_screen* rscreen;
+       enum radeon_family family = radeon_get_family(rw);
 
        rscreen = CALLOC_STRUCT(r600_screen);
        if (rscreen == NULL) {
                return NULL;
        }
+
+       switch (family) {
+       case CHIP_R600:
+       case CHIP_RV610:
+       case CHIP_RV630:
+       case CHIP_RV670:
+       case CHIP_RV620:
+       case CHIP_RV635:
+       case CHIP_RS780:
+       case CHIP_RS880:
+               rscreen->chip_class = R600;
+               break;
+       case CHIP_RV770:
+       case CHIP_RV730:
+       case CHIP_RV710:
+       case CHIP_RV740:
+               rscreen->chip_class = R700;
+               break;
+       default:
+               FREE(rscreen);
+               return NULL;
+       }
        rscreen->rw = rw;
        rscreen->screen.winsys = (struct pipe_winsys*)rw;
        rscreen->screen.destroy = r600_destroy_screen;
@@ -231,11 +271,7 @@ struct pipe_screen *radeon_create_screen(struct radeon *rw)
        rscreen->screen.get_paramf = r600_get_paramf;
        rscreen->screen.is_format_supported = r600_is_format_supported;
        rscreen->screen.context_create = r600_create_context;
-       rscreen->screen.get_tex_transfer = r600_get_tex_transfer;
-       rscreen->screen.tex_transfer_destroy = r600_tex_transfer_destroy;
-       rscreen->screen.transfer_map = r600_transfer_map;
-       rscreen->screen.transfer_unmap = r600_transfer_unmap;
-       r600_screen_init_buffer_functions(&rscreen->screen);
        r600_init_screen_texture_functions(&rscreen->screen);
+       r600_init_screen_resource_functions(rscreen);
        return &rscreen->screen;
 }