v3d: Load and store aligned utiles all at once.
[mesa.git] / src / gallium / drivers / v3d / v3d_screen.c
index 95e6a6907f49eea76336820379e5328aaa8f692c..f6846080c1c7214ff1c25e1950d4d418d55d0cae 100644 (file)
@@ -22,7 +22,7 @@
  * IN THE SOFTWARE.
  */
 
-#include "os/os_misc.h"
+#include "util/os_misc.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_screen.h"
 #include "pipe/p_state.h"
@@ -31,6 +31,8 @@
 #include "util/u_memory.h"
 #include "util/u_format.h"
 #include "util/u_hash_table.h"
+#include "util/u_screen.h"
+#include "util/u_transfer_helper.h"
 #include "util/ralloc.h"
 
 #include <xf86drm.h>
 #include "compiler/v3d_compiler.h"
 
 static const char *
-vc5_screen_get_name(struct pipe_screen *pscreen)
+v3d_screen_get_name(struct pipe_screen *pscreen)
 {
-        struct vc5_screen *screen = vc5_screen(pscreen);
+        struct v3d_screen *screen = v3d_screen(pscreen);
 
         if (!screen->name) {
                 screen->name = ralloc_asprintf(screen,
-                                               "VC5 V3D %d.%d",
+                                               "V3D %d.%d",
                                                screen->devinfo.ver / 10,
                                                screen->devinfo.ver % 10);
         }
@@ -55,33 +57,48 @@ vc5_screen_get_name(struct pipe_screen *pscreen)
 }
 
 static const char *
-vc5_screen_get_vendor(struct pipe_screen *pscreen)
+v3d_screen_get_vendor(struct pipe_screen *pscreen)
 {
         return "Broadcom";
 }
 
 static void
-vc5_screen_destroy(struct pipe_screen *pscreen)
+v3d_screen_destroy(struct pipe_screen *pscreen)
 {
-        struct vc5_screen *screen = vc5_screen(pscreen);
+        struct v3d_screen *screen = v3d_screen(pscreen);
 
         util_hash_table_destroy(screen->bo_handles);
-        vc5_bufmgr_destroy(pscreen);
+        v3d_bufmgr_destroy(pscreen);
         slab_destroy_parent(&screen->transfer_pool);
 
-        if (using_vc5_simulator)
-                vc5_simulator_destroy(screen);
+        if (using_v3d_simulator)
+                v3d_simulator_destroy(screen);
 
         v3d_compiler_free(screen->compiler);
+        u_transfer_helper_destroy(pscreen->transfer_helper);
 
         close(screen->fd);
         ralloc_free(pscreen);
 }
 
+static bool
+v3d_has_feature(struct v3d_screen *screen, enum drm_v3d_param feature)
+{
+        struct drm_v3d_get_param p = {
+                .param = feature,
+        };
+        int ret = v3d_ioctl(screen->fd, DRM_IOCTL_V3D_GET_PARAM, &p);
+
+        if (ret != 0)
+                return false;
+
+        return p.value;
+}
+
 static int
-vc5_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
+v3d_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 {
-        struct vc5_screen *screen = vc5_screen(pscreen);
+        struct v3d_screen *screen = v3d_screen(pscreen);
 
         switch (param) {
                 /* Supported features (boolean caps). */
@@ -100,17 +117,22 @@ vc5_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
         case PIPE_CAP_SM3:
         case PIPE_CAP_TEXTURE_QUERY_LOD:
         case PIPE_CAP_PRIMITIVE_RESTART:
-        case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
         case PIPE_CAP_OCCLUSION_QUERY:
         case PIPE_CAP_POINT_SPRITE:
         case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
-        case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
         case PIPE_CAP_COMPUTE:
         case PIPE_CAP_DRAW_INDIRECT:
+        case PIPE_CAP_MULTI_DRAW_INDIRECT:
         case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
         case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET:
+        case PIPE_CAP_TGSI_CAN_READ_OUTPUTS:
+        case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
+        case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
                 return 1;
 
+        case PIPE_CAP_GENERATE_MIPMAP:
+                return v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_TFU);
+
         case PIPE_CAP_INDEP_BLEND_ENABLE:
                 return screen->devinfo.ver >= 40;
 
@@ -123,8 +145,8 @@ vc5_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
         case PIPE_CAP_GLSL_FEATURE_LEVEL:
                 return 400;
 
-        case PIPE_CAP_MAX_VIEWPORTS:
-                return 1;
+       case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
+               return 140;
 
         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
                 return 1;
@@ -146,132 +168,8 @@ vc5_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
         case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
                 return 1;
 
-
-                /* Stream output. */
         case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
                 return 4;
-        case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
-        case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
-                return 64;
-
-        case PIPE_CAP_MIN_TEXEL_OFFSET:
-        case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
-                return -8;
-        case PIPE_CAP_MAX_TEXEL_OFFSET:
-        case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
-                return 7;
-
-                /* Unsupported features. */
-        case PIPE_CAP_ANISOTROPIC_FILTER:
-        case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
-        case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
-        case PIPE_CAP_CUBE_MAP_ARRAY:
-        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
-        case PIPE_CAP_SEAMLESS_CUBE_MAP:
-        case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
-        case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
-        case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
-        case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
-        case PIPE_CAP_SHADER_STENCIL_EXPORT:
-        case PIPE_CAP_TGSI_TEXCOORD:
-        case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
-        case PIPE_CAP_CONDITIONAL_RENDER:
-        case PIPE_CAP_TEXTURE_BARRIER:
-        case PIPE_CAP_INDEP_BLEND_FUNC:
-        case PIPE_CAP_DEPTH_CLIP_DISABLE:
-        case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
-        case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
-        case PIPE_CAP_USER_VERTEX_BUFFERS:
-        case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
-        case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
-        case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
-        case PIPE_CAP_TGSI_TES_LAYER_VIEWPORT:
-        case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
-        case PIPE_CAP_TEXTURE_GATHER_SM5:
-        case PIPE_CAP_FAKE_SW_MSAA:
-        case PIPE_CAP_SAMPLE_SHADING:
-        case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
-        case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
-        case PIPE_CAP_MAX_VERTEX_STREAMS:
-        case PIPE_CAP_MULTI_DRAW_INDIRECT:
-        case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
-        case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
-        case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
-        case PIPE_CAP_SAMPLER_VIEW_TARGET:
-        case PIPE_CAP_CLIP_HALFZ:
-        case PIPE_CAP_VERTEXID_NOBASE:
-        case PIPE_CAP_POLYGON_OFFSET_CLAMP:
-        case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
-        case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
-        case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
-        case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
-        case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
-        case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
-        case PIPE_CAP_DEPTH_BOUNDS_TEST:
-        case PIPE_CAP_TGSI_TXQS:
-        case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
-        case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
-        case PIPE_CAP_CLEAR_TEXTURE:
-        case PIPE_CAP_DRAW_PARAMETERS:
-        case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
-        case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
-        case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
-        case PIPE_CAP_INVALIDATE_BUFFER:
-        case PIPE_CAP_GENERATE_MIPMAP:
-        case PIPE_CAP_STRING_MARKER:
-        case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
-        case PIPE_CAP_QUERY_BUFFER_OBJECT:
-        case PIPE_CAP_QUERY_MEMORY_INFO:
-        case PIPE_CAP_PCI_GROUP:
-        case PIPE_CAP_PCI_BUS:
-        case PIPE_CAP_PCI_DEVICE:
-        case PIPE_CAP_PCI_FUNCTION:
-        case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
-        case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
-        case PIPE_CAP_CULL_DISTANCE:
-        case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
-        case PIPE_CAP_TGSI_VOTE:
-        case PIPE_CAP_MAX_WINDOW_RECTANGLES:
-        case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
-        case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
-        case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
-        case PIPE_CAP_TGSI_FS_FBFETCH:
-        case PIPE_CAP_INT64:
-        case PIPE_CAP_INT64_DIVMOD:
-        case PIPE_CAP_DOUBLES:
-        case PIPE_CAP_BINDLESS_TEXTURE:
-        case PIPE_CAP_POST_DEPTH_COVERAGE:
-        case PIPE_CAP_CAN_BIND_CONST_BUFFER_AS_VERTEX:
-        case PIPE_CAP_TGSI_BALLOT:
-        case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE:
-        case PIPE_CAP_POLYGON_MODE_FILL_RECTANGLE:
-        case PIPE_CAP_TGSI_CLOCK:
-        case PIPE_CAP_TGSI_TEX_TXF_LZ:
-        case PIPE_CAP_NATIVE_FENCE_FD:
-        case PIPE_CAP_FENCE_SIGNAL:
-        case PIPE_CAP_TGSI_MUL_ZERO_WINS:
-        case PIPE_CAP_NIR_SAMPLERS_AS_DEREF:
-        case PIPE_CAP_QUERY_SO_OVERFLOW:
-        case PIPE_CAP_MEMOBJ:
-        case PIPE_CAP_LOAD_CONSTBUF:
-        case PIPE_CAP_TILE_RASTER_ORDER:
-        case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
-        case PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
-        case PIPE_CAP_CONTEXT_PRIORITY_MASK:
-        case PIPE_CAP_CONSTBUF0_FLAGS:
-        case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_TRIANGLES:
-        case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_POINTS_LINES:
-        case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_TRIANGLES:
-        case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES:
-        case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE:
-        case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS:
-        case PIPE_CAP_PACKED_UNIFORMS:
-                return 0;
-
-                /* Geometry shader output, unsupported. */
-        case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
-        case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
-                return 0;
 
                 /* Texturing. */
         case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
@@ -285,24 +183,8 @@ vc5_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
         case PIPE_CAP_MAX_RENDER_TARGETS:
                 return 4;
 
-                /* Queries. */
-        case PIPE_CAP_QUERY_TIME_ELAPSED:
-        case PIPE_CAP_QUERY_TIMESTAMP:
-                return 0;
-
-        case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
-                return 2048;
-
-        case PIPE_CAP_ENDIANNESS:
-                return PIPE_ENDIAN_LITTLE;
-
-        case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
-                return 64;
-
         case PIPE_CAP_VENDOR_ID:
                 return 0x14E4;
-        case PIPE_CAP_DEVICE_ID:
-                return 0xFFFFFFFF;
         case PIPE_CAP_ACCELERATED:
                 return 1;
         case PIPE_CAP_VIDEO_MEMORY: {
@@ -317,13 +199,12 @@ vc5_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
                 return 1;
 
         default:
-                fprintf(stderr, "unknown param %d\n", param);
-                return 0;
+                return u_pipe_screen_get_param_defaults(pscreen, param);
         }
 }
 
 static float
-vc5_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
+v3d_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
 {
         switch (param) {
         case PIPE_CAPF_MAX_LINE_WIDTH:
@@ -350,7 +231,7 @@ vc5_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
 }
 
 static int
-vc5_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
+v3d_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
                            enum pipe_shader_cap param)
 {
         if (shader != PIPE_SHADER_VERTEX &&
@@ -373,7 +254,7 @@ vc5_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
                 if (shader == PIPE_SHADER_FRAGMENT)
                         return VC5_MAX_FS_INPUTS / 4;
                 else
-                        return 16;
+                        return VC5_MAX_ATTRIBUTES;
         case PIPE_SHADER_CAP_MAX_OUTPUTS:
                 if (shader == PIPE_SHADER_FRAGMENT)
                         return 4;
@@ -407,6 +288,8 @@ vc5_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
         case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
         case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
                 return 0;
+        case PIPE_SHADER_CAP_SCALAR_ISA:
+                return 1;
         case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
         case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
         case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
@@ -429,19 +312,22 @@ vc5_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
 }
 
 static boolean
-vc5_screen_is_format_supported(struct pipe_screen *pscreen,
+v3d_screen_is_format_supported(struct pipe_screen *pscreen,
                                enum pipe_format format,
                                enum pipe_texture_target target,
                                unsigned sample_count,
+                               unsigned storage_sample_count,
                                unsigned usage)
 {
-        struct vc5_screen *screen = vc5_screen(pscreen);
+        struct v3d_screen *screen = v3d_screen(pscreen);
+
+        if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
+                return false;
 
         if (sample_count > 1 && sample_count != VC5_MAX_SAMPLES)
                 return FALSE;
 
-        if ((target >= PIPE_MAX_TEXTURE_TYPES) ||
-            !util_format_is_supported(format, usage)) {
+        if (target >= PIPE_MAX_TEXTURE_TYPES) {
                 return FALSE;
         }
 
@@ -506,12 +392,12 @@ vc5_screen_is_format_supported(struct pipe_screen *pscreen,
         }
 
         if ((usage & PIPE_BIND_RENDER_TARGET) &&
-            !vc5_rt_format_supported(&screen->devinfo, format)) {
+            !v3d_rt_format_supported(&screen->devinfo, format)) {
                 return FALSE;
         }
 
         if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
-            !vc5_tex_format_supported(&screen->devinfo, format)) {
+            !v3d_tex_format_supported(&screen->devinfo, format)) {
                 return FALSE;
         }
 
@@ -547,7 +433,7 @@ static int handle_compare(void *key1, void *key2)
 }
 
 static bool
-vc5_get_device_info(struct vc5_screen *screen)
+v3d_get_device_info(struct v3d_screen *screen)
 {
         struct drm_v3d_get_param ident0 = {
                 .param = DRM_V3D_PARAM_V3D_CORE0_IDENT0,
@@ -557,13 +443,13 @@ vc5_get_device_info(struct vc5_screen *screen)
         };
         int ret;
 
-        ret = vc5_ioctl(screen->fd, DRM_IOCTL_V3D_GET_PARAM, &ident0);
+        ret = v3d_ioctl(screen->fd, DRM_IOCTL_V3D_GET_PARAM, &ident0);
         if (ret != 0) {
                 fprintf(stderr, "Couldn't get V3D core IDENT0: %s\n",
                         strerror(errno));
                 return false;
         }
-        ret = vc5_ioctl(screen->fd, DRM_IOCTL_V3D_GET_PARAM, &ident1);
+        ret = v3d_ioctl(screen->fd, DRM_IOCTL_V3D_GET_PARAM, &ident1);
         if (ret != 0) {
                 fprintf(stderr, "Couldn't get V3D core IDENT1: %s\n",
                         strerror(errno));
@@ -574,6 +460,8 @@ vc5_get_device_info(struct vc5_screen *screen)
         uint32_t minor = (ident1.value >> 0) & 0xf;
         screen->devinfo.ver = major * 10 + minor;
 
+        screen->devinfo.vpm_size = (ident1.value >> 28 & 0xf) * 8192;
+
         switch (screen->devinfo.ver) {
         case 33:
         case 41:
@@ -591,53 +479,61 @@ vc5_get_device_info(struct vc5_screen *screen)
 }
 
 static const void *
-vc5_screen_get_compiler_options(struct pipe_screen *pscreen,
+v3d_screen_get_compiler_options(struct pipe_screen *pscreen,
                                 enum pipe_shader_ir ir, unsigned shader)
 {
         return &v3d_nir_options;
 }
 
 struct pipe_screen *
-v3d_screen_create(int fd)
+v3d_screen_create(int fd, struct renderonly *ro)
 {
-        struct vc5_screen *screen = rzalloc(NULL, struct vc5_screen);
+        struct v3d_screen *screen = rzalloc(NULL, struct v3d_screen);
         struct pipe_screen *pscreen;
 
         pscreen = &screen->base;
 
-        pscreen->destroy = vc5_screen_destroy;
-        pscreen->get_param = vc5_screen_get_param;
-        pscreen->get_paramf = vc5_screen_get_paramf;
-        pscreen->get_shader_param = vc5_screen_get_shader_param;
-        pscreen->context_create = vc5_context_create;
-        pscreen->is_format_supported = vc5_screen_is_format_supported;
+        pscreen->destroy = v3d_screen_destroy;
+        pscreen->get_param = v3d_screen_get_param;
+        pscreen->get_paramf = v3d_screen_get_paramf;
+        pscreen->get_shader_param = v3d_screen_get_shader_param;
+        pscreen->context_create = v3d_context_create;
+        pscreen->is_format_supported = v3d_screen_is_format_supported;
 
         screen->fd = fd;
+        if (ro) {
+                screen->ro = renderonly_dup(ro);
+                if (!screen->ro) {
+                        fprintf(stderr, "Failed to dup renderonly object\n");
+                        ralloc_free(screen);
+                        return NULL;
+                }
+        }
         list_inithead(&screen->bo_cache.time_list);
         (void)mtx_init(&screen->bo_handles_mutex, mtx_plain);
         screen->bo_handles = util_hash_table_create(handle_hash, handle_compare);
 
 #if defined(USE_V3D_SIMULATOR)
-        vc5_simulator_init(screen);
+        v3d_simulator_init(screen);
 #endif
 
-        if (!vc5_get_device_info(screen))
+        if (!v3d_get_device_info(screen))
                 goto fail;
 
-        slab_create_parent(&screen->transfer_pool, sizeof(struct vc5_transfer), 16);
+        slab_create_parent(&screen->transfer_pool, sizeof(struct v3d_transfer), 16);
 
-        vc5_fence_init(screen);
+        v3d_fence_init(screen);
 
         v3d_process_debug_variable();
 
-        vc5_resource_screen_init(pscreen);
+        v3d_resource_screen_init(pscreen);
 
         screen->compiler = v3d_compiler_init(&screen->devinfo);
 
-        pscreen->get_name = vc5_screen_get_name;
-        pscreen->get_vendor = vc5_screen_get_vendor;
-        pscreen->get_device_vendor = vc5_screen_get_vendor;
-        pscreen->get_compiler_options = vc5_screen_get_compiler_options;
+        pscreen->get_name = v3d_screen_get_name;
+        pscreen->get_vendor = v3d_screen_get_vendor;
+        pscreen->get_device_vendor = v3d_screen_get_vendor;
+        pscreen->get_compiler_options = v3d_screen_get_compiler_options;
 
         return pscreen;