diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile index c877a21a0739..5c3515e8cce1 100644 --- a/drivers/gpu/drm/vmwgfx/Makefile +++ b/drivers/gpu/drm/vmwgfx/Makefile @@ -8,7 +8,7 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \ vmwgfx_cmdbuf_res.o vmwgfx_cmdbuf.o vmwgfx_stdu.o \ vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o vmwgfx_msg.o \ vmwgfx_simple_resource.o vmwgfx_va.o vmwgfx_blit.o \ - vmwgfx_validation.o vmwgfx_page_dirty.o \ + vmwgfx_validation.o vmwgfx_page_dirty.o vmwgfx_streamoutput.o \ ttm_object.o ttm_lock.o obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h index 9cbba0e8ce6a..799bc0963f7a 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /********************************************************** - * Copyright 1998-2015 VMware, Inc. + * Copyright 1998-2020 VMware, Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -104,12 +104,12 @@ typedef enum { SVGA_3D_CMD_DEAD1 = 1083, SVGA_3D_CMD_DEAD2 = 1084, - SVGA_3D_CMD_LOGICOPS_BITBLT = 1085, - SVGA_3D_CMD_LOGICOPS_TRANSBLT = 1086, - SVGA_3D_CMD_LOGICOPS_STRETCHBLT = 1087, - SVGA_3D_CMD_LOGICOPS_COLORFILL = 1088, - SVGA_3D_CMD_LOGICOPS_ALPHABLEND = 1089, - SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND = 1090, + SVGA_3D_CMD_DEAD12 = 1085, + SVGA_3D_CMD_DEAD13 = 1086, + SVGA_3D_CMD_DEAD14 = 1087, + SVGA_3D_CMD_DEAD15 = 1088, + SVGA_3D_CMD_DEAD16 = 1089, + SVGA_3D_CMD_DEAD17 = 1090, SVGA_3D_CMD_SET_OTABLE_BASE = 1091, SVGA_3D_CMD_READBACK_OTABLE = 1092, @@ -261,30 +261,23 @@ typedef enum { SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET = 1220, SVGA_3D_CMD_DX_SET_PS_CONSTANT_BUFFER_OFFSET = 1221, SVGA_3D_CMD_DX_SET_GS_CONSTANT_BUFFER_OFFSET = 1222, - - /* - * Reserve some IDs to be used for the SM5 shader types. - */ - SVGA_3D_CMD_DX_RESERVED1 = 1223, - SVGA_3D_CMD_DX_RESERVED2 = 1224, - SVGA_3D_CMD_DX_RESERVED3 = 1225, + SVGA_3D_CMD_DX_SET_HS_CONSTANT_BUFFER_OFFSET = 1223, + SVGA_3D_CMD_DX_SET_DS_CONSTANT_BUFFER_OFFSET = 1224, + SVGA_3D_CMD_DX_SET_CS_CONSTANT_BUFFER_OFFSET = 1225, SVGA_3D_CMD_DX_COND_BIND_ALL_SHADER = 1226, SVGA_3D_CMD_DX_MAX = 1227, SVGA_3D_CMD_SCREEN_COPY = 1227, - /* - * Reserve some IDs to be used for video. - */ - SVGA_3D_CMD_VIDEO_RESERVED1 = 1228, - SVGA_3D_CMD_VIDEO_RESERVED2 = 1229, - SVGA_3D_CMD_VIDEO_RESERVED3 = 1230, - SVGA_3D_CMD_VIDEO_RESERVED4 = 1231, - SVGA_3D_CMD_VIDEO_RESERVED5 = 1232, - SVGA_3D_CMD_VIDEO_RESERVED6 = 1233, - SVGA_3D_CMD_VIDEO_RESERVED7 = 1234, - SVGA_3D_CMD_VIDEO_RESERVED8 = 1235, + SVGA_3D_CMD_RESERVED1 = 1228, + SVGA_3D_CMD_RESERVED2 = 1229, + SVGA_3D_CMD_RESERVED3 = 1230, + SVGA_3D_CMD_RESERVED4 = 1231, + SVGA_3D_CMD_RESERVED5 = 1232, + SVGA_3D_CMD_RESERVED6 = 1233, + SVGA_3D_CMD_RESERVED7 = 1234, + SVGA_3D_CMD_RESERVED8 = 1235, SVGA_3D_CMD_GROW_OTABLE = 1236, SVGA_3D_CMD_DX_GROW_COTABLE = 1237, @@ -298,7 +291,46 @@ typedef enum { SVGA_3D_CMD_DX_PRED_CONVERT = 1243, SVGA_3D_CMD_WHOLE_SURFACE_COPY = 1244, - SVGA_3D_CMD_MAX = 1245, + SVGA_3D_CMD_DX_DEFINE_UA_VIEW = 1245, + SVGA_3D_CMD_DX_DESTROY_UA_VIEW = 1246, + SVGA_3D_CMD_DX_CLEAR_UA_VIEW_UINT = 1247, + SVGA_3D_CMD_DX_CLEAR_UA_VIEW_FLOAT = 1248, + SVGA_3D_CMD_DX_COPY_STRUCTURE_COUNT = 1249, + SVGA_3D_CMD_DX_SET_UA_VIEWS = 1250, + + SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED_INDIRECT = 1251, + SVGA_3D_CMD_DX_DRAW_INSTANCED_INDIRECT = 1252, + SVGA_3D_CMD_DX_DISPATCH = 1253, + SVGA_3D_CMD_DX_DISPATCH_INDIRECT = 1254, + + SVGA_3D_CMD_WRITE_ZERO_SURFACE = 1255, + SVGA_3D_CMD_HINT_ZERO_SURFACE = 1256, + SVGA_3D_CMD_DX_TRANSFER_TO_BUFFER = 1257, + SVGA_3D_CMD_DX_SET_STRUCTURE_COUNT = 1258, + + SVGA_3D_CMD_LOGICOPS_BITBLT = 1259, + SVGA_3D_CMD_LOGICOPS_TRANSBLT = 1260, + SVGA_3D_CMD_LOGICOPS_STRETCHBLT = 1261, + SVGA_3D_CMD_LOGICOPS_COLORFILL = 1262, + SVGA_3D_CMD_LOGICOPS_ALPHABLEND = 1263, + SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND = 1264, + + SVGA_3D_CMD_RESERVED2_1 = 1265, + + SVGA_3D_CMD_RESERVED2_2 = 1266, + SVGA_3D_CMD_DEFINE_GB_SURFACE_V4 = 1267, + SVGA_3D_CMD_DX_SET_CS_UA_VIEWS = 1268, + SVGA_3D_CMD_DX_SET_MIN_LOD = 1269, + SVGA_3D_CMD_RESERVED2_3 = 1270, + SVGA_3D_CMD_RESERVED2_4 = 1271, + SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW_V2 = 1272, + SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT_WITH_MOB = 1273, + SVGA_3D_CMD_DX_SET_SHADER_IFACE = 1274, + SVGA_3D_CMD_DX_BIND_STREAMOUTPUT = 1275, + SVGA_3D_CMD_SURFACE_STRETCHBLT_NON_MS_TO_MS = 1276, + SVGA_3D_CMD_DX_BIND_SHADER_IFACE = 1277, + + SVGA_3D_CMD_MAX = 1278, SVGA_3D_CMD_FUTURE_MAX = 3000 } SVGAFifo3dCmdId; @@ -334,6 +366,7 @@ struct { uint32 sid; SVGA3dSurface1Flags surfaceFlags; SVGA3dSurfaceFormat format; + /* * If surfaceFlags has SVGA3D_SURFACE_CUBEMAP bit set, all SVGA3dSurfaceFace * structures must have the same value of numMipLevels field. @@ -341,6 +374,7 @@ struct { * numMipLevels set to 0. */ SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES]; + /* * Followed by an SVGA3dSize structure for each mip level in each face. * @@ -360,6 +394,7 @@ struct { uint32 sid; SVGA3dSurface1Flags surfaceFlags; SVGA3dSurfaceFormat format; + /* * If surfaceFlags has SVGA3D_SURFACE_CUBEMAP bit set, all SVGA3dSurfaceFace * structures must have the same value of numMipLevels field. @@ -369,6 +404,7 @@ struct { SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES]; uint32 multisampleCount; SVGA3dTextureFilter autogenFilter; + /* * Followed by an SVGA3dSize structure for each mip level in each face. * @@ -512,6 +548,18 @@ struct { #include "vmware_pack_end.h" SVGA3dCmdWholeSurfaceCopy; /* SVGA_3D_CMD_WHOLE_SURFACE_COPY */ +typedef +#include "vmware_pack_begin.h" +struct { + SVGA3dSurfaceImageId src; + SVGA3dSurfaceImageId dest; + SVGA3dBox boxSrc; + SVGA3dBox boxDest; +} +#include "vmware_pack_end.h" +SVGA3dCmdSurfaceStretchBltNonMSToMS; +/* SVGA_3D_CMD_SURFACE_STRETCHBLT_NON_MS_TO_MS */ + typedef #include "vmware_pack_begin.h" struct { @@ -555,6 +603,7 @@ struct { SVGAGuestImage guest; SVGA3dSurfaceImageId host; SVGA3dTransferType transfer; + /* * Followed by variable number of SVGA3dCopyBox structures. For consistency * in all clipping logic and coordinate translation, we define the @@ -789,7 +838,7 @@ struct { uint32 indexBufferSid; /* Valid index buffer sid. */ uint32 indexBufferOffset; /* Byte offset into the vertex buffer, almost */ - /* always 0 for DX9 guests, non-zero for OpenGL */ + /* always 0 for pre SM guests, non-zero for OpenGL */ /* guests. We can't represent non-multiple of */ /* stride offsets in D3D9Renderer... */ uint8 indexBufferStride; /* Allowable values = 1, 2, or 4 */ @@ -1228,6 +1277,7 @@ struct SVGA3dCmdLogicOpsBitBlt { SVGA3dSurfaceImageId src; SVGA3dSurfaceImageId dst; SVGA3dLogicOp logicOp; + SVGA3dLogicOpRop3 logicOpRop3; /* Followed by variable number of SVGA3dCopyBox structures */ } #include "vmware_pack_end.h" @@ -1247,7 +1297,8 @@ struct SVGA3dCmdLogicOpsTransBlt { uint32 color; uint32 flags; SVGA3dBox srcBox; - SVGA3dBox dstBox; + SVGA3dSignedBox dstBox; + SVGA3dBox clipBox; } #include "vmware_pack_end.h" SVGA3dCmdLogicOpsTransBlt; /* SVGA_3D_CMD_LOGICOPS_TRANSBLT */ @@ -1266,7 +1317,8 @@ struct SVGA3dCmdLogicOpsStretchBlt { uint16 mode; uint16 flags; SVGA3dBox srcBox; - SVGA3dBox dstBox; + SVGA3dSignedBox dstBox; + SVGA3dBox clipBox; } #include "vmware_pack_end.h" SVGA3dCmdLogicOpsStretchBlt; /* SVGA_3D_CMD_LOGICOPS_STRETCHBLT */ @@ -1283,6 +1335,7 @@ struct SVGA3dCmdLogicOpsColorFill { SVGA3dSurfaceImageId dst; uint32 color; SVGA3dLogicOp logicOp; + SVGA3dLogicOpRop3 logicOpRop3; /* Followed by variable number of SVGA3dRect structures. */ } #include "vmware_pack_end.h" @@ -1302,7 +1355,8 @@ struct SVGA3dCmdLogicOpsAlphaBlend { uint32 alphaVal; uint32 flags; SVGA3dBox srcBox; - SVGA3dBox dstBox; + SVGA3dSignedBox dstBox; + SVGA3dBox clipBox; } #include "vmware_pack_end.h" SVGA3dCmdLogicOpsAlphaBlend; /* SVGA_3D_CMD_LOGICOPS_ALPHABLEND */ @@ -1365,8 +1419,9 @@ struct { SVGA3dSurface2Flags surface2Flags; uint8 multisamplePattern; uint8 qualityLevel; - uint8 pad0[2]; - uint32 pad1[3]; + uint16 bufferByteStride; + float minLOD; + uint32 pad0[2]; } #include "vmware_pack_end.h" SVGAOTableSurfaceEntry; @@ -1543,7 +1598,7 @@ typedef #include "vmware_pack_begin.h" struct { SVGAOTableType type; - PPN baseAddress; + PPN32 baseAddress; uint32 sizeInBytes; uint32 validSizeInBytes; SVGAMobFormat ptDepth; @@ -1599,7 +1654,7 @@ typedef struct SVGA3dCmdDefineGBMob { SVGAMobId mobid; SVGAMobFormat ptDepth; - PPN base; + PPN32 base; uint32 sizeInBytes; } #include "vmware_pack_end.h" @@ -1618,7 +1673,6 @@ struct SVGA3dCmdDestroyGBMob { #include "vmware_pack_end.h" SVGA3dCmdDestroyGBMob; /* SVGA_3D_CMD_DESTROY_GB_MOB */ - /* * Define a memory object (Mob) in the OTable with a PPN64 base. */ @@ -1718,6 +1772,27 @@ struct SVGA3dCmdDefineGBSurface_v3 { #include "vmware_pack_end.h" SVGA3dCmdDefineGBSurface_v3; /* SVGA_3D_CMD_DEFINE_GB_SURFACE_V3 */ +/* + * Defines a guest-backed surface, adding buffer byte stride. + */ +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDefineGBSurface_v4 { + uint32 sid; + SVGA3dSurfaceAllFlags surfaceFlags; + SVGA3dSurfaceFormat format; + uint32 numMipLevels; + uint32 multisampleCount; + SVGA3dMSPattern multisamplePattern; + SVGA3dMSQualityLevel qualityLevel; + SVGA3dTextureFilter autogenFilter; + SVGA3dSize size; + uint32 arraySize; + uint32 bufferByteStride; +} +#include "vmware_pack_end.h" +SVGA3dCmdDefineGBSurface_v4; /* SVGA_3D_CMD_DEFINE_GB_SURFACE_V4 */ + /* * Destroy a guest-backed surface. */ @@ -2181,4 +2256,20 @@ SVGA3dCmdScreenCopy; /* SVGA_3D_CMD_SCREEN_COPY */ #define SVGA_SCREEN_COPY_STATUS_SUCCESS 0x01 #define SVGA_SCREEN_COPY_STATUS_INVALID 0xFFFFFFFF +typedef +#include "vmware_pack_begin.h" +struct { + uint32 sid; +} +#include "vmware_pack_end.h" +SVGA3dCmdWriteZeroSurface; /* SVGA_3D_CMD_WRITE_ZERO_SURFACE */ + +typedef +#include "vmware_pack_begin.h" +struct { + uint32 sid; +} +#include "vmware_pack_end.h" +SVGA3dCmdHintZeroSurface; /* SVGA_3D_CMD_HINT_ZERO_SURFACE */ + #endif /* _SVGA3D_CMD_H_ */ diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_devcaps.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_devcaps.h index f256560049bf..617b468c626c 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_devcaps.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_devcaps.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /********************************************************** - * Copyright 1998-2015 VMware, Inc. + * Copyright 1998-2019 VMware, Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -39,6 +39,8 @@ #include "includeCheck.h" +#include "svga3d_types.h" + /* * 3D Hardware Version * @@ -69,381 +71,408 @@ typedef enum { * DevCap indexes. */ -typedef enum { - SVGA3D_DEVCAP_INVALID = ((uint32)-1), - SVGA3D_DEVCAP_3D = 0, - SVGA3D_DEVCAP_MAX_LIGHTS = 1, +typedef uint32 SVGA3dDevCapIndex; - /* - * SVGA3D_DEVCAP_MAX_TEXTURES reflects the maximum number of - * fixed-function texture units available. Each of these units - * work in both FFP and Shader modes, and they support texture - * transforms and texture coordinates. The host may have additional - * texture image units that are only usable with shaders. - */ - SVGA3D_DEVCAP_MAX_TEXTURES = 2, - SVGA3D_DEVCAP_MAX_CLIP_PLANES = 3, - SVGA3D_DEVCAP_VERTEX_SHADER_VERSION = 4, - SVGA3D_DEVCAP_VERTEX_SHADER = 5, - SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION = 6, - SVGA3D_DEVCAP_FRAGMENT_SHADER = 7, - SVGA3D_DEVCAP_MAX_RENDER_TARGETS = 8, - SVGA3D_DEVCAP_S23E8_TEXTURES = 9, - SVGA3D_DEVCAP_S10E5_TEXTURES = 10, - SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND = 11, - SVGA3D_DEVCAP_D16_BUFFER_FORMAT = 12, - SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT = 13, - SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT = 14, - SVGA3D_DEVCAP_QUERY_TYPES = 15, - SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING = 16, - SVGA3D_DEVCAP_MAX_POINT_SIZE = 17, - SVGA3D_DEVCAP_MAX_SHADER_TEXTURES = 18, - SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH = 19, - SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT = 20, - SVGA3D_DEVCAP_MAX_VOLUME_EXTENT = 21, - SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT = 22, - SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO = 23, - SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY = 24, - SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT = 25, - SVGA3D_DEVCAP_MAX_VERTEX_INDEX = 26, - SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS = 27, - SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS = 28, - SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS = 29, - SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS = 30, - SVGA3D_DEVCAP_TEXTURE_OPS = 31, - SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8 = 32, - SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8 = 33, - SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10 = 34, - SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5 = 35, - SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5 = 36, - SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4 = 37, - SVGA3D_DEVCAP_SURFACEFMT_R5G6B5 = 38, - SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16 = 39, - SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8 = 40, - SVGA3D_DEVCAP_SURFACEFMT_ALPHA8 = 41, - SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8 = 42, - SVGA3D_DEVCAP_SURFACEFMT_Z_D16 = 43, - SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8 = 44, - SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8 = 45, - SVGA3D_DEVCAP_SURFACEFMT_DXT1 = 46, - SVGA3D_DEVCAP_SURFACEFMT_DXT2 = 47, - SVGA3D_DEVCAP_SURFACEFMT_DXT3 = 48, - SVGA3D_DEVCAP_SURFACEFMT_DXT4 = 49, - SVGA3D_DEVCAP_SURFACEFMT_DXT5 = 50, - SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8 = 51, - SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10 = 52, - SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8 = 53, - SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8 = 54, - SVGA3D_DEVCAP_SURFACEFMT_CxV8U8 = 55, - SVGA3D_DEVCAP_SURFACEFMT_R_S10E5 = 56, - SVGA3D_DEVCAP_SURFACEFMT_R_S23E8 = 57, - SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5 = 58, - SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8 = 59, - SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5 = 60, - SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8 = 61, +#define SVGA3D_DEVCAP_INVALID ((uint32)-1) +#define SVGA3D_DEVCAP_3D 0 +#define SVGA3D_DEVCAP_MAX_LIGHTS 1 - /* - * There is a hole in our devcap definitions for - * historical reasons. - * - * Define a constant just for completeness. - */ - SVGA3D_DEVCAP_MISSING62 = 62, +/* + * SVGA3D_DEVCAP_MAX_TEXTURES reflects the maximum number of + * fixed-function texture units available. Each of these units + * work in both FFP and Shader modes, and they support texture + * transforms and texture coordinates. The host may have additional + * texture image units that are only usable with shaders. + */ +#define SVGA3D_DEVCAP_MAX_TEXTURES 2 +#define SVGA3D_DEVCAP_MAX_CLIP_PLANES 3 +#define SVGA3D_DEVCAP_VERTEX_SHADER_VERSION 4 +#define SVGA3D_DEVCAP_VERTEX_SHADER 5 +#define SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION 6 +#define SVGA3D_DEVCAP_FRAGMENT_SHADER 7 +#define SVGA3D_DEVCAP_MAX_RENDER_TARGETS 8 +#define SVGA3D_DEVCAP_S23E8_TEXTURES 9 +#define SVGA3D_DEVCAP_S10E5_TEXTURES 10 +#define SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND 11 +#define SVGA3D_DEVCAP_D16_BUFFER_FORMAT 12 +#define SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT 13 +#define SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT 14 +#define SVGA3D_DEVCAP_QUERY_TYPES 15 +#define SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING 16 +#define SVGA3D_DEVCAP_MAX_POINT_SIZE 17 +#define SVGA3D_DEVCAP_MAX_SHADER_TEXTURES 18 +#define SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH 19 +#define SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT 20 +#define SVGA3D_DEVCAP_MAX_VOLUME_EXTENT 21 +#define SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT 22 +#define SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO 23 +#define SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY 24 +#define SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT 25 +#define SVGA3D_DEVCAP_MAX_VERTEX_INDEX 26 +#define SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS 27 +#define SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS 28 +#define SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS 29 +#define SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS 30 +#define SVGA3D_DEVCAP_TEXTURE_OPS 31 +#define SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8 32 +#define SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8 33 +#define SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10 34 +#define SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5 35 +#define SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5 36 +#define SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4 37 +#define SVGA3D_DEVCAP_SURFACEFMT_R5G6B5 38 +#define SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16 39 +#define SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8 40 +#define SVGA3D_DEVCAP_SURFACEFMT_ALPHA8 41 +#define SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8 42 +#define SVGA3D_DEVCAP_SURFACEFMT_Z_D16 43 +#define SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8 44 +#define SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8 45 +#define SVGA3D_DEVCAP_SURFACEFMT_DXT1 46 +#define SVGA3D_DEVCAP_SURFACEFMT_DXT2 47 +#define SVGA3D_DEVCAP_SURFACEFMT_DXT3 48 +#define SVGA3D_DEVCAP_SURFACEFMT_DXT4 49 +#define SVGA3D_DEVCAP_SURFACEFMT_DXT5 50 +#define SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8 51 +#define SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10 52 +#define SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8 53 +#define SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8 54 +#define SVGA3D_DEVCAP_SURFACEFMT_CxV8U8 55 +#define SVGA3D_DEVCAP_SURFACEFMT_R_S10E5 56 +#define SVGA3D_DEVCAP_SURFACEFMT_R_S23E8 57 +#define SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5 58 +#define SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8 59 +#define SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5 60 +#define SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8 61 - SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES = 63, +/* + * There is a hole in our devcap definitions for + * historical reasons. + * + * Define a constant just for completeness. + */ +#define SVGA3D_DEVCAP_MISSING62 62 - /* - * Note that MAX_SIMULTANEOUS_RENDER_TARGETS is a maximum count of color - * render targets. This does not include the depth or stencil targets. - */ - SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS = 64, +#define SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES 63 - SVGA3D_DEVCAP_SURFACEFMT_V16U16 = 65, - SVGA3D_DEVCAP_SURFACEFMT_G16R16 = 66, - SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16 = 67, - SVGA3D_DEVCAP_SURFACEFMT_UYVY = 68, - SVGA3D_DEVCAP_SURFACEFMT_YUY2 = 69, - SVGA3D_DEVCAP_MULTISAMPLE_NONMASKABLESAMPLES = 70, - SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES = 71, - SVGA3D_DEVCAP_ALPHATOCOVERAGE = 72, - SVGA3D_DEVCAP_SUPERSAMPLE = 73, - SVGA3D_DEVCAP_AUTOGENMIPMAPS = 74, - SVGA3D_DEVCAP_SURFACEFMT_NV12 = 75, - SVGA3D_DEVCAP_SURFACEFMT_AYUV = 76, +/* + * Note that MAX_SIMULTANEOUS_RENDER_TARGETS is a maximum count of color + * render targets. This does not include the depth or stencil targets. + */ +#define SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS 64 - /* - * This is the maximum number of SVGA context IDs that the guest - * can define using SVGA_3D_CMD_CONTEXT_DEFINE. - */ - SVGA3D_DEVCAP_MAX_CONTEXT_IDS = 77, +#define SVGA3D_DEVCAP_SURFACEFMT_V16U16 65 +#define SVGA3D_DEVCAP_SURFACEFMT_G16R16 66 +#define SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16 67 +#define SVGA3D_DEVCAP_SURFACEFMT_UYVY 68 +#define SVGA3D_DEVCAP_SURFACEFMT_YUY2 69 - /* - * This is the maximum number of SVGA surface IDs that the guest - * can define using SVGA_3D_CMD_SURFACE_DEFINE*. - */ - SVGA3D_DEVCAP_MAX_SURFACE_IDS = 78, +/* + * Deprecated. + */ +#define SVGA3D_DEVCAP_DEAD4 70 +#define SVGA3D_DEVCAP_DEAD5 71 +#define SVGA3D_DEVCAP_DEAD7 72 +#define SVGA3D_DEVCAP_DEAD6 73 - SVGA3D_DEVCAP_SURFACEFMT_Z_DF16 = 79, - SVGA3D_DEVCAP_SURFACEFMT_Z_DF24 = 80, - SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT = 81, +#define SVGA3D_DEVCAP_AUTOGENMIPMAPS 74 +#define SVGA3D_DEVCAP_SURFACEFMT_NV12 75 +#define SVGA3D_DEVCAP_DEAD10 76 - SVGA3D_DEVCAP_SURFACEFMT_ATI1 = 82, - SVGA3D_DEVCAP_SURFACEFMT_ATI2 = 83, +/* + * This is the maximum number of SVGA context IDs that the guest + * can define using SVGA_3D_CMD_CONTEXT_DEFINE. + */ +#define SVGA3D_DEVCAP_MAX_CONTEXT_IDS 77 - /* - * Deprecated. - */ - SVGA3D_DEVCAP_DEAD1 = 84, +/* + * This is the maximum number of SVGA surface IDs that the guest + * can define using SVGA_3D_CMD_SURFACE_DEFINE*. + */ +#define SVGA3D_DEVCAP_MAX_SURFACE_IDS 78 - /* - * This contains several SVGA_3D_CAPS_VIDEO_DECODE elements - * ored together, one for every type of video decoding supported. - */ - SVGA3D_DEVCAP_VIDEO_DECODE = 85, +#define SVGA3D_DEVCAP_SURFACEFMT_Z_DF16 79 +#define SVGA3D_DEVCAP_SURFACEFMT_Z_DF24 80 +#define SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT 81 - /* - * This contains several SVGA_3D_CAPS_VIDEO_PROCESS elements - * ored together, one for every type of video processing supported. - */ - SVGA3D_DEVCAP_VIDEO_PROCESS = 86, +#define SVGA3D_DEVCAP_SURFACEFMT_ATI1 82 +#define SVGA3D_DEVCAP_SURFACEFMT_ATI2 83 - SVGA3D_DEVCAP_LINE_AA = 87, /* boolean */ - SVGA3D_DEVCAP_LINE_STIPPLE = 88, /* boolean */ - SVGA3D_DEVCAP_MAX_LINE_WIDTH = 89, /* float */ - SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH = 90, /* float */ +/* + * Deprecated. + */ +#define SVGA3D_DEVCAP_DEAD1 84 +#define SVGA3D_DEVCAP_DEAD8 85 +#define SVGA3D_DEVCAP_DEAD9 86 - SVGA3D_DEVCAP_SURFACEFMT_YV12 = 91, +#define SVGA3D_DEVCAP_LINE_AA 87 /* boolean */ +#define SVGA3D_DEVCAP_LINE_STIPPLE 88 /* boolean */ +#define SVGA3D_DEVCAP_MAX_LINE_WIDTH 89 /* float */ +#define SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH 90 /* float */ - /* - * Does the host support the SVGA logic ops commands? - */ - SVGA3D_DEVCAP_LOGICOPS = 92, +#define SVGA3D_DEVCAP_SURFACEFMT_YV12 91 - /* - * Are TS_CONSTANT, TS_COLOR_KEY, and TS_COLOR_KEY_ENABLE supported? - */ - SVGA3D_DEVCAP_TS_COLOR_KEY = 93, /* boolean */ +/* + * Deprecated. + */ +#define SVGA3D_DEVCAP_DEAD3 92 - /* - * Deprecated. - */ - SVGA3D_DEVCAP_DEAD2 = 94, +/* + * Are TS_CONSTANT, TS_COLOR_KEY, and TS_COLOR_KEY_ENABLE supported? + */ +#define SVGA3D_DEVCAP_TS_COLOR_KEY 93 /* boolean */ - /* - * Does the device support DXContexts? - */ - SVGA3D_DEVCAP_DXCONTEXT = 95, +/* + * Deprecated. + */ +#define SVGA3D_DEVCAP_DEAD2 94 - /* - * What is the maximum size of a texture array? - * - * (Even if this cap is zero, cubemaps are still allowed.) - */ - SVGA3D_DEVCAP_MAX_TEXTURE_ARRAY_SIZE = 96, +/* + * Does the device support DXContexts? + */ +#define SVGA3D_DEVCAP_DXCONTEXT 95 - /* - * What is the maximum number of vertex buffers or vertex input registers - * that can be expected to work correctly with a DXContext? - * - * The guest is allowed to set up to SVGA3D_DX_MAX_VERTEXBUFFERS, but - * anything in excess of this cap is not guaranteed to render correctly. - * - * Similarly, the guest can set up to SVGA3D_DX_MAX_VERTEXINPUTREGISTERS - * input registers without the SVGA3D_DEVCAP_SM4_1 cap, or - * SVGA3D_DX_SM41_MAX_VERTEXINPUTREGISTERS with the SVGA3D_DEVCAP_SM4_1, - * but only the registers up to this cap value are guaranteed to render - * correctly. - * - * If guest-drivers are able to expose a lower-limit, it's recommended - * that they clamp to this value. Otherwise, the host will make a - * best-effort on case-by-case basis if guests exceed this. - */ - SVGA3D_DEVCAP_DX_MAX_VERTEXBUFFERS = 97, +/* + * Deprecated. + */ +#define SVGA3D_DEVCAP_DEAD11 96 - /* - * What is the maximum number of constant buffers that can be expected to - * work correctly with a DX context? - * - * The guest is allowed to set up to SVGA3D_DX_MAX_CONSTBUFFERS, but - * anything in excess of this cap is not guaranteed to render correctly. - * - * If guest-drivers are able to expose a lower-limit, it's recommended - * that they clamp to this value. Otherwise, the host will make a - * best-effort on case-by-case basis if guests exceed this. - */ - SVGA3D_DEVCAP_DX_MAX_CONSTANT_BUFFERS = 98, +/* + * What is the maximum number of vertex buffers or vertex input registers + * that can be expected to work correctly with a DXContext? + * + * The guest is allowed to set up to SVGA3D_DX_MAX_VERTEXBUFFERS, but + * anything in excess of this cap is not guaranteed to render correctly. + * + * Similarly, the guest can set up to SVGA3D_DX_MAX_VERTEXINPUTREGISTERS + * input registers without the SVGA3D_DEVCAP_SM4_1 cap, or + * SVGA3D_DX_SM41_MAX_VERTEXINPUTREGISTERS with the SVGA3D_DEVCAP_SM4_1, + * but only the registers up to this cap value are guaranteed to render + * correctly. + * + * If guest-drivers are able to expose a lower-limit, it's recommended + * that they clamp to this value. Otherwise, the host will make a + * best-effort on case-by-case basis if guests exceed this. + */ +#define SVGA3D_DEVCAP_DX_MAX_VERTEXBUFFERS 97 - /* - * Does the device support provoking vertex control? - * - * If this cap is present, the provokingVertexLast field in the - * rasterizer state is enabled. (Guests can then set it to FALSE, - * meaning that the first vertex is the provoking vertex, or TRUE, - * meaning that the last verteix is the provoking vertex.) - * - * If this cap is FALSE, then guests should set the provokingVertexLast - * to FALSE, otherwise rendering behavior is undefined. - */ - SVGA3D_DEVCAP_DX_PROVOKING_VERTEX = 99, +/* + * What is the maximum number of constant buffers that can be expected to + * work correctly with a DX context? + * + * The guest is allowed to set up to SVGA3D_DX_MAX_CONSTBUFFERS, but + * anything in excess of this cap is not guaranteed to render correctly. + * + * If guest-drivers are able to expose a lower-limit, it's recommended + * that they clamp to this value. Otherwise, the host will make a + * best-effort on case-by-case basis if guests exceed this. + */ +#define SVGA3D_DEVCAP_DX_MAX_CONSTANT_BUFFERS 98 - SVGA3D_DEVCAP_DXFMT_X8R8G8B8 = 100, - SVGA3D_DEVCAP_DXFMT_A8R8G8B8 = 101, - SVGA3D_DEVCAP_DXFMT_R5G6B5 = 102, - SVGA3D_DEVCAP_DXFMT_X1R5G5B5 = 103, - SVGA3D_DEVCAP_DXFMT_A1R5G5B5 = 104, - SVGA3D_DEVCAP_DXFMT_A4R4G4B4 = 105, - SVGA3D_DEVCAP_DXFMT_Z_D32 = 106, - SVGA3D_DEVCAP_DXFMT_Z_D16 = 107, - SVGA3D_DEVCAP_DXFMT_Z_D24S8 = 108, - SVGA3D_DEVCAP_DXFMT_Z_D15S1 = 109, - SVGA3D_DEVCAP_DXFMT_LUMINANCE8 = 110, - SVGA3D_DEVCAP_DXFMT_LUMINANCE4_ALPHA4 = 111, - SVGA3D_DEVCAP_DXFMT_LUMINANCE16 = 112, - SVGA3D_DEVCAP_DXFMT_LUMINANCE8_ALPHA8 = 113, - SVGA3D_DEVCAP_DXFMT_DXT1 = 114, - SVGA3D_DEVCAP_DXFMT_DXT2 = 115, - SVGA3D_DEVCAP_DXFMT_DXT3 = 116, - SVGA3D_DEVCAP_DXFMT_DXT4 = 117, - SVGA3D_DEVCAP_DXFMT_DXT5 = 118, - SVGA3D_DEVCAP_DXFMT_BUMPU8V8 = 119, - SVGA3D_DEVCAP_DXFMT_BUMPL6V5U5 = 120, - SVGA3D_DEVCAP_DXFMT_BUMPX8L8V8U8 = 121, - SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD1 = 122, - SVGA3D_DEVCAP_DXFMT_ARGB_S10E5 = 123, - SVGA3D_DEVCAP_DXFMT_ARGB_S23E8 = 124, - SVGA3D_DEVCAP_DXFMT_A2R10G10B10 = 125, - SVGA3D_DEVCAP_DXFMT_V8U8 = 126, - SVGA3D_DEVCAP_DXFMT_Q8W8V8U8 = 127, - SVGA3D_DEVCAP_DXFMT_CxV8U8 = 128, - SVGA3D_DEVCAP_DXFMT_X8L8V8U8 = 129, - SVGA3D_DEVCAP_DXFMT_A2W10V10U10 = 130, - SVGA3D_DEVCAP_DXFMT_ALPHA8 = 131, - SVGA3D_DEVCAP_DXFMT_R_S10E5 = 132, - SVGA3D_DEVCAP_DXFMT_R_S23E8 = 133, - SVGA3D_DEVCAP_DXFMT_RG_S10E5 = 134, - SVGA3D_DEVCAP_DXFMT_RG_S23E8 = 135, - SVGA3D_DEVCAP_DXFMT_BUFFER = 136, - SVGA3D_DEVCAP_DXFMT_Z_D24X8 = 137, - SVGA3D_DEVCAP_DXFMT_V16U16 = 138, - SVGA3D_DEVCAP_DXFMT_G16R16 = 139, - SVGA3D_DEVCAP_DXFMT_A16B16G16R16 = 140, - SVGA3D_DEVCAP_DXFMT_UYVY = 141, - SVGA3D_DEVCAP_DXFMT_YUY2 = 142, - SVGA3D_DEVCAP_DXFMT_NV12 = 143, - SVGA3D_DEVCAP_DXFMT_AYUV = 144, - SVGA3D_DEVCAP_DXFMT_R32G32B32A32_TYPELESS = 145, - SVGA3D_DEVCAP_DXFMT_R32G32B32A32_UINT = 146, - SVGA3D_DEVCAP_DXFMT_R32G32B32A32_SINT = 147, - SVGA3D_DEVCAP_DXFMT_R32G32B32_TYPELESS = 148, - SVGA3D_DEVCAP_DXFMT_R32G32B32_FLOAT = 149, - SVGA3D_DEVCAP_DXFMT_R32G32B32_UINT = 150, - SVGA3D_DEVCAP_DXFMT_R32G32B32_SINT = 151, - SVGA3D_DEVCAP_DXFMT_R16G16B16A16_TYPELESS = 152, - SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UINT = 153, - SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SNORM = 154, - SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SINT = 155, - SVGA3D_DEVCAP_DXFMT_R32G32_TYPELESS = 156, - SVGA3D_DEVCAP_DXFMT_R32G32_UINT = 157, - SVGA3D_DEVCAP_DXFMT_R32G32_SINT = 158, - SVGA3D_DEVCAP_DXFMT_R32G8X24_TYPELESS = 159, - SVGA3D_DEVCAP_DXFMT_D32_FLOAT_S8X24_UINT = 160, - SVGA3D_DEVCAP_DXFMT_R32_FLOAT_X8X24 = 161, - SVGA3D_DEVCAP_DXFMT_X32_G8X24_UINT = 162, - SVGA3D_DEVCAP_DXFMT_R10G10B10A2_TYPELESS = 163, - SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UINT = 164, - SVGA3D_DEVCAP_DXFMT_R11G11B10_FLOAT = 165, - SVGA3D_DEVCAP_DXFMT_R8G8B8A8_TYPELESS = 166, - SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM = 167, - SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM_SRGB = 168, - SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UINT = 169, - SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SINT = 170, - SVGA3D_DEVCAP_DXFMT_R16G16_TYPELESS = 171, - SVGA3D_DEVCAP_DXFMT_R16G16_UINT = 172, - SVGA3D_DEVCAP_DXFMT_R16G16_SINT = 173, - SVGA3D_DEVCAP_DXFMT_R32_TYPELESS = 174, - SVGA3D_DEVCAP_DXFMT_D32_FLOAT = 175, - SVGA3D_DEVCAP_DXFMT_R32_UINT = 176, - SVGA3D_DEVCAP_DXFMT_R32_SINT = 177, - SVGA3D_DEVCAP_DXFMT_R24G8_TYPELESS = 178, - SVGA3D_DEVCAP_DXFMT_D24_UNORM_S8_UINT = 179, - SVGA3D_DEVCAP_DXFMT_R24_UNORM_X8 = 180, - SVGA3D_DEVCAP_DXFMT_X24_G8_UINT = 181, - SVGA3D_DEVCAP_DXFMT_R8G8_TYPELESS = 182, - SVGA3D_DEVCAP_DXFMT_R8G8_UNORM = 183, - SVGA3D_DEVCAP_DXFMT_R8G8_UINT = 184, - SVGA3D_DEVCAP_DXFMT_R8G8_SINT = 185, - SVGA3D_DEVCAP_DXFMT_R16_TYPELESS = 186, - SVGA3D_DEVCAP_DXFMT_R16_UNORM = 187, - SVGA3D_DEVCAP_DXFMT_R16_UINT = 188, - SVGA3D_DEVCAP_DXFMT_R16_SNORM = 189, - SVGA3D_DEVCAP_DXFMT_R16_SINT = 190, - SVGA3D_DEVCAP_DXFMT_R8_TYPELESS = 191, - SVGA3D_DEVCAP_DXFMT_R8_UNORM = 192, - SVGA3D_DEVCAP_DXFMT_R8_UINT = 193, - SVGA3D_DEVCAP_DXFMT_R8_SNORM = 194, - SVGA3D_DEVCAP_DXFMT_R8_SINT = 195, - SVGA3D_DEVCAP_DXFMT_P8 = 196, - SVGA3D_DEVCAP_DXFMT_R9G9B9E5_SHAREDEXP = 197, - SVGA3D_DEVCAP_DXFMT_R8G8_B8G8_UNORM = 198, - SVGA3D_DEVCAP_DXFMT_G8R8_G8B8_UNORM = 199, - SVGA3D_DEVCAP_DXFMT_BC1_TYPELESS = 200, - SVGA3D_DEVCAP_DXFMT_BC1_UNORM_SRGB = 201, - SVGA3D_DEVCAP_DXFMT_BC2_TYPELESS = 202, - SVGA3D_DEVCAP_DXFMT_BC2_UNORM_SRGB = 203, - SVGA3D_DEVCAP_DXFMT_BC3_TYPELESS = 204, - SVGA3D_DEVCAP_DXFMT_BC3_UNORM_SRGB = 205, - SVGA3D_DEVCAP_DXFMT_BC4_TYPELESS = 206, - SVGA3D_DEVCAP_DXFMT_ATI1 = 207, - SVGA3D_DEVCAP_DXFMT_BC4_SNORM = 208, - SVGA3D_DEVCAP_DXFMT_BC5_TYPELESS = 209, - SVGA3D_DEVCAP_DXFMT_ATI2 = 210, - SVGA3D_DEVCAP_DXFMT_BC5_SNORM = 211, - SVGA3D_DEVCAP_DXFMT_R10G10B10_XR_BIAS_A2_UNORM = 212, - SVGA3D_DEVCAP_DXFMT_B8G8R8A8_TYPELESS = 213, - SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM_SRGB = 214, - SVGA3D_DEVCAP_DXFMT_B8G8R8X8_TYPELESS = 215, - SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM_SRGB = 216, - SVGA3D_DEVCAP_DXFMT_Z_DF16 = 217, - SVGA3D_DEVCAP_DXFMT_Z_DF24 = 218, - SVGA3D_DEVCAP_DXFMT_Z_D24S8_INT = 219, - SVGA3D_DEVCAP_DXFMT_YV12 = 220, - SVGA3D_DEVCAP_DXFMT_R32G32B32A32_FLOAT = 221, - SVGA3D_DEVCAP_DXFMT_R16G16B16A16_FLOAT = 222, - SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UNORM = 223, - SVGA3D_DEVCAP_DXFMT_R32G32_FLOAT = 224, - SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UNORM = 225, - SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SNORM = 226, - SVGA3D_DEVCAP_DXFMT_R16G16_FLOAT = 227, - SVGA3D_DEVCAP_DXFMT_R16G16_UNORM = 228, - SVGA3D_DEVCAP_DXFMT_R16G16_SNORM = 229, - SVGA3D_DEVCAP_DXFMT_R32_FLOAT = 230, - SVGA3D_DEVCAP_DXFMT_R8G8_SNORM = 231, - SVGA3D_DEVCAP_DXFMT_R16_FLOAT = 232, - SVGA3D_DEVCAP_DXFMT_D16_UNORM = 233, - SVGA3D_DEVCAP_DXFMT_A8_UNORM = 234, - SVGA3D_DEVCAP_DXFMT_BC1_UNORM = 235, - SVGA3D_DEVCAP_DXFMT_BC2_UNORM = 236, - SVGA3D_DEVCAP_DXFMT_BC3_UNORM = 237, - SVGA3D_DEVCAP_DXFMT_B5G6R5_UNORM = 238, - SVGA3D_DEVCAP_DXFMT_B5G5R5A1_UNORM = 239, - SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM = 240, - SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM = 241, - SVGA3D_DEVCAP_DXFMT_BC4_UNORM = 242, - SVGA3D_DEVCAP_DXFMT_BC5_UNORM = 243, +/* + * Does the device support provoking vertex control? + * + * If this cap is present, the provokingVertexLast field in the + * rasterizer state is enabled. (Guests can then set it to FALSE, + * meaning that the first vertex is the provoking vertex, or TRUE, + * meaning that the last verteix is the provoking vertex.) + * + * If this cap is FALSE, then guests should set the provokingVertexLast + * to FALSE, otherwise rendering behavior is undefined. + */ +#define SVGA3D_DEVCAP_DX_PROVOKING_VERTEX 99 - /* - * Advertises shaderModel 4.1 support, independent blend-states, - * cube-map arrays, and a higher vertex input registers limit. - * - * (See documentation on SVGA3D_DEVCAP_DX_MAX_VERTEXBUFFERS.) - */ - SVGA3D_DEVCAP_SM41 = 244, +#define SVGA3D_DEVCAP_DXFMT_X8R8G8B8 100 +#define SVGA3D_DEVCAP_DXFMT_A8R8G8B8 101 +#define SVGA3D_DEVCAP_DXFMT_R5G6B5 102 +#define SVGA3D_DEVCAP_DXFMT_X1R5G5B5 103 +#define SVGA3D_DEVCAP_DXFMT_A1R5G5B5 104 +#define SVGA3D_DEVCAP_DXFMT_A4R4G4B4 105 +#define SVGA3D_DEVCAP_DXFMT_Z_D32 106 +#define SVGA3D_DEVCAP_DXFMT_Z_D16 107 +#define SVGA3D_DEVCAP_DXFMT_Z_D24S8 108 +#define SVGA3D_DEVCAP_DXFMT_Z_D15S1 109 +#define SVGA3D_DEVCAP_DXFMT_LUMINANCE8 110 +#define SVGA3D_DEVCAP_DXFMT_LUMINANCE4_ALPHA4 111 +#define SVGA3D_DEVCAP_DXFMT_LUMINANCE16 112 +#define SVGA3D_DEVCAP_DXFMT_LUMINANCE8_ALPHA8 113 +#define SVGA3D_DEVCAP_DXFMT_DXT1 114 +#define SVGA3D_DEVCAP_DXFMT_DXT2 115 +#define SVGA3D_DEVCAP_DXFMT_DXT3 116 +#define SVGA3D_DEVCAP_DXFMT_DXT4 117 +#define SVGA3D_DEVCAP_DXFMT_DXT5 118 +#define SVGA3D_DEVCAP_DXFMT_BUMPU8V8 119 +#define SVGA3D_DEVCAP_DXFMT_BUMPL6V5U5 120 +#define SVGA3D_DEVCAP_DXFMT_BUMPX8L8V8U8 121 +#define SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD1 122 +#define SVGA3D_DEVCAP_DXFMT_ARGB_S10E5 123 +#define SVGA3D_DEVCAP_DXFMT_ARGB_S23E8 124 +#define SVGA3D_DEVCAP_DXFMT_A2R10G10B10 125 +#define SVGA3D_DEVCAP_DXFMT_V8U8 126 +#define SVGA3D_DEVCAP_DXFMT_Q8W8V8U8 127 +#define SVGA3D_DEVCAP_DXFMT_CxV8U8 128 +#define SVGA3D_DEVCAP_DXFMT_X8L8V8U8 129 +#define SVGA3D_DEVCAP_DXFMT_A2W10V10U10 130 +#define SVGA3D_DEVCAP_DXFMT_ALPHA8 131 +#define SVGA3D_DEVCAP_DXFMT_R_S10E5 132 +#define SVGA3D_DEVCAP_DXFMT_R_S23E8 133 +#define SVGA3D_DEVCAP_DXFMT_RG_S10E5 134 +#define SVGA3D_DEVCAP_DXFMT_RG_S23E8 135 +#define SVGA3D_DEVCAP_DXFMT_BUFFER 136 +#define SVGA3D_DEVCAP_DXFMT_Z_D24X8 137 +#define SVGA3D_DEVCAP_DXFMT_V16U16 138 +#define SVGA3D_DEVCAP_DXFMT_G16R16 139 +#define SVGA3D_DEVCAP_DXFMT_A16B16G16R16 140 +#define SVGA3D_DEVCAP_DXFMT_UYVY 141 +#define SVGA3D_DEVCAP_DXFMT_YUY2 142 +#define SVGA3D_DEVCAP_DXFMT_NV12 143 +#define SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD2 144 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32A32_TYPELESS 145 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32A32_UINT 146 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32A32_SINT 147 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32_TYPELESS 148 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32_FLOAT 149 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32_UINT 150 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32_SINT 151 +#define SVGA3D_DEVCAP_DXFMT_R16G16B16A16_TYPELESS 152 +#define SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UINT 153 +#define SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SNORM 154 +#define SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SINT 155 +#define SVGA3D_DEVCAP_DXFMT_R32G32_TYPELESS 156 +#define SVGA3D_DEVCAP_DXFMT_R32G32_UINT 157 +#define SVGA3D_DEVCAP_DXFMT_R32G32_SINT 158 +#define SVGA3D_DEVCAP_DXFMT_R32G8X24_TYPELESS 159 +#define SVGA3D_DEVCAP_DXFMT_D32_FLOAT_S8X24_UINT 160 +#define SVGA3D_DEVCAP_DXFMT_R32_FLOAT_X8X24 161 +#define SVGA3D_DEVCAP_DXFMT_X32_G8X24_UINT 162 +#define SVGA3D_DEVCAP_DXFMT_R10G10B10A2_TYPELESS 163 +#define SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UINT 164 +#define SVGA3D_DEVCAP_DXFMT_R11G11B10_FLOAT 165 +#define SVGA3D_DEVCAP_DXFMT_R8G8B8A8_TYPELESS 166 +#define SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM 167 +#define SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM_SRGB 168 +#define SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UINT 169 +#define SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SINT 170 +#define SVGA3D_DEVCAP_DXFMT_R16G16_TYPELESS 171 +#define SVGA3D_DEVCAP_DXFMT_R16G16_UINT 172 +#define SVGA3D_DEVCAP_DXFMT_R16G16_SINT 173 +#define SVGA3D_DEVCAP_DXFMT_R32_TYPELESS 174 +#define SVGA3D_DEVCAP_DXFMT_D32_FLOAT 175 +#define SVGA3D_DEVCAP_DXFMT_R32_UINT 176 +#define SVGA3D_DEVCAP_DXFMT_R32_SINT 177 +#define SVGA3D_DEVCAP_DXFMT_R24G8_TYPELESS 178 +#define SVGA3D_DEVCAP_DXFMT_D24_UNORM_S8_UINT 179 +#define SVGA3D_DEVCAP_DXFMT_R24_UNORM_X8 180 +#define SVGA3D_DEVCAP_DXFMT_X24_G8_UINT 181 +#define SVGA3D_DEVCAP_DXFMT_R8G8_TYPELESS 182 +#define SVGA3D_DEVCAP_DXFMT_R8G8_UNORM 183 +#define SVGA3D_DEVCAP_DXFMT_R8G8_UINT 184 +#define SVGA3D_DEVCAP_DXFMT_R8G8_SINT 185 +#define SVGA3D_DEVCAP_DXFMT_R16_TYPELESS 186 +#define SVGA3D_DEVCAP_DXFMT_R16_UNORM 187 +#define SVGA3D_DEVCAP_DXFMT_R16_UINT 188 +#define SVGA3D_DEVCAP_DXFMT_R16_SNORM 189 +#define SVGA3D_DEVCAP_DXFMT_R16_SINT 190 +#define SVGA3D_DEVCAP_DXFMT_R8_TYPELESS 191 +#define SVGA3D_DEVCAP_DXFMT_R8_UNORM 192 +#define SVGA3D_DEVCAP_DXFMT_R8_UINT 193 +#define SVGA3D_DEVCAP_DXFMT_R8_SNORM 194 +#define SVGA3D_DEVCAP_DXFMT_R8_SINT 195 +#define SVGA3D_DEVCAP_DXFMT_P8 196 +#define SVGA3D_DEVCAP_DXFMT_R9G9B9E5_SHAREDEXP 197 +#define SVGA3D_DEVCAP_DXFMT_R8G8_B8G8_UNORM 198 +#define SVGA3D_DEVCAP_DXFMT_G8R8_G8B8_UNORM 199 +#define SVGA3D_DEVCAP_DXFMT_BC1_TYPELESS 200 +#define SVGA3D_DEVCAP_DXFMT_BC1_UNORM_SRGB 201 +#define SVGA3D_DEVCAP_DXFMT_BC2_TYPELESS 202 +#define SVGA3D_DEVCAP_DXFMT_BC2_UNORM_SRGB 203 +#define SVGA3D_DEVCAP_DXFMT_BC3_TYPELESS 204 +#define SVGA3D_DEVCAP_DXFMT_BC3_UNORM_SRGB 205 +#define SVGA3D_DEVCAP_DXFMT_BC4_TYPELESS 206 +#define SVGA3D_DEVCAP_DXFMT_ATI1 207 +#define SVGA3D_DEVCAP_DXFMT_BC4_SNORM 208 +#define SVGA3D_DEVCAP_DXFMT_BC5_TYPELESS 209 +#define SVGA3D_DEVCAP_DXFMT_ATI2 210 +#define SVGA3D_DEVCAP_DXFMT_BC5_SNORM 211 +#define SVGA3D_DEVCAP_DXFMT_R10G10B10_XR_BIAS_A2_UNORM 212 +#define SVGA3D_DEVCAP_DXFMT_B8G8R8A8_TYPELESS 213 +#define SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM_SRGB 214 +#define SVGA3D_DEVCAP_DXFMT_B8G8R8X8_TYPELESS 215 +#define SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM_SRGB 216 +#define SVGA3D_DEVCAP_DXFMT_Z_DF16 217 +#define SVGA3D_DEVCAP_DXFMT_Z_DF24 218 +#define SVGA3D_DEVCAP_DXFMT_Z_D24S8_INT 219 +#define SVGA3D_DEVCAP_DXFMT_YV12 220 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32A32_FLOAT 221 +#define SVGA3D_DEVCAP_DXFMT_R16G16B16A16_FLOAT 222 +#define SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UNORM 223 +#define SVGA3D_DEVCAP_DXFMT_R32G32_FLOAT 224 +#define SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UNORM 225 +#define SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SNORM 226 +#define SVGA3D_DEVCAP_DXFMT_R16G16_FLOAT 227 +#define SVGA3D_DEVCAP_DXFMT_R16G16_UNORM 228 +#define SVGA3D_DEVCAP_DXFMT_R16G16_SNORM 229 +#define SVGA3D_DEVCAP_DXFMT_R32_FLOAT 230 +#define SVGA3D_DEVCAP_DXFMT_R8G8_SNORM 231 +#define SVGA3D_DEVCAP_DXFMT_R16_FLOAT 232 +#define SVGA3D_DEVCAP_DXFMT_D16_UNORM 233 +#define SVGA3D_DEVCAP_DXFMT_A8_UNORM 234 +#define SVGA3D_DEVCAP_DXFMT_BC1_UNORM 235 +#define SVGA3D_DEVCAP_DXFMT_BC2_UNORM 236 +#define SVGA3D_DEVCAP_DXFMT_BC3_UNORM 237 +#define SVGA3D_DEVCAP_DXFMT_B5G6R5_UNORM 238 +#define SVGA3D_DEVCAP_DXFMT_B5G5R5A1_UNORM 239 +#define SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM 240 +#define SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM 241 +#define SVGA3D_DEVCAP_DXFMT_BC4_UNORM 242 +#define SVGA3D_DEVCAP_DXFMT_BC5_UNORM 243 - SVGA3D_DEVCAP_MULTISAMPLE_2X = 245, - SVGA3D_DEVCAP_MULTISAMPLE_4X = 246, +/* + * Advertises shaderModel 4.1 support, independent blend-states, + * cube-map arrays, and a higher vertex input registers limit. + * + * (See documentation on SVGA3D_DEVCAP_DX_MAX_VERTEXBUFFERS.) + */ +#define SVGA3D_DEVCAP_SM41 244 +#define SVGA3D_DEVCAP_MULTISAMPLE_2X 245 +#define SVGA3D_DEVCAP_MULTISAMPLE_4X 246 - SVGA3D_DEVCAP_MAX /* This must be the last index. */ -} SVGA3dDevCapIndex; +/* + * Indicates that the device has rendering support for + * the full multisample quality. If this cap is not present, + * the host may or may not support full quality rendering. + * + * See also SVGA_REG_MS_HINT_RESOLVED. + */ +#define SVGA3D_DEVCAP_MS_FULL_QUALITY 247 + +/* + * Advertises support for the SVGA3D LogicOps commands. + */ +#define SVGA3D_DEVCAP_LOGICOPS 248 + +/* + * Advertises support for using logicOps in the DXBlendStates. + */ +#define SVGA3D_DEVCAP_LOGIC_BLENDOPS 249 + +/* +* Note DXFMT range is now non-contiguous. +*/ +#define SVGA3D_DEVCAP_RESERVED_1 250 +#define SVGA3D_DEVCAP_DXFMT_BC6H_TYPELESS 251 +#define SVGA3D_DEVCAP_DXFMT_BC6H_UF16 252 +#define SVGA3D_DEVCAP_DXFMT_BC6H_SF16 253 +#define SVGA3D_DEVCAP_DXFMT_BC7_TYPELESS 254 +#define SVGA3D_DEVCAP_DXFMT_BC7_UNORM 255 +#define SVGA3D_DEVCAP_DXFMT_BC7_UNORM_SRGB 256 +#define SVGA3D_DEVCAP_RESERVED_2 257 + +#define SVGA3D_DEVCAP_SM5 258 +#define SVGA3D_DEVCAP_MULTISAMPLE_8X 259 + +/* This must be the last index. */ +#define SVGA3D_DEVCAP_MAX 260 /* * Bit definitions for DXFMT devcaps @@ -472,10 +501,10 @@ typedef enum { #define SVGA3D_DXFMT_MAX (1 << 10) typedef union { - Bool b; + SVGA3dBool b; uint32 u; - int32 i; - float f; + int32 i; + float f; } SVGA3dDevCapResult; #endif /* _SVGA3D_DEVCAPS_H_ */ diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_dx.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_dx.h index 7a49c94df221..f703ac2b1768 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_dx.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_dx.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /********************************************************** - * Copyright 2012-2015 VMware, Inc. + * Copyright 2012-2019 VMware, Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -118,12 +118,14 @@ typedef uint8 SVGA3dMultisampleRastEnable; #define SVGA3D_DX_MAX_SRVIEWS 128 #define SVGA3D_DX_MAX_CONSTBUFFERS 16 #define SVGA3D_DX_MAX_SAMPLERS 16 +#define SVGA3D_DX_MAX_CLASS_INSTANCES 253 #define SVGA3D_DX_MAX_CONSTBUF_BINDING_SIZE (4096 * 4 * (uint32)sizeof(uint32)) typedef uint32 SVGA3dShaderResourceViewId; typedef uint32 SVGA3dRenderTargetViewId; typedef uint32 SVGA3dDepthStencilViewId; +typedef uint32 SVGA3dUAViewId; typedef uint32 SVGA3dShaderId; typedef uint32 SVGA3dElementLayoutId; @@ -145,6 +147,17 @@ typedef union { float value[4]; } SVGA3dRGBAFloat; +typedef union { + struct { + uint32 r; + uint32 g; + uint32 b; + uint32 a; + }; + + uint32 value[4]; +} SVGA3dRGBAUint32; + typedef #include "vmware_pack_begin.h" struct { @@ -249,6 +262,39 @@ struct SVGA3dCmdDXSetShader { #include "vmware_pack_end.h" SVGA3dCmdDXSetShader; /* SVGA_3D_CMD_DX_SET_SHADER */ +typedef union { + struct { + uint32 cbOffset : 12; + uint32 cbId : 4; + uint32 baseSamp : 4; + uint32 baseTex : 7; + uint32 reserved : 5; + }; + uint32 value; +} SVGA3dIfaceData; + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXSetShaderIface { + SVGA3dShaderType type; + uint32 numClassInstances; + uint32 index; + uint32 iface; + SVGA3dIfaceData data; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXSetShaderIface; /* SVGA_3D_CMD_DX_SET_SHADER_IFACE */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXBindShaderIface { + uint32 cid; + SVGAMobId mobid; + uint32 offsetInBytes; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXBindShaderIface; /* SVGA_3D_CMD_DX_BIND_SHADER_IFACE */ + typedef #include "vmware_pack_begin.h" struct SVGA3dCmdDXSetSamplers { @@ -304,6 +350,26 @@ struct SVGA3dCmdDXDrawIndexedInstanced { #include "vmware_pack_end.h" SVGA3dCmdDXDrawIndexedInstanced; /* SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED */ +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDrawIndexedInstancedIndirect { + SVGA3dSurfaceId argsBufferSid; + uint32 byteOffsetForArgs; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDrawIndexedInstancedIndirect; +/* SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED_INDIRECT */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDrawInstancedIndirect { + SVGA3dSurfaceId argsBufferSid; + uint32 byteOffsetForArgs; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDrawInstancedIndirect; +/* SVGA_3D_CMD_DX_DRAW_INSTANCED_INDIRECT */ + typedef #include "vmware_pack_begin.h" struct SVGA3dCmdDXDrawAuto { @@ -312,6 +378,27 @@ struct SVGA3dCmdDXDrawAuto { #include "vmware_pack_end.h" SVGA3dCmdDXDrawAuto; /* SVGA_3D_CMD_DX_DRAW_AUTO */ +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDispatch { + uint32 threadGroupCountX; + uint32 threadGroupCountY; + uint32 threadGroupCountZ; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDispatch; +/* SVGA_3D_CMD_DX_DISPATCH */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDispatchIndirect { + SVGA3dSurfaceId argsBufferSid; + uint32 byteOffsetForArgs; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDispatchIndirect; +/* SVGA_3D_CMD_DX_DISPATCH_INDIRECT */ + typedef #include "vmware_pack_begin.h" struct SVGA3dCmdDXSetInputLayout { @@ -525,7 +612,7 @@ struct MKS3dDXSOState { uint32 offset; /* Starting offset */ uint32 intOffset; /* Internal offset */ uint32 vertexCount; /* vertices written */ - uint32 sizeInBytes; /* max bytes to write */ + uint32 dead; } #include "vmware_pack_end.h" SVGA3dDXSOState; @@ -786,6 +873,31 @@ struct SVGA3dCmdDXTransferFromBuffer { SVGA3dCmdDXTransferFromBuffer; /* SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER */ +#define SVGA3D_TRANSFER_TO_BUFFER_READBACK (1 << 0) +#define SVGA3D_TRANSFER_TO_BUFFER_FLAGS_MASK (1 << 0) +typedef uint32 SVGA3dTransferToBufferFlags; + +/* + * Raw byte wise transfer to a buffer surface from another surface + * of the requested box. Supported if SVGA_CAP_DX2 is set. This + * command does not take a context. + */ +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXTransferToBuffer { + SVGA3dSurfaceId srcSid; + uint32 srcSubResource; + SVGA3dBox srcBox; + SVGA3dSurfaceId destSid; + uint32 destOffset; + uint32 destPitch; + uint32 destSlicePitch; + SVGA3dTransferToBufferFlags flags; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXTransferToBuffer; /* SVGA_3D_CMD_DX_TRANSFER_TO_BUFFER */ + + /* * Raw byte wise transfer from a buffer surface into another surface * of the requested box. Supported if SVGA3D_DEVCAP_DXCONTEXT is set. @@ -905,6 +1017,20 @@ typedef SVGA3dCmdDXSetConstantBufferOffset SVGA3dCmdDXSetPSConstantBufferOffset; typedef SVGA3dCmdDXSetConstantBufferOffset SVGA3dCmdDXSetGSConstantBufferOffset; /* SVGA_3D_CMD_DX_SET_GS_CONSTANT_BUFFER_OFFSET */ +typedef SVGA3dCmdDXSetConstantBufferOffset SVGA3dCmdDXSetHSConstantBufferOffset; +/* SVGA_3D_CMD_DX_SET_HS_CONSTANT_BUFFER_OFFSET */ + +typedef SVGA3dCmdDXSetConstantBufferOffset SVGA3dCmdDXSetDSConstantBufferOffset; +/* SVGA_3D_CMD_DX_SET_DS_CONSTANT_BUFFER_OFFSET */ + +typedef SVGA3dCmdDXSetConstantBufferOffset SVGA3dCmdDXSetCSConstantBufferOffset; +/* SVGA_3D_CMD_DX_SET_CS_CONSTANT_BUFFER_OFFSET */ + + +#define SVGA3D_BUFFEREX_SRV_RAW (1 << 0) +#define SVGA3D_BUFFEREX_SRV_FLAGS_MAX (1 << 1) +#define SVGA3D_BUFFEREX_SRV_FLAGS_MASK (SVGA3D_BUFFEREX_SRV_FLAGS_MAX - 1) +typedef uint32 SVGA3dBufferExFlags; typedef #include "vmware_pack_begin.h" @@ -925,7 +1051,7 @@ struct { struct { uint32 firstElement; uint32 numElements; - uint32 flags; + SVGA3dBufferExFlags flags; uint32 pad0; } bufferex; }; @@ -1072,6 +1198,32 @@ struct SVGA3dCmdDXDefineDepthStencilView { SVGA3dCmdDXDefineDepthStencilView; /* SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW */ +/* + * Version 2 needed in order to start validating and using the flags + * field. Unfortunately the device wasn't validating or using the + * flags field and the driver wasn't initializing it in shipped code, + * so a new version of the command is needed to allow that code to + * continue to work. + */ +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDefineDepthStencilView_v2 { + SVGA3dDepthStencilViewId depthStencilViewId; + + SVGA3dSurfaceId sid; + SVGA3dSurfaceFormat format; + SVGA3dResourceType resourceDimension; + uint32 mipSlice; + uint32 firstArraySlice; + uint32 arraySize; + SVGA3DCreateDSViewFlags flags; + uint8 pad0; + uint16 pad1; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDefineDepthStencilView_v2; +/* SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW_V2 */ + typedef #include "vmware_pack_begin.h" struct SVGA3dCmdDXDestroyDepthStencilView { @@ -1081,6 +1233,138 @@ struct SVGA3dCmdDXDestroyDepthStencilView { SVGA3dCmdDXDestroyDepthStencilView; /* SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW */ + +#define SVGA3D_UABUFFER_RAW (1 << 0) +#define SVGA3D_UABUFFER_APPEND (1 << 1) +#define SVGA3D_UABUFFER_COUNTER (1 << 2) +typedef uint32 SVGA3dUABufferFlags; + +typedef +#include "vmware_pack_begin.h" +struct { + union { + struct { + uint32 firstElement; + uint32 numElements; + SVGA3dUABufferFlags flags; + uint32 padding0; + uint32 padding1; + } buffer; + struct { + uint32 mipSlice; + uint32 firstArraySlice; + uint32 arraySize; + uint32 padding0; + uint32 padding1; + } tex; /* 1d, 2d */ + struct { + uint32 mipSlice; + uint32 firstW; + uint32 wSize; + uint32 padding0; + uint32 padding1; + } tex3D; + }; +} +#include "vmware_pack_end.h" +SVGA3dUAViewDesc; + +typedef +#include "vmware_pack_begin.h" +struct { + SVGA3dSurfaceId sid; + SVGA3dSurfaceFormat format; + SVGA3dResourceType resourceDimension; + SVGA3dUAViewDesc desc; + uint32 structureCount; + uint32 pad[7]; +} +#include "vmware_pack_end.h" +SVGACOTableDXUAViewEntry; + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDefineUAView { + SVGA3dUAViewId uaViewId; + + SVGA3dSurfaceId sid; + SVGA3dSurfaceFormat format; + SVGA3dResourceType resourceDimension; + + SVGA3dUAViewDesc desc; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDefineUAView; +/* SVGA_3D_CMD_DX_DEFINE_UA_VIEW */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDestroyUAView { + SVGA3dUAViewId uaViewId; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDestroyUAView; +/* SVGA_3D_CMD_DX_DESTROY_UA_VIEW */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXClearUAViewUint { + SVGA3dUAViewId uaViewId; + SVGA3dRGBAUint32 value; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXClearUAViewUint; +/* SVGA_3D_CMD_DX_CLEAR_UA_VIEW_UINT */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXClearUAViewFloat { + SVGA3dUAViewId uaViewId; + SVGA3dRGBAFloat value; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXClearUAViewFloat; +/* SVGA_3D_CMD_DX_CLEAR_UA_VIEW_FLOAT */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXCopyStructureCount { + SVGA3dUAViewId srcUAViewId; + SVGA3dSurfaceId destSid; + uint32 destByteOffset; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXCopyStructureCount; +/* SVGA_3D_CMD_DX_COPY_STRUCTURE_COUNT */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXSetStructureCount { + SVGA3dUAViewId uaViewId; + uint32 structureCount; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXSetStructureCount; +/* SVGA_3D_CMD_DX_SET_STRUCTURE_COUNT */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXSetUAViews { + uint32 uavSpliceIndex; + /* Followed by a variable number of SVGA3dUAViewId's. */ +} +#include "vmware_pack_end.h" +SVGA3dCmdDXSetUAViews; /* SVGA_3D_CMD_DX_SET_UA_VIEWS */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXSetCSUAViews { + uint32 startIndex; + /* Followed by a variable number of SVGA3dUAViewId's. */ +} +#include "vmware_pack_end.h" +SVGA3dCmdDXSetCSUAViews; /* SVGA_3D_CMD_DX_SET_CS_UA_VIEWS */ + typedef #include "vmware_pack_begin.h" struct SVGA3dInputElementDesc { @@ -1099,7 +1383,7 @@ typedef struct { uint32 elid; uint32 numDescs; - SVGA3dInputElementDesc desc[32]; + SVGA3dInputElementDesc descs[32]; uint32 pad[62]; } #include "vmware_pack_end.h" @@ -1261,7 +1545,8 @@ struct { uint8 lineStippleEnable; uint8 lineStippleFactor; uint16 lineStipplePattern; - uint32 forcedSampleCount; + uint8 forcedSampleCount; + uint8 mustBeZero[3]; } #include "vmware_pack_end.h" SVGACOTableDXRasterizerStateEntry; @@ -1352,6 +1637,71 @@ struct SVGA3dCmdDXDestroySamplerState { #include "vmware_pack_end.h" SVGA3dCmdDXDestroySamplerState; /* SVGA_3D_CMD_DX_DESTROY_SAMPLER_STATE */ + +#define SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED 0 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_POSITION 1 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_CLIP_DISTANCE 2 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_CULL_DISTANCE 3 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_RENDER_TARGET_ARRAY_INDEX 4 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_VIEWPORT_ARRAY_INDEX 5 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_VERTEX_ID 6 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_PRIMITIVE_ID 7 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_INSTANCE_ID 8 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_IS_FRONT_FACE 9 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_SAMPLE_INDEX 10 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR 11 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR 12 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR 13 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR 14 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR 15 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR 16 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR 17 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR 18 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR 19 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_INSIDE_TESSFACTOR 20 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_LINE_DETAIL_TESSFACTOR 21 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_LINE_DENSITY_TESSFACTOR 22 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_MAX 23 +typedef uint32 SVGA3dDXSignatureSemanticName; + +#define SVGADX_SIGNATURE_REGISTER_COMPONENT_UNKNOWN 0 +typedef uint32 SVGA3dDXSignatureRegisterComponentType; + +#define SVGADX_SIGNATURE_MIN_PRECISION_DEFAULT 0 +typedef uint32 SVGA3dDXSignatureMinPrecision; + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dDXSignatureEntry { + uint32 registerIndex; + SVGA3dDXSignatureSemanticName semanticName; + uint32 mask; /* Lower 4 bits represent X, Y, Z, W channels */ + SVGA3dDXSignatureRegisterComponentType componentType; + SVGA3dDXSignatureMinPrecision minPrecision; +} +#include "vmware_pack_end.h" +SVGA3dDXShaderSignatureEntry; + +#define SVGADX_SIGNATURE_HEADER_VERSION_0 0x08a92d12 + +/* + * The SVGA3dDXSignatureHeader structure is added after the shader + * body in the mob that is bound to the shader. It is followed by the + * specified number of SVGA3dDXSignatureEntry structures for each of + * the three types of signatures in the order (input, output, patch + * constants). + */ +typedef +#include "vmware_pack_begin.h" +struct SVGA3dDXSignatureHeader { + uint32 headerVersion; + uint32 numInputSignatures; + uint32 numOutputSignatures; + uint32 numPatchConstantSignatures; +} +#include "vmware_pack_end.h" +SVGA3dDXShaderSignatureHeader; + typedef #include "vmware_pack_begin.h" struct SVGA3dCmdDXDefineShader { @@ -1415,7 +1765,8 @@ SVGA3dCmdDXCondBindAllShader; /* SVGA_3D_CMD_DX_COND_BIND_ALL_SHADER */ /* * The maximum number of streamout decl's in each streamout entry. */ -#define SVGA3D_MAX_STREAMOUT_DECLS 64 +#define SVGA3D_MAX_DX10_STREAMOUT_DECLS 64 +#define SVGA3D_MAX_STREAMOUT_DECLS 512 typedef #include "vmware_pack_begin.h" @@ -1434,10 +1785,16 @@ typedef #include "vmware_pack_begin.h" struct SVGAOTableStreamOutputEntry { uint32 numOutputStreamEntries; - SVGA3dStreamOutputDeclarationEntry decl[SVGA3D_MAX_STREAMOUT_DECLS]; + SVGA3dStreamOutputDeclarationEntry decl[SVGA3D_MAX_DX10_STREAMOUT_DECLS]; uint32 streamOutputStrideInBytes[SVGA3D_DX_MAX_SOTARGETS]; uint32 rasterizedStream; - uint32 pad[250]; + uint32 numOutputStreamStrides; + uint32 mobid; + uint32 offsetInBytes; + uint8 usesMob; + uint8 pad0; + uint16 pad1; + uint32 pad2[246]; } #include "vmware_pack_end.h" SVGACOTableDXStreamOutputEntry; @@ -1447,13 +1804,47 @@ typedef struct SVGA3dCmdDXDefineStreamOutput { SVGA3dStreamOutputId soid; uint32 numOutputStreamEntries; - SVGA3dStreamOutputDeclarationEntry decl[SVGA3D_MAX_STREAMOUT_DECLS]; + SVGA3dStreamOutputDeclarationEntry decl[SVGA3D_MAX_DX10_STREAMOUT_DECLS]; uint32 streamOutputStrideInBytes[SVGA3D_DX_MAX_SOTARGETS]; uint32 rasterizedStream; } #include "vmware_pack_end.h" SVGA3dCmdDXDefineStreamOutput; /* SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT */ +/* + * Version 2 needed in order to start validating and using the + * rasterizedStream field. Unfortunately the device wasn't validating + * or using this field and the driver wasn't initializing it in shipped + * code, so a new version of the command is needed to allow that code + * to continue to work. Also added new numOutputStreamStrides field. + */ + +#define SVGA3D_DX_SO_NO_RASTERIZED_STREAM 0xFFFFFFFF + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDefineStreamOutputWithMob { + SVGA3dStreamOutputId soid; + uint32 numOutputStreamEntries; + uint32 numOutputStreamStrides; + uint32 streamOutputStrideInBytes[SVGA3D_DX_MAX_SOTARGETS]; + uint32 rasterizedStream; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDefineStreamOutputWithMob; +/* SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT_WITH_MOB */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXBindStreamOutput { + SVGA3dStreamOutputId soid; + uint32 mobid; + uint32 offsetInBytes; + uint32 sizeInBytes; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXBindStreamOutput; /* SVGA_3D_CMD_DX_BIND_STREAMOUTPUT */ + typedef #include "vmware_pack_begin.h" struct SVGA3dCmdDXDestroyStreamOutput { @@ -1470,6 +1861,15 @@ struct SVGA3dCmdDXSetStreamOutput { #include "vmware_pack_end.h" SVGA3dCmdDXSetStreamOutput; /* SVGA_3D_CMD_DX_SET_STREAMOUTPUT */ +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXSetMinLOD { + SVGA3dSurfaceId sid; + float minLOD; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXSetMinLOD; /* SVGA_3D_CMD_DX_SET_MIN_LOD */ + typedef #include "vmware_pack_begin.h" struct { @@ -1581,33 +1981,38 @@ struct SVGADXContextMobFormat { uint32 rasterizerStateId; uint32 depthStencilViewId; uint32 renderTargetViewIds[SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS]; - uint32 unorderedAccessViewIds[SVGA3D_MAX_UAVIEWS]; } renderState; + uint32 pad0[8]; + struct { uint32 targets[SVGA3D_DX_MAX_SOTARGETS]; uint32 soid; } streamOut; - uint32 pad0[11]; + + uint32 pad1[10]; + + uint32 uavSpliceIndex; uint8 numViewports; uint8 numScissorRects; - uint16 pad1[1]; + uint16 pad2[1]; - uint32 pad2[3]; + uint32 pad3[3]; SVGA3dViewport viewports[SVGA3D_DX_MAX_VIEWPORTS]; - uint32 pad3[32]; + uint32 pad4[32]; SVGASignedRect scissorRects[SVGA3D_DX_MAX_SCISSORRECTS]; - uint32 pad4[64]; + uint32 pad5[64]; struct { uint32 queryID; uint32 value; } predication; - uint32 pad5[2]; + SVGAMobId shaderIfaceMobid; + uint32 shaderIfaceOffset; struct { uint32 shaderId; SVGA3dConstantBufferBinding constantBuffers[SVGA3D_DX_MAX_CONSTBUFFERS]; @@ -1619,11 +2024,38 @@ struct SVGADXContextMobFormat { SVGA3dQueryId queryID[SVGA3D_MAX_QUERY]; SVGA3dCOTableData cotables[SVGA_COTABLE_MAX]; - uint32 pad7[380]; + + uint32 pad7[64]; + + uint32 uaViewIds[SVGA3D_DX11_1_MAX_UAVIEWS]; + uint32 csuaViewIds[SVGA3D_DX11_1_MAX_UAVIEWS]; + + uint32 pad8[188]; } #include "vmware_pack_end.h" SVGADXContextMobFormat; +/* + * There is conflicting documentation on max class instances (253 vs 256). The + * lower value is the one used throughout the device, but since mob format is + * more involved to increase if needed, conservatively use the higher one here. + */ +#define SVGA3D_DX_MAX_CLASS_INSTANCES_PADDED 256 + +typedef +#include "vmware_pack_begin.h" +struct SVGADXShaderIfaceMobFormat { + struct { + uint32 numClassInstances; + uint32 iface[SVGA3D_DX_MAX_CLASS_INSTANCES_PADDED]; + SVGA3dIfaceData data[SVGA3D_DX_MAX_CLASS_INSTANCES_PADDED]; + } shaderIfaceState[SVGA3D_NUM_SHADERTYPE]; + + uint32 pad0[1018]; +} +#include "vmware_pack_end.h" +SVGADXShaderIfaceMobFormat; + typedef #include "vmware_pack_begin.h" struct SVGA3dCmdDXTempSetContext { diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_limits.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_limits.h index b22a67f15660..f4375a41b3aa 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_limits.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_limits.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /********************************************************** - * Copyright 2007-2015 VMware, Inc. + * Copyright 2007-2019 VMware, Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -40,11 +40,25 @@ #include "includeCheck.h" #define SVGA3D_NUM_CLIPPLANES 6 +#define SVGA3D_MAX_CONTEXT_IDS 256 +#define SVGA3D_MAX_SURFACE_IDS (32 * 1024) + +/* + * While there are separate bind-points for RenderTargetViews and + * UnorderedAccessViews in a DXContext, there is in fact one shared + * semantic space that the guest-driver can use on any given draw call. + * So there are really only 8 slots that can be spilt up between them, with the + * spliceIndex controlling where the UAV's sit in the collapsed array. + */ #define SVGA3D_MAX_RENDER_TARGETS 8 #define SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS (SVGA3D_MAX_RENDER_TARGETS) #define SVGA3D_MAX_UAVIEWS 8 -#define SVGA3D_MAX_CONTEXT_IDS 256 -#define SVGA3D_MAX_SURFACE_IDS (32 * 1024) +#define SVGA3D_DX11_1_MAX_UAVIEWS 64 + +/* + * Maximum canonical size of a surface in host-backed mode (pre-GBObjects). + */ +#define SVGA3D_HB_MAX_SURFACE_SIZE MBYTES_2_BYTES(128) /* * Maximum ID a shader can be assigned on a given context. @@ -59,6 +73,8 @@ #define SVGA3D_NUM_TEXTURE_UNITS 32 #define SVGA3D_NUM_LIGHTS 8 +#define SVGA3D_MAX_VIDEOPROCESSOR_SAMPLERS 32 + /* * Maximum size in dwords of shader text the SVGA device will allow. * Currently 8 MB. @@ -67,6 +83,11 @@ #define SVGA3D_MAX_SHADER_MEMORY (SVGA3D_MAX_SHADER_MEMORY_BYTES / \ sizeof(uint32)) +/* + * The maximum value of threadGroupCount in each dimension + */ +#define SVGA3D_MAX_SHADER_THREAD_GROUPS 65535 + #define SVGA3D_MAX_CLIP_PLANES 6 /* @@ -85,7 +106,9 @@ /* * Maximum number of array indexes in a GB surface (with DX enabled). */ -#define SVGA3D_MAX_SURFACE_ARRAYSIZE 512 +#define SVGA3D_SM4_MAX_SURFACE_ARRAYSIZE 512 +#define SVGA3D_SM5_MAX_SURFACE_ARRAYSIZE 2048 +#define SVGA3D_MAX_SURFACE_ARRAYSIZE SVGA3D_SM5_MAX_SURFACE_ARRAYSIZE /* * The maximum number of vertex arrays we're guaranteed to support in @@ -99,4 +122,9 @@ */ #define SVGA3D_MAX_DRAW_PRIMITIVE_RANGES 32 +/* + * The maximum number of samples that can be contained in a surface. + */ +#define SVGA3D_MAX_SAMPLES 8 + #endif /* _SVGA3D_LIMITS_H_ */ diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h index 61414f105c67..4db25bd9fa22 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h @@ -131,6 +131,8 @@ enum svga3d_block_desc { SVGA3DBLOCKDESC_BC3 = 1 << 26, SVGA3DBLOCKDESC_BC4 = 1 << 27, SVGA3DBLOCKDESC_BC5 = 1 << 28, + SVGA3DBLOCKDESC_BC6H = 1 << 29, + SVGA3DBLOCKDESC_BC7 = 1 << 30, SVGA3DBLOCKDESC_A_UINT = SVGA3DBLOCKDESC_ALPHA | SVGA3DBLOCKDESC_UINT | @@ -290,6 +292,18 @@ enum svga3d_block_desc { SVGA3DBLOCKDESC_COMP_UNORM, SVGA3DBLOCKDESC_BC5_COMP_SNORM = SVGA3DBLOCKDESC_BC5 | SVGA3DBLOCKDESC_COMP_SNORM, + SVGA3DBLOCKDESC_BC6H_COMP_TYPELESS = SVGA3DBLOCKDESC_BC6H | + SVGA3DBLOCKDESC_COMP_TYPELESS, + SVGA3DBLOCKDESC_BC6H_COMP_UF16 = SVGA3DBLOCKDESC_BC6H | + SVGA3DBLOCKDESC_COMPRESSED, + SVGA3DBLOCKDESC_BC6H_COMP_SF16 = SVGA3DBLOCKDESC_BC6H | + SVGA3DBLOCKDESC_COMPRESSED, + SVGA3DBLOCKDESC_BC7_COMP_TYPELESS = SVGA3DBLOCKDESC_BC7 | + SVGA3DBLOCKDESC_COMP_TYPELESS, + SVGA3DBLOCKDESC_BC7_COMP_UNORM = SVGA3DBLOCKDESC_BC7 | + SVGA3DBLOCKDESC_COMP_UNORM, + SVGA3DBLOCKDESC_BC7_COMP_UNORM_SRGB = SVGA3DBLOCKDESC_BC7_COMP_UNORM | + SVGA3DBLOCKDESC_SRGB, SVGA3DBLOCKDESC_NV12 = SVGA3DBLOCKDESC_YUV_VIDEO | SVGA3DBLOCKDESC_PLANAR_YUV | @@ -494,7 +508,7 @@ static const struct svga3d_surface_desc svga3d_surface_descs[] = { {{8}, {8}, {8}, {0}}, {{16}, {8}, {0}, {0}}}, - {SVGA3D_FORMAT_DEAD1, SVGA3DBLOCKDESC_UVL, + {SVGA3D_FORMAT_DEAD1, SVGA3DBLOCKDESC_NONE, {1, 1, 1}, 3, 3, {{8}, {8}, {8}, {0}}, {{16}, {8}, {0}, {0}}}, @@ -604,7 +618,7 @@ static const struct svga3d_surface_desc svga3d_surface_descs[] = { {{0}, {0}, {48}, {0}}, {{0}, {0}, {0}, {0}}}, - {SVGA3D_AYUV, SVGA3DBLOCKDESC_AYUV, + {SVGA3D_FORMAT_DEAD2, SVGA3DBLOCKDESC_NONE, {1, 1, 1}, 4, 4, {{8}, {8}, {8}, {8}}, {{0}, {8}, {16}, {24}}}, @@ -1103,6 +1117,46 @@ static const struct svga3d_surface_desc svga3d_surface_descs[] = { {4, 4, 1}, 16, 16, {{0}, {0}, {128}, {0}}, {{0}, {0}, {0}, {0}}}, + + {SVGA3D_B4G4R4A4_UNORM, SVGA3DBLOCKDESC_RGBA_UNORM, + {1, 1, 1}, 2, 2, + {{4}, {4}, {4}, {4}}, + {{0}, {4}, {8}, {12}}}, + + {SVGA3D_BC6H_TYPELESS, SVGA3DBLOCKDESC_BC6H_COMP_TYPELESS, + {4, 4, 1}, 16, 16, + {{0}, {0}, {128}, {0}}, + {{0}, {0}, {0}, {0}}}, + + {SVGA3D_BC6H_UF16, SVGA3DBLOCKDESC_BC6H_COMP_UF16, + {4, 4, 1}, 16, 16, + {{0}, {0}, {128}, {0}}, + {{0}, {0}, {0}, {0}}}, + + {SVGA3D_BC6H_SF16, SVGA3DBLOCKDESC_BC6H_COMP_SF16, + {4, 4, 1}, 16, 16, + {{0}, {0}, {128}, {0}}, + {{0}, {0}, {0}, {0}}}, + + {SVGA3D_BC7_TYPELESS, SVGA3DBLOCKDESC_BC7_COMP_TYPELESS, + {4, 4, 1}, 16, 16, + {{0}, {0}, {128}, {0}}, + {{0}, {0}, {0}, {0}}}, + + {SVGA3D_BC7_UNORM, SVGA3DBLOCKDESC_BC7_COMP_UNORM, + {4, 4, 1}, 16, 16, + {{0}, {0}, {128}, {0}}, + {{0}, {0}, {0}, {0}}}, + + {SVGA3D_BC7_UNORM_SRGB, SVGA3DBLOCKDESC_BC7_COMP_UNORM_SRGB, + {4, 4, 1}, 16, 16, + {{0}, {0}, {128}, {0}}, + {{0}, {0}, {0}, {0}}}, + + {SVGA3D_AYUV, SVGA3DBLOCKDESC_AYUV, + {1, 1, 1}, 4, 4, + {{8}, {8}, {8}, {8}}, + {{0}, {8}, {16}, {24}}}, }; static inline u32 clamped_umul32(u32 a, u32 b) diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_types.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_types.h index 308370665a8e..77e338a65791 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_types.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_types.h @@ -113,6 +113,19 @@ struct { #include "vmware_pack_end.h" SVGA3dBox; +typedef +#include "vmware_pack_begin.h" +struct { + int32 x; + int32 y; + int32 z; + int32 w; + int32 h; + int32 d; +} +#include "vmware_pack_end.h" +SVGA3dSignedBox; + typedef #include "vmware_pack_begin.h" struct { @@ -198,8 +211,7 @@ typedef enum SVGA3dSurfaceFormat { /* Planar video formats */ SVGA3D_NV12 = 44, - /* Video format with alpha */ - SVGA3D_AYUV = 45, + SVGA3D_FORMAT_DEAD2 = 45, SVGA3D_R32G32B32A32_TYPELESS = 46, SVGA3D_R32G32B32A32_UINT = 47, @@ -305,6 +317,18 @@ typedef enum SVGA3dSurfaceFormat { SVGA3D_B8G8R8X8_UNORM = 142, SVGA3D_BC4_UNORM = 143, SVGA3D_BC5_UNORM = 144, + SVGA3D_B4G4R4A4_UNORM = 145, + + /* DX11 compressed formats */ + SVGA3D_BC6H_TYPELESS = 146, + SVGA3D_BC6H_UF16 = 147, + SVGA3D_BC6H_SF16 = 148, + SVGA3D_BC7_TYPELESS = 149, + SVGA3D_BC7_UNORM = 150, + SVGA3D_BC7_UNORM_SRGB = 151, + + /* Video format with alpha */ + SVGA3D_AYUV = 152, SVGA3D_FORMAT_MAX } SVGA3dSurfaceFormat; @@ -326,10 +350,10 @@ typedef enum SVGA3dSurfaceFormat { #define SVGA3D_SURFACE_HINT_RENDERTARGET (CONST64U(1) << 6) #define SVGA3D_SURFACE_HINT_DEPTHSTENCIL (CONST64U(1) << 7) #define SVGA3D_SURFACE_HINT_WRITEONLY (CONST64U(1) << 8) -#define SVGA3D_SURFACE_MASKABLE_ANTIALIAS (CONST64U(1) << 9) +#define SVGA3D_SURFACE_DEAD2 (CONST64U(1) << 9) #define SVGA3D_SURFACE_AUTOGENMIPMAPS (CONST64U(1) << 10) -#define SVGA3D_SURFACE_DECODE_RENDERTARGET (CONST64U(1) << 11) +#define SVGA3D_SURFACE_DEAD1 (CONST64U(1) << 11) /* * Is this surface using a base-level pitch for it's mob backing? @@ -387,7 +411,7 @@ typedef enum SVGA3dSurfaceFormat { * Setting this flag allow this surface to be used with the * SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER command. It is only valid for * buffer surfaces, and no bind flags are allowed to be set on surfaces - * with this flag. + * with this flag except SVGA3D_SURFACE_TRANSFER_TO_BUFFER. */ #define SVGA3D_SURFACE_TRANSFER_FROM_BUFFER (CONST64U(1) << 30) @@ -402,7 +426,31 @@ typedef enum SVGA3dSurfaceFormat { */ #define SVGA3D_SURFACE_MULTISAMPLE (CONST64U(1) << 32) -#define SVGA3D_SURFACE_FLAG_MAX (CONST64U(1) << 33) +/* + * Specified that the surface is allowed to be bound to a UAView. + */ +#define SVGA3D_SURFACE_BIND_UAVIEW (CONST64U(1) << 33) + +/* + * Setting this flag allow this surface to be used with the + * SVGA_3D_CMD_DX_TRANSFER_TO_BUFFER command. It is only valid for + * buffer surfaces, and no bind flags are allowed to be set on surfaces + * with this flag except SVGA3D_SURFACE_TRANSFER_FROM_BUFFER. + */ +#define SVGA3D_SURFACE_TRANSFER_TO_BUFFER (CONST64U(1) << 34) + +#define SVGA3D_SURFACE_BIND_LOGICOPS (CONST64U(1) << 35) + +/* + * Optional flags for use with SVGA3D_SURFACE_BIND_UAVIEW + */ +#define SVGA3D_SURFACE_BIND_RAW_VIEWS (CONST64U(1) << 36) +#define SVGA3D_SURFACE_BUFFER_STRUCTURED (CONST64U(1) << 37) + +#define SVGA3D_SURFACE_DRAWINDIRECT_ARGS (CONST64U(1) << 38) +#define SVGA3D_SURFACE_RESOURCE_CLAMP (CONST64U(1) << 39) + +#define SVGA3D_SURFACE_FLAG_MAX (CONST64U(1) << 40) /* * Surface flags types: @@ -428,17 +476,25 @@ typedef uint64 SVGA3dSurfaceAllFlags; SVGA3D_SURFACE_STAGING_DOWNLOAD | \ SVGA3D_SURFACE_HINT_INDIRECT_UPDATE | \ SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ - SVGA3D_SURFACE_MULTISAMPLE \ + SVGA3D_SURFACE_RESERVED1 | \ + SVGA3D_SURFACE_MULTISAMPLE | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_LOGICOPS | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ ) #define SVGA3D_SURFACE_HB_PRESENT_DISALLOWED_MASK \ ( SVGA3D_SURFACE_1D | \ + SVGA3D_SURFACE_RESERVED1 | \ SVGA3D_SURFACE_MULTISAMPLE \ ) #define SVGA3D_SURFACE_2D_DISALLOWED_MASK \ ( SVGA3D_SURFACE_CUBEMAP | \ - SVGA3D_SURFACE_MASKABLE_ANTIALIAS | \ SVGA3D_SURFACE_AUTOGENMIPMAPS | \ SVGA3D_SURFACE_VOLUME | \ SVGA3D_SURFACE_1D | \ @@ -448,7 +504,14 @@ typedef uint64 SVGA3dSurfaceAllFlags; SVGA3D_SURFACE_BIND_DEPTH_STENCIL | \ SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ - SVGA3D_SURFACE_MULTISAMPLE \ + SVGA3D_SURFACE_RESERVED1 | \ + SVGA3D_SURFACE_MULTISAMPLE | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ ) #define SVGA3D_SURFACE_BASICOPS_DISALLOWED_MASK \ @@ -456,6 +519,7 @@ typedef uint64 SVGA3dSurfaceAllFlags; SVGA3D_SURFACE_AUTOGENMIPMAPS | \ SVGA3D_SURFACE_VOLUME | \ SVGA3D_SURFACE_1D | \ + SVGA3D_SURFACE_RESERVED1 | \ SVGA3D_SURFACE_MULTISAMPLE \ ) @@ -474,7 +538,14 @@ typedef uint64 SVGA3dSurfaceAllFlags; SVGA3D_SURFACE_STAGING_DOWNLOAD | \ SVGA3D_SURFACE_HINT_INDIRECT_UPDATE | \ SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ - SVGA3D_SURFACE_MULTISAMPLE \ + SVGA3D_SURFACE_RESERVED1 | \ + SVGA3D_SURFACE_MULTISAMPLE | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ ) #define SVGA3D_SURFACE_BUFFER_DISALLOWED_MASK \ @@ -482,10 +553,11 @@ typedef uint64 SVGA3dSurfaceAllFlags; SVGA3D_SURFACE_AUTOGENMIPMAPS | \ SVGA3D_SURFACE_VOLUME | \ SVGA3D_SURFACE_1D | \ - SVGA3D_SURFACE_MASKABLE_ANTIALIAS | \ + SVGA3D_SURFACE_DEAD2 | \ SVGA3D_SURFACE_ARRAY | \ SVGA3D_SURFACE_MULTISAMPLE | \ - SVGA3D_SURFACE_MOB_PITCH \ + SVGA3D_SURFACE_MOB_PITCH | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ ) #define SVGA3D_SURFACE_MULTISAMPLE_DISALLOWED_MASK \ @@ -494,14 +566,23 @@ typedef uint64 SVGA3dSurfaceAllFlags; SVGA3D_SURFACE_VOLUME | \ SVGA3D_SURFACE_1D | \ SVGA3D_SURFACE_SCREENTARGET | \ - SVGA3D_SURFACE_MOB_PITCH \ + SVGA3D_SURFACE_MOB_PITCH | \ + SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ + SVGA3D_SURFACE_RESERVED1 | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_LOGICOPS | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS \ ) -#define SVGA3D_SURFACE_DX_ONLY_MASK \ - ( SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ - SVGA3D_SURFACE_STAGING_UPLOAD | \ - SVGA3D_SURFACE_STAGING_DOWNLOAD | \ - SVGA3D_SURFACE_TRANSFER_FROM_BUFFER \ +#define SVGA3D_SURFACE_DX_ONLY_MASK \ + ( SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ + SVGA3D_SURFACE_STAGING_UPLOAD | \ + SVGA3D_SURFACE_STAGING_DOWNLOAD | \ + SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER \ ) #define SVGA3D_SURFACE_STAGING_MASK \ @@ -516,9 +597,135 @@ typedef uint64 SVGA3dSurfaceAllFlags; SVGA3D_SURFACE_BIND_SHADER_RESOURCE | \ SVGA3D_SURFACE_BIND_RENDER_TARGET | \ SVGA3D_SURFACE_BIND_DEPTH_STENCIL | \ - SVGA3D_SURFACE_BIND_STREAM_OUTPUT \ + SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_BIND_LOGICOPS | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS \ ) +#define SVGA3D_SURFACE_VADECODE_DISALLOWED_MASK \ + ( SVGA3D_SURFACE_CUBEMAP | \ + SVGA3D_SURFACE_HINT_STATIC | \ + SVGA3D_SURFACE_HINT_DYNAMIC | \ + SVGA3D_SURFACE_HINT_INDEXBUFFER | \ + SVGA3D_SURFACE_HINT_VERTEXBUFFER | \ + SVGA3D_SURFACE_HINT_TEXTURE | \ + SVGA3D_SURFACE_HINT_RENDERTARGET | \ + SVGA3D_SURFACE_HINT_DEPTHSTENCIL | \ + SVGA3D_SURFACE_HINT_WRITEONLY | \ + SVGA3D_SURFACE_DEAD2 | \ + SVGA3D_SURFACE_AUTOGENMIPMAPS | \ + SVGA3D_SURFACE_HINT_RT_LOCKABLE | \ + SVGA3D_SURFACE_VOLUME | \ + SVGA3D_SURFACE_SCREENTARGET | \ + SVGA3D_SURFACE_1D | \ + SVGA3D_SURFACE_BIND_VERTEX_BUFFER | \ + SVGA3D_SURFACE_BIND_INDEX_BUFFER | \ + SVGA3D_SURFACE_BIND_CONSTANT_BUFFER | \ + SVGA3D_SURFACE_BIND_RENDER_TARGET | \ + SVGA3D_SURFACE_BIND_SHADER_RESOURCE | \ + SVGA3D_SURFACE_BIND_DEPTH_STENCIL | \ + SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ + SVGA3D_SURFACE_INACTIVE | \ + SVGA3D_SURFACE_STAGING_UPLOAD | \ + SVGA3D_SURFACE_STAGING_DOWNLOAD | \ + SVGA3D_SURFACE_HINT_INDIRECT_UPDATE | \ + SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ + SVGA3D_SURFACE_MULTISAMPLE | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_LOGICOPS | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ + ) + +#define SVGA3D_SURFACE_VAPROCESSFRAME_OUTPUT_DISALLOWED_MASK \ + ( SVGA3D_SURFACE_HINT_INDEXBUFFER | \ + SVGA3D_SURFACE_HINT_VERTEXBUFFER | \ + SVGA3D_SURFACE_HINT_DEPTHSTENCIL | \ + SVGA3D_SURFACE_DEAD2 | \ + SVGA3D_SURFACE_VOLUME | \ + SVGA3D_SURFACE_1D | \ + SVGA3D_SURFACE_BIND_VERTEX_BUFFER | \ + SVGA3D_SURFACE_BIND_INDEX_BUFFER | \ + SVGA3D_SURFACE_BIND_CONSTANT_BUFFER | \ + SVGA3D_SURFACE_BIND_DEPTH_STENCIL | \ + SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ + SVGA3D_SURFACE_INACTIVE | \ + SVGA3D_SURFACE_STAGING_UPLOAD | \ + SVGA3D_SURFACE_STAGING_DOWNLOAD | \ + SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ + SVGA3D_SURFACE_VADECODE | \ + SVGA3D_SURFACE_MULTISAMPLE | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_LOGICOPS | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ + ) + +#define SVGA3D_SURFACE_VAPROCESSFRAME_INPUT_DISALLOWED_MASK \ + ( SVGA3D_SURFACE_CUBEMAP | \ + SVGA3D_SURFACE_HINT_INDEXBUFFER | \ + SVGA3D_SURFACE_HINT_VERTEXBUFFER | \ + SVGA3D_SURFACE_HINT_DEPTHSTENCIL | \ + SVGA3D_SURFACE_DEAD2 | \ + SVGA3D_SURFACE_VOLUME | \ + SVGA3D_SURFACE_SCREENTARGET | \ + SVGA3D_SURFACE_1D | \ + SVGA3D_SURFACE_BIND_VERTEX_BUFFER | \ + SVGA3D_SURFACE_BIND_INDEX_BUFFER | \ + SVGA3D_SURFACE_BIND_CONSTANT_BUFFER | \ + SVGA3D_SURFACE_BIND_DEPTH_STENCIL | \ + SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ + SVGA3D_SURFACE_STAGING_UPLOAD | \ + SVGA3D_SURFACE_STAGING_DOWNLOAD | \ + SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ + SVGA3D_SURFACE_MULTISAMPLE | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_LOGICOPS | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ + ) + +#define SVGA3D_SURFACE_LOGICOPS_DISALLOWED_MASK \ + ( SVGA3D_SURFACE_CUBEMAP | \ + SVGA3D_SURFACE_DEAD2 | \ + SVGA3D_SURFACE_AUTOGENMIPMAPS | \ + SVGA3D_SURFACE_VOLUME | \ + SVGA3D_SURFACE_1D | \ + SVGA3D_SURFACE_BIND_VERTEX_BUFFER | \ + SVGA3D_SURFACE_BIND_INDEX_BUFFER | \ + SVGA3D_SURFACE_BIND_CONSTANT_BUFFER | \ + SVGA3D_SURFACE_BIND_DEPTH_STENCIL | \ + SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ + SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ + SVGA3D_SURFACE_VADECODE | \ + SVGA3D_SURFACE_MULTISAMPLE | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ + ) + +#define SVGA3D_BUFFER_STRUCTURED_STRIDE_MAX 2048 + + +/* + * These are really the D3DFORMAT_OP defines from the wdk. We need + * them so that we can query the host for what the supported surface + * operations are (when we're using the D3D backend, in particular), + * and so we can send those operations to the guest. + */ typedef enum { SVGA3DFORMAT_OP_TEXTURE = 0x00000001, SVGA3DFORMAT_OP_VOLUMETEXTURE = 0x00000002, @@ -1338,7 +1545,40 @@ typedef enum { SVGA3D_PRIMITIVE_LINESTRIP_ADJ = 8, SVGA3D_PRIMITIVE_TRIANGLELIST_ADJ = 9, SVGA3D_PRIMITIVE_TRIANGLESTRIP_ADJ = 10, - SVGA3D_PRIMITIVE_MAX + SVGA3D_PRIMITIVE_DX10_MAX = 11, + SVGA3D_PRIMITIVE_1_CONTROL_POINT_PATCH = 11, + SVGA3D_PRIMITIVE_2_CONTROL_POINT_PATCH = 12, + SVGA3D_PRIMITIVE_3_CONTROL_POINT_PATCH = 13, + SVGA3D_PRIMITIVE_4_CONTROL_POINT_PATCH = 14, + SVGA3D_PRIMITIVE_5_CONTROL_POINT_PATCH = 15, + SVGA3D_PRIMITIVE_6_CONTROL_POINT_PATCH = 16, + SVGA3D_PRIMITIVE_7_CONTROL_POINT_PATCH = 17, + SVGA3D_PRIMITIVE_8_CONTROL_POINT_PATCH = 18, + SVGA3D_PRIMITIVE_9_CONTROL_POINT_PATCH = 19, + SVGA3D_PRIMITIVE_10_CONTROL_POINT_PATCH = 20, + SVGA3D_PRIMITIVE_11_CONTROL_POINT_PATCH = 21, + SVGA3D_PRIMITIVE_12_CONTROL_POINT_PATCH = 22, + SVGA3D_PRIMITIVE_13_CONTROL_POINT_PATCH = 23, + SVGA3D_PRIMITIVE_14_CONTROL_POINT_PATCH = 24, + SVGA3D_PRIMITIVE_15_CONTROL_POINT_PATCH = 25, + SVGA3D_PRIMITIVE_16_CONTROL_POINT_PATCH = 26, + SVGA3D_PRIMITIVE_17_CONTROL_POINT_PATCH = 27, + SVGA3D_PRIMITIVE_18_CONTROL_POINT_PATCH = 28, + SVGA3D_PRIMITIVE_19_CONTROL_POINT_PATCH = 29, + SVGA3D_PRIMITIVE_20_CONTROL_POINT_PATCH = 30, + SVGA3D_PRIMITIVE_21_CONTROL_POINT_PATCH = 31, + SVGA3D_PRIMITIVE_22_CONTROL_POINT_PATCH = 32, + SVGA3D_PRIMITIVE_23_CONTROL_POINT_PATCH = 33, + SVGA3D_PRIMITIVE_24_CONTROL_POINT_PATCH = 34, + SVGA3D_PRIMITIVE_25_CONTROL_POINT_PATCH = 35, + SVGA3D_PRIMITIVE_26_CONTROL_POINT_PATCH = 36, + SVGA3D_PRIMITIVE_27_CONTROL_POINT_PATCH = 37, + SVGA3D_PRIMITIVE_28_CONTROL_POINT_PATCH = 38, + SVGA3D_PRIMITIVE_29_CONTROL_POINT_PATCH = 39, + SVGA3D_PRIMITIVE_30_CONTROL_POINT_PATCH = 40, + SVGA3D_PRIMITIVE_31_CONTROL_POINT_PATCH = 41, + SVGA3D_PRIMITIVE_32_CONTROL_POINT_PATCH = 42, + SVGA3D_PRIMITIVE_MAX = 43 } SVGA3dPrimitiveType; typedef enum { @@ -1442,16 +1682,15 @@ typedef enum { SVGA3D_QUERYTYPE_STREAMOUTPUTSTATS = 5, SVGA3D_QUERYTYPE_STREAMOVERFLOWPREDICATE = 6, SVGA3D_QUERYTYPE_OCCLUSION64 = 7, - SVGA3D_QUERYTYPE_EVENT = 8, - SVGA3D_QUERYTYPE_DX10_MAX = 9, - SVGA3D_QUERYTYPE_SOSTATS_STREAM0 = 9, - SVGA3D_QUERYTYPE_SOSTATS_STREAM1 = 10, - SVGA3D_QUERYTYPE_SOSTATS_STREAM2 = 11, - SVGA3D_QUERYTYPE_SOSTATS_STREAM3 = 12, - SVGA3D_QUERYTYPE_SOP_STREAM0 = 13, - SVGA3D_QUERYTYPE_SOP_STREAM1 = 14, - SVGA3D_QUERYTYPE_SOP_STREAM2 = 15, - SVGA3D_QUERYTYPE_SOP_STREAM3 = 16, + SVGA3D_QUERYTYPE_DX10_MAX = 8, + SVGA3D_QUERYTYPE_SOSTATS_STREAM0 = 8, + SVGA3D_QUERYTYPE_SOSTATS_STREAM1 = 9, + SVGA3D_QUERYTYPE_SOSTATS_STREAM2 = 10, + SVGA3D_QUERYTYPE_SOSTATS_STREAM3 = 11, + SVGA3D_QUERYTYPE_SOP_STREAM0 = 12, + SVGA3D_QUERYTYPE_SOP_STREAM1 = 13, + SVGA3D_QUERYTYPE_SOP_STREAM2 = 14, + SVGA3D_QUERYTYPE_SOP_STREAM3 = 15, SVGA3D_QUERYTYPE_MAX } SVGA3dQueryType; @@ -1584,28 +1823,33 @@ typedef enum { SVGA3D_READ_HOST_VRAM = 2, } SVGA3dTransferType; -typedef enum { - SVGA3D_LOGICOP_INVALID = 0, - SVGA3D_LOGICOP_MIN = 1, - SVGA3D_LOGICOP_COPY = 1, - SVGA3D_LOGICOP_NOT = 2, - SVGA3D_LOGICOP_AND = 3, - SVGA3D_LOGICOP_OR = 4, - SVGA3D_LOGICOP_XOR = 5, - SVGA3D_LOGICOP_NXOR = 6, - SVGA3D_LOGICOP_ROP3MIN = 30, /* 7-29 are reserved for future logic ops. */ - SVGA3D_LOGICOP_ROP3MAX = (SVGA3D_LOGICOP_ROP3MIN + 255), - SVGA3D_LOGICOP_MAX = (SVGA3D_LOGICOP_ROP3MAX + 1), -} SVGA3dLogicOp; +#define SVGA3D_LOGICOP_INVALID 0 +#define SVGA3D_LOGICOP_MIN 1 +#define SVGA3D_LOGICOP_COPY 1 +#define SVGA3D_LOGICOP_NOT 2 +#define SVGA3D_LOGICOP_AND 3 +#define SVGA3D_LOGICOP_OR 4 +#define SVGA3D_LOGICOP_XOR 5 +#define SVGA3D_LOGICOP_NXOR 6 +#define SVGA3D_LOGICOP_ROP3 7 +#define SVGA3D_LOGICOP_MAX 8 + +typedef uint16 SVGA3dLogicOp; + +#define SVGA3D_LOGICOP_ROP3_INVALID ((uint16) -1) +#define SVGA3D_LOGICOP_ROP3_MIN 0 +#define SVGA3D_LOGICOP_ROP3_MAX 256 + +typedef uint16 SVGA3dLogicOpRop3; typedef #include "vmware_pack_begin.h" struct { union { struct { - uint16 function; /* SVGA3dFogFunction */ - uint8 type; /* SVGA3dFogType */ - uint8 base; /* SVGA3dFogBase */ + uint16 function; // SVGA3dFogFunction + uint8 type; // SVGA3dFogType + uint8 base; // SVGA3dFogBase }; uint32 uintValue; }; @@ -1742,4 +1986,15 @@ typedef enum SVGA3dMSQualityLevel { SVGA3D_MS_QUALITY_MAX = 2, } SVGA3dMSQualityLevel; +/* + * Screen Target Update Flags + */ + +typedef enum SVGA3dFrameUpdateType { + SVGA3D_FRAME_END = 0, + SVGA3D_FRAME_PARTIAL = 1, + SVGA3D_FRAME_UNKNOWN = 2, + SVGA3D_FRAME_MAX = 3, +} SVGA3dFrameUpdateType; + #endif /* _SVGA3D_TYPES_H_ */ diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga_reg.h b/drivers/gpu/drm/vmwgfx/device_include/svga_reg.h index 056f54b35d73..19fb9e3299e7 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga_reg.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga_reg.h @@ -70,8 +70,7 @@ typedef uint32 SVGAMobId; /* * Legal values for the SVGA_REG_CURSOR_ON register in old-fashioned - * cursor bypass mode. This is still supported, but no new guest - * drivers should use it. + * cursor bypass mode. */ #define SVGA_CURSOR_ON_HIDE 0x0 #define SVGA_CURSOR_ON_SHOW 0x1 @@ -136,6 +135,17 @@ typedef uint32 SVGAMobId; #define SVGA_IRQFLAG_COMMAND_BUFFER 0x8 /* Command buffer completed */ #define SVGA_IRQFLAG_ERROR 0x10 /* Error while processing commands */ +/* + * The byte-size is the size of the actual cursor data, + * possibly after expanding it to the current bit depth. + * + * 40K is sufficient memory for two 32-bit planes for a 64 x 64 cursor. + * + * The dimension limit is a bound on the maximum width or height. + */ +#define SVGA_MAX_CURSOR_CMD_BYTES (40 * 1024) +#define SVGA_MAX_CURSOR_CMD_DIMENSION 1024 + /* * Registers */ @@ -169,7 +179,7 @@ enum { SVGA_REG_SYNC = 21, /* See "FIFO Synchronization Registers" */ SVGA_REG_BUSY = 22, /* See "FIFO Synchronization Registers" */ SVGA_REG_GUEST_ID = 23, /* (Deprecated) */ - SVGA_REG_CURSOR_ID = 24, /* (Deprecated) */ + SVGA_REG_DEAD = 24, /* Drivers should never write this. */ SVGA_REG_CURSOR_X = 25, /* (Deprecated) */ SVGA_REG_CURSOR_Y = 26, /* (Deprecated) */ SVGA_REG_CURSOR_ON = 27, /* (Deprecated) */ @@ -208,7 +218,13 @@ enum { SVGA_REG_MAX_PRIMARY_MEM = 50, SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM = 50, - SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB = 51, /* Sugested limit on mob mem */ + /* + * Legacy version of SVGA_REG_GBOBJECT_MEM_SIZE_KB for drivers that + * don't know how to convert to a 64-bit byte value without overflowing. + * (See SVGA_REG_GBOBJECT_MEM_SIZE_KB). + */ + SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB = 51, + SVGA_REG_DEV_CAP = 52, /* Write dev cap index, read value */ SVGA_REG_CMD_PREPEND_LOW = 53, SVGA_REG_CMD_PREPEND_HIGH = 54, @@ -218,7 +234,59 @@ enum { SVGA_REG_BLANK_SCREEN_TARGETS = 58, SVGA_REG_CAP2 = 59, SVGA_REG_DEVEL_CAP = 60, - SVGA_REG_TOP = 61, /* Must be 1 more than the last register */ + + /* + * Allow the guest to hint to the device which driver is running. + * + * This should not generally change device behavior, but might be + * convenient to work-around specific bugs in guest drivers. + * + * Drivers should first write their id value into SVGA_REG_GUEST_DRIVER_ID, + * and then fill out all of the version registers that they have defined. + * + * After the driver has written all of the registers, they should + * then write the value SVGA_REG_GUEST_DRIVER_ID_SUBMIT to the + * SVGA_REG_GUEST_DRIVER_ID register, to signal that they have finished. + * + * The SVGA_REG_GUEST_DRIVER_ID values are defined below by the + * SVGARegGuestDriverId enum. + * + * The SVGA_REG_GUEST_DRIVER_VERSION fields are driver-specific, + * but ideally should encode a monotonically increasing number that allows + * the device to perform inequality checks against ranges of driver versions. + */ + SVGA_REG_GUEST_DRIVER_ID = 61, + SVGA_REG_GUEST_DRIVER_VERSION1 = 62, + SVGA_REG_GUEST_DRIVER_VERSION2 = 63, + SVGA_REG_GUEST_DRIVER_VERSION3 = 64, + SVGA_REG_CURSOR_MOBID = 65, + SVGA_REG_CURSOR_MAX_BYTE_SIZE = 66, + SVGA_REG_CURSOR_MAX_DIMENSION = 67, + + SVGA_REG_FIFO_CAPS = 68, + SVGA_REG_FENCE = 69, + + SVGA_REG_RESERVED1 = 70, + SVGA_REG_RESERVED2 = 71, + SVGA_REG_RESERVED3 = 72, + SVGA_REG_RESERVED4 = 73, + SVGA_REG_RESERVED5 = 74, + SVGA_REG_SCREENDMA = 75, + + /* + * The maximum amount of guest-backed objects that the device can have + * resident at a time. Guest-drivers should keep their working set size + * below this limit for best performance. + * + * Note that this value is in kilobytes, and not bytes, because the actual + * number of bytes might be larger than can fit in a 32-bit register. + * + * PLEASE USE A 64-BIT VALUE WHEN CONVERTING THIS INTO BYTES. + * (See SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB). + */ + SVGA_REG_GBOBJECT_MEM_SIZE_KB = 76, + + SVGA_REG_TOP = 77, /* Must be 1 more than the last register */ SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */ /* Next 768 (== 256*3) registers exist for colormap */ @@ -229,6 +297,20 @@ enum { the use of the current SVGA driver. */ }; + +/* + * Values for SVGA_REG_GUEST_DRIVER_ID. + */ +typedef enum SVGARegGuestDriverId { + SVGA_REG_GUEST_DRIVER_ID_UNKNOWN = 0, + SVGA_REG_GUEST_DRIVER_ID_WDDM = 1, + SVGA_REG_GUEST_DRIVER_ID_LINUX = 2, + SVGA_REG_GUEST_DRIVER_ID_MAX, + + SVGA_REG_GUEST_DRIVER_ID_SUBMIT = MAX_UINT32, +} SVGARegGuestDriverId; + + /* * Guest memory regions (GMRs): * @@ -416,7 +498,6 @@ typedef enum { SVGA_CB_CONTEXT_0 = 0x0, SVGA_CB_CONTEXT_1 = 0x1, /* Supported with SVGA_CAP_HP_CMD_QUEUE */ SVGA_CB_CONTEXT_MAX = 0x2, - SVGA_CB_CONTEXT_HP_MAX = 0x2, } SVGACBContext; @@ -733,9 +814,6 @@ SVGASignedPoint; * and must not be reused. Those capabilities will never be reported * by new versions of the SVGA device. * - * XXX: Add longer descriptions for each capability, including a list - * of the new features that each capability provides. - * * SVGA_CAP_IRQMASK -- * Provides device interrupts. Adds device register SVGA_REG_IRQMASK * to set interrupt mask and direct I/O port SVGA_IRQSTATUS_PORT to @@ -842,17 +920,51 @@ SVGASignedPoint; * Allow the IntraSurfaceCopy command. * * SVGA_CAP2_DX2 -- - * Allow the DefineGBSurface_v3, WholeSurfaceCopy. + * Allow the DefineGBSurface_v3, WholeSurfaceCopy, WriteZeroSurface, and + * HintZeroSurface commands, and the SVGA_REG_GUEST_DRIVER_ID register. + * + * SVGA_CAP2_GB_MEMSIZE_2 -- + * Allow the SVGA_REG_GBOBJECT_MEM_SIZE_KB register. + * + * SVGA_CAP2_SCREENDMA_REG -- + * Allow the SVGA_REG_SCREENDMA register. + * + * SVGA_CAP2_OTABLE_PTDEPTH_2 -- + * Allow 2 level page tables for OTable commands. + * + * SVGA_CAP2_NON_MS_TO_MS_STRETCHBLT -- + * Allow a stretch blt from a non-multisampled surface to a multisampled + * surface. + * + * SVGA_CAP2_CURSOR_MOB -- + * Allow the SVGA_REG_CURSOR_MOBID register. + * + * SVGA_CAP2_MSHINT -- + * Allow the SVGA_REG_MSHINT register. + * + * SVGA_CAP2_DX3 -- + * Allows the DefineGBSurface_v4 command. + * Allows the DXDefineDepthStencilView_v2, DXDefineStreamOutputWithMob, + * and DXBindStreamOutput commands if 3D is also available. + * Allows the DXPredStagingCopy and DXStagingCopy commands if SM41 + * is also available. * * SVGA_CAP2_RESERVED -- * Reserve the last bit for extending the SVGA capabilities to some * future mechanisms. */ -#define SVGA_CAP2_NONE 0x00000000 -#define SVGA_CAP2_GROW_OTABLE 0x00000001 -#define SVGA_CAP2_INTRA_SURFACE_COPY 0x00000002 -#define SVGA_CAP2_DX2 0x00000004 -#define SVGA_CAP2_RESERVED 0x80000000 +#define SVGA_CAP2_NONE 0x00000000 +#define SVGA_CAP2_GROW_OTABLE 0x00000001 +#define SVGA_CAP2_INTRA_SURFACE_COPY 0x00000002 +#define SVGA_CAP2_DX2 0x00000004 +#define SVGA_CAP2_GB_MEMSIZE_2 0x00000008 +#define SVGA_CAP2_SCREENDMA_REG 0x00000010 +#define SVGA_CAP2_OTABLE_PTDEPTH_2 0x00000020 +#define SVGA_CAP2_NON_MS_TO_MS_STRETCHBLT 0x00000040 +#define SVGA_CAP2_CURSOR_MOB 0x00000080 +#define SVGA_CAP2_MSHINT 0x00000100 +#define SVGA_CAP2_DX3 0x00000400 +#define SVGA_CAP2_RESERVED 0x80000000 /* @@ -875,7 +987,9 @@ typedef enum { SVGABackdoorCapFifoCaps = 1, SVGABackdoorCap3dHWVersion = 2, SVGABackdoorCapDeviceCaps2 = 3, - SVGABackdoorCapMax = 4, + SVGABackdoorCapDevelCaps = 4, + SVGABackdoorDevelRenderer = 5, + SVGABackdoorCapMax = 6, } SVGABackdoorCapType; @@ -1055,103 +1169,80 @@ enum { /* * FIFO Synchronization Registers * - * This explains the relationship between the various FIFO - * sync-related registers in IOSpace and in FIFO space. - * * SVGA_REG_SYNC -- * - * The SYNC register can be used in two different ways by the guest: + * The SYNC register can be used by the guest driver to signal to the + * device that the guest driver is waiting for previously submitted + * commands to complete. * - * 1. If the guest wishes to fully sync (drain) the FIFO, - * it will write once to SYNC then poll on the BUSY - * register. The FIFO is sync'ed once BUSY is zero. + * When the guest driver writes to the SYNC register, the device sets + * the BUSY register to TRUE, and starts processing the submitted commands + * (if it was not already doing so). When all previously submitted + * commands are finished and the device is idle again, it sets the BUSY + * register back to FALSE. (If the guest driver submits new commands + * after writing the SYNC register, the new commands are not guaranteed + * to have been procesesd.) * - * 2. If the guest wants to asynchronously wake up the host, - * it will write once to SYNC without polling on BUSY. - * Ideally it will do this after some new commands have - * been placed in the FIFO, and after reading a zero - * from SVGA_FIFO_BUSY. + * When guest drivers are submitting commands using the FIFO, the device + * periodically polls to check for new FIFO commands when idle, which may + * introduce a delay in command processing. If the guest-driver wants + * the commands to be processed quickly (which it typically does), it + * should write SYNC after each batch of commands is committed to the + * FIFO to immediately wake up the device. For even better performance, + * the guest can use the SVGA_FIFO_BUSY register to avoid these extra + * SYNC writes if the device is already active, using the technique known + * as "Ringing the Doorbell" (described below). (Note that command + * buffer submission implicitly wakes up the device, and so doesn't + * suffer from this problem.) * - * (1) is the original behaviour that SYNC was designed to - * support. Originally, a write to SYNC would implicitly - * trigger a read from BUSY. This causes us to synchronously - * process the FIFO. - * - * This behaviour has since been changed so that writing SYNC - * will *not* implicitly cause a read from BUSY. Instead, it - * makes a channel call which asynchronously wakes up the MKS - * thread. - * - * New guests can use this new behaviour to implement (2) - * efficiently. This lets guests get the host's attention - * without waiting for the MKS to poll, which gives us much - * better CPU utilization on SMP hosts and on UP hosts while - * we're blocked on the host GPU. - * - * Old guests shouldn't notice the behaviour change. SYNC was - * never guaranteed to process the entire FIFO, since it was - * bounded to a particular number of CPU cycles. Old guests will - * still loop on the BUSY register until the FIFO is empty. - * - * Writing to SYNC currently has the following side-effects: - * - * - Sets SVGA_REG_BUSY to TRUE (in the monitor) - * - Asynchronously wakes up the MKS thread for FIFO processing - * - The value written to SYNC is recorded as a "reason", for - * stats purposes. - * - * If SVGA_FIFO_BUSY is available, drivers are advised to only - * write to SYNC if SVGA_FIFO_BUSY is FALSE. Drivers should set - * SVGA_FIFO_BUSY to TRUE after writing to SYNC. The MKS will - * eventually set SVGA_FIFO_BUSY on its own, but this approach - * lets the driver avoid sending multiple asynchronous wakeup - * messages to the MKS thread. + * The SYNC register can also be used in combination with BUSY to + * synchronously ensure that all SVGA commands are processed (with both + * the FIFO and command-buffers). To do this, the guest driver should + * write to SYNC, and then loop reading BUSY until BUSY returns FALSE. + * This technique is known as a "Legacy Sync". * * SVGA_REG_BUSY -- * * This register is set to TRUE when SVGA_REG_SYNC is written, - * and it reads as FALSE when the FIFO has been completely - * drained. + * and is set back to FALSE when the device has finished processing + * all commands and is idle again. * - * Every read from this register causes us to synchronously - * process FIFO commands. There is no guarantee as to how many - * commands each read will process. + * Every read from the BUSY reigster will block for an undefined + * amount of time (normally until the device finishes some interesting + * work unit), or the device is idle. * - * CPU time spent processing FIFO commands will be billed to - * the guest. - * - * New drivers should avoid using this register unless they - * need to guarantee that the FIFO is completely drained. It - * is overkill for performing a sync-to-fence. Older drivers - * will use this register for any type of synchronization. + * Guest drivers can also do a partial Legacy Sync to check for some + * particular condition, for instance by stopping early when a fence + * passes before BUSY has been set back to FALSE. This is particularly + * useful if the guest-driver knows that it is blocked waiting on the + * device, because it will yield CPU time back to the host. * * SVGA_FIFO_BUSY -- * - * This register is a fast way for the guest driver to check - * whether the FIFO is already being processed. It reads and - * writes at normal RAM speeds, with no monitor intervention. + * The SVGA_FIFO_BUSY register is a fast way for the guest driver to check + * whether the device is actively processing FIFO commands before writing + * the more expensive SYNC register. * - * If this register reads as TRUE, the host is guaranteeing that - * any new commands written into the FIFO will be noticed before - * the MKS goes back to sleep. + * If this register reads as TRUE, the device is actively processing + * FIFO commands. * - * If this register reads as FALSE, no such guarantee can be - * made. + * If this register reads as FALSE, the device may not be actively + * processing commands, and the guest driver should try + * "Ringing the Doorbell". * - * The guest should use this register to quickly determine - * whether or not it needs to wake up the host. If the guest - * just wrote a command or group of commands that it would like - * the host to begin processing, it should: + * To Ring the Doorbell, the guest should: * - * 1. Read SVGA_FIFO_BUSY. If it reads as TRUE, no further - * action is necessary. + * 1. Have already written their batch of commands into the FIFO. + * 2. Check if the SVGA_FIFO_BUSY register is available by reading + * SVGA_FIFO_MIN. + * 3. Read SVGA_FIFO_BUSY. If it reads as TRUE, the device is actively + * processing FIFO commands, and no further action is necessary. + * 4. If SVGA_FIFO_BUSY was FALSE, write TRUE to SVGA_REG_SYNC. * - * 2. Write TRUE to SVGA_FIFO_BUSY. This informs future guest - * code that we've already sent a SYNC to the host and we - * don't need to send a duplicate. - * - * 3. Write a reason to SVGA_REG_SYNC. This will send an - * asynchronous wakeup to the MKS thread. + * For maximum performance, this procedure should be followed after + * every meaningful batch of commands has been written into the FIFO. + * (Normally when the underlying application signals it's finished a + * meaningful work unit by calling Flush.) */ @@ -1164,9 +1255,6 @@ enum { * Video -- SVGA Video overlay units are supported * Escape -- Escape command is supported * - * XXX: Add longer descriptions for each capability, including a list - * of the new features that each capability provides. - * * SVGA_FIFO_CAP_SCREEN_OBJECT -- * * Provides dynamic multi-screen rendering, for improved Unity and @@ -1278,6 +1366,15 @@ enum { #define SVGA_FIFO_RESERVED_UNKNOWN 0xffffffff +/* + * ScreenDMA Register Values + */ + +#define SVGA_SCREENDMA_REG_UNDEFINED 0 +#define SVGA_SCREENDMA_REG_NOT_PRESENT 1 +#define SVGA_SCREENDMA_REG_PRESENT 2 +#define SVGA_SCREENDMA_REG_MAX 3 + /* * Video overlay support */ @@ -1664,6 +1761,80 @@ struct { SVGAFifoCmdDefineAlphaCursor; +/* + * Provide a new large cursor image, as an AND/XOR mask. + * + * Should only be used for CursorMob functionality + */ + +typedef +#include "vmware_pack_begin.h" +struct { + uint32 hotspotX; + uint32 hotspotY; + uint32 width; + uint32 height; + uint32 andMaskDepth; + uint32 xorMaskDepth; + /* + * Followed by scanline data for AND mask, then XOR mask. + * Each scanline is padded to a 32-bit boundary. + */ +} +#include "vmware_pack_end.h" +SVGAGBColorCursorHeader; + + +/* + * Provide a new large cursor image, in 32-bit BGRA format. + * + * Should only be used for CursorMob functionality + */ + +typedef +#include "vmware_pack_begin.h" +struct { + uint32 hotspotX; + uint32 hotspotY; + uint32 width; + uint32 height; + /* Followed by scanline data */ +} +#include "vmware_pack_end.h" +SVGAGBAlphaCursorHeader; + + /* + * Define the SVGA guest backed cursor types + */ + +typedef enum { + SVGA_COLOR_CURSOR = 0, + SVGA_ALPHA_CURSOR = 1, +} SVGAGBCursorType; + +/* + * Provide a new large cursor image. + * + * Should only be used for CursorMob functionality + */ + +typedef +#include "vmware_pack_begin.h" +struct { + SVGAGBCursorType type; + union { + SVGAGBColorCursorHeader colorHeader; + SVGAGBAlphaCursorHeader alphaHeader; + } header; + uint32 sizeInBytes; + /* + * Followed by the cursor data + */ +} +#include "vmware_pack_end.h" +SVGAGBCursorHeader; + + /* * SVGA_CMD_UPDATE_VERBOSE -- * @@ -2061,9 +2232,12 @@ SVGAFifoCmdRemapGMR2; #define SVGA_VRAM_MAX_SIZE (128 * 1024 * 1024) #define SVGA_MEMORY_SIZE_MAX (1024 * 1024 * 1024) #define SVGA_FIFO_SIZE_MAX (2 * 1024 * 1024) -#define SVGA_GRAPHICS_MEMORY_KB_MIN (32 * 1024) -#define SVGA_GRAPHICS_MEMORY_KB_MAX (2 * 1024 * 1024) -#define SVGA_GRAPHICS_MEMORY_KB_DEFAULT (256 * 1024) +#define SVGA_GRAPHICS_MEMORY_KB_MIN (32 * 1024) +#define SVGA_GRAPHICS_MEMORY_KB_MAX_2GB (2 * 1024 * 1024) +#define SVGA_GRAPHICS_MEMORY_KB_MAX_3GB (3 * 1024 * 1024) +#define SVGA_GRAPHICS_MEMORY_KB_MAX_4GB (4 * 1024 * 1024) +#define SVGA_GRAPHICS_MEMORY_KB_MAX_8GB (8 * 1024 * 1024) +#define SVGA_GRAPHICS_MEMORY_KB_DEFAULT (256 * 1024) #define SVGA_VRAM_SIZE_W2K (64 * 1024 * 1024) /* 64 MB */ @@ -2086,4 +2260,6 @@ SVGAFifoCmdRemapGMR2; #define SVGA_FIFO_SIZE_GBOBJECTS (256 * 1024) #define SVGA_VRAM_SIZE_GBOBJECTS (4 * 1024 * 1024) +#define SVGA_PCI_REGS_PAGES (1) + #endif diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga_types.h b/drivers/gpu/drm/vmwgfx/device_include/svga_types.h index 350bbc6fab02..beddccee40f6 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga_types.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga_types.h @@ -37,6 +37,7 @@ typedef s8 int8; typedef uint64 PA; typedef uint32 PPN; +typedef uint32 PPN32; typedef uint64 PPN64; typedef bool Bool; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c index 66e14e38d5e8..f41550797970 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c @@ -57,9 +57,11 @@ #define VMW_BINDING_RT_BIT 0 #define VMW_BINDING_PS_BIT 1 -#define VMW_BINDING_SO_BIT 2 +#define VMW_BINDING_SO_T_BIT 2 #define VMW_BINDING_VB_BIT 3 -#define VMW_BINDING_NUM_BITS 4 +#define VMW_BINDING_UAV_BIT 4 +#define VMW_BINDING_CS_UAV_BIT 5 +#define VMW_BINDING_NUM_BITS 6 #define VMW_BINDING_PS_SR_BIT 0 @@ -75,6 +77,8 @@ * @vertex_buffers: Vertex buffer bindings. * @index_buffer: Index buffer binding. * @per_shader: Per shader-type bindings. + * @ua_views: UAV bindings. + * @so_state: StreamOutput bindings. * @dirty: Bitmap tracking per binding-type changes that have not yet * been emitted to the device. * @dirty_vb: Bitmap tracking individual vertex buffer binding changes that @@ -95,10 +99,12 @@ struct vmw_ctx_binding_state { struct vmw_ctx_bindinfo_view render_targets[SVGA3D_RT_MAX]; struct vmw_ctx_bindinfo_tex texture_units[SVGA3D_NUM_TEXTURE_UNITS]; struct vmw_ctx_bindinfo_view ds_view; - struct vmw_ctx_bindinfo_so so_targets[SVGA3D_DX_MAX_SOTARGETS]; + struct vmw_ctx_bindinfo_so_target so_targets[SVGA3D_DX_MAX_SOTARGETS]; struct vmw_ctx_bindinfo_vb vertex_buffers[SVGA3D_DX_MAX_VERTEXBUFFERS]; struct vmw_ctx_bindinfo_ib index_buffer; - struct vmw_dx_shader_bindings per_shader[SVGA3D_NUM_SHADERTYPE_DX10]; + struct vmw_dx_shader_bindings per_shader[SVGA3D_NUM_SHADERTYPE]; + struct vmw_ctx_bindinfo_uav ua_views[VMW_MAX_UAV_BIND_TYPE]; + struct vmw_ctx_bindinfo_so so_state; unsigned long dirty; DECLARE_BITMAP(dirty_vb, SVGA3D_DX_MAX_VERTEXBUFFERS); @@ -115,12 +121,16 @@ static int vmw_binding_scrub_texture(struct vmw_ctx_bindinfo *bi, bool rebind); static int vmw_binding_scrub_cb(struct vmw_ctx_bindinfo *bi, bool rebind); static int vmw_binding_scrub_dx_rt(struct vmw_ctx_bindinfo *bi, bool rebind); static int vmw_binding_scrub_sr(struct vmw_ctx_bindinfo *bi, bool rebind); -static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind); +static int vmw_binding_scrub_so_target(struct vmw_ctx_bindinfo *bi, bool rebind); static int vmw_binding_emit_dirty(struct vmw_ctx_binding_state *cbs); static int vmw_binding_scrub_dx_shader(struct vmw_ctx_bindinfo *bi, bool rebind); static int vmw_binding_scrub_ib(struct vmw_ctx_bindinfo *bi, bool rebind); static int vmw_binding_scrub_vb(struct vmw_ctx_bindinfo *bi, bool rebind); +static int vmw_binding_scrub_uav(struct vmw_ctx_bindinfo *bi, bool rebind); +static int vmw_binding_scrub_cs_uav(struct vmw_ctx_bindinfo *bi, bool rebind); +static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind); + static void vmw_binding_build_asserts(void) __attribute__ ((unused)); typedef int (*vmw_scrub_func)(struct vmw_ctx_bindinfo *, bool); @@ -151,6 +161,9 @@ static const size_t vmw_binding_shader_offsets[] = { offsetof(struct vmw_ctx_binding_state, per_shader[0].shader), offsetof(struct vmw_ctx_binding_state, per_shader[1].shader), offsetof(struct vmw_ctx_binding_state, per_shader[2].shader), + offsetof(struct vmw_ctx_binding_state, per_shader[3].shader), + offsetof(struct vmw_ctx_binding_state, per_shader[4].shader), + offsetof(struct vmw_ctx_binding_state, per_shader[5].shader), }; static const size_t vmw_binding_rt_offsets[] = { offsetof(struct vmw_ctx_binding_state, render_targets), @@ -162,6 +175,9 @@ static const size_t vmw_binding_cb_offsets[] = { offsetof(struct vmw_ctx_binding_state, per_shader[0].const_buffers), offsetof(struct vmw_ctx_binding_state, per_shader[1].const_buffers), offsetof(struct vmw_ctx_binding_state, per_shader[2].const_buffers), + offsetof(struct vmw_ctx_binding_state, per_shader[3].const_buffers), + offsetof(struct vmw_ctx_binding_state, per_shader[4].const_buffers), + offsetof(struct vmw_ctx_binding_state, per_shader[5].const_buffers), }; static const size_t vmw_binding_dx_ds_offsets[] = { offsetof(struct vmw_ctx_binding_state, ds_view), @@ -170,8 +186,11 @@ static const size_t vmw_binding_sr_offsets[] = { offsetof(struct vmw_ctx_binding_state, per_shader[0].shader_res), offsetof(struct vmw_ctx_binding_state, per_shader[1].shader_res), offsetof(struct vmw_ctx_binding_state, per_shader[2].shader_res), + offsetof(struct vmw_ctx_binding_state, per_shader[3].shader_res), + offsetof(struct vmw_ctx_binding_state, per_shader[4].shader_res), + offsetof(struct vmw_ctx_binding_state, per_shader[5].shader_res), }; -static const size_t vmw_binding_so_offsets[] = { +static const size_t vmw_binding_so_target_offsets[] = { offsetof(struct vmw_ctx_binding_state, so_targets), }; static const size_t vmw_binding_vb_offsets[] = { @@ -180,6 +199,15 @@ static const size_t vmw_binding_vb_offsets[] = { static const size_t vmw_binding_ib_offsets[] = { offsetof(struct vmw_ctx_binding_state, index_buffer), }; +static const size_t vmw_binding_uav_offsets[] = { + offsetof(struct vmw_ctx_binding_state, ua_views[0].views), +}; +static const size_t vmw_binding_cs_uav_offsets[] = { + offsetof(struct vmw_ctx_binding_state, ua_views[1].views), +}; +static const size_t vmw_binding_so_offsets[] = { + offsetof(struct vmw_ctx_binding_state, so_state), +}; static const struct vmw_binding_info vmw_binding_infos[] = { [vmw_ctx_binding_shader] = { @@ -214,10 +242,10 @@ static const struct vmw_binding_info vmw_binding_infos[] = { .size = sizeof(struct vmw_ctx_bindinfo_view), .offsets = vmw_binding_dx_ds_offsets, .scrub_func = vmw_binding_scrub_dx_rt}, - [vmw_ctx_binding_so] = { - .size = sizeof(struct vmw_ctx_bindinfo_so), - .offsets = vmw_binding_so_offsets, - .scrub_func = vmw_binding_scrub_so}, + [vmw_ctx_binding_so_target] = { + .size = sizeof(struct vmw_ctx_bindinfo_so_target), + .offsets = vmw_binding_so_target_offsets, + .scrub_func = vmw_binding_scrub_so_target}, [vmw_ctx_binding_vb] = { .size = sizeof(struct vmw_ctx_bindinfo_vb), .offsets = vmw_binding_vb_offsets, @@ -226,6 +254,18 @@ static const struct vmw_binding_info vmw_binding_infos[] = { .size = sizeof(struct vmw_ctx_bindinfo_ib), .offsets = vmw_binding_ib_offsets, .scrub_func = vmw_binding_scrub_ib}, + [vmw_ctx_binding_uav] = { + .size = sizeof(struct vmw_ctx_bindinfo_view), + .offsets = vmw_binding_uav_offsets, + .scrub_func = vmw_binding_scrub_uav}, + [vmw_ctx_binding_cs_uav] = { + .size = sizeof(struct vmw_ctx_bindinfo_view), + .offsets = vmw_binding_cs_uav_offsets, + .scrub_func = vmw_binding_scrub_cs_uav}, + [vmw_ctx_binding_so] = { + .size = sizeof(struct vmw_ctx_bindinfo_so), + .offsets = vmw_binding_so_offsets, + .scrub_func = vmw_binding_scrub_so}, }; /** @@ -311,6 +351,18 @@ void vmw_binding_add(struct vmw_ctx_binding_state *cbs, INIT_LIST_HEAD(&loc->res_list); } +/** + * vmw_binding_add_uav_index - Add UAV index for tracking. + * @cbs: Pointer to the context binding state tracker. + * @slot: UAV type to which bind this index. + * @index: The splice index to track. + */ +void vmw_binding_add_uav_index(struct vmw_ctx_binding_state *cbs, uint32 slot, + uint32 index) +{ + cbs->ua_views[slot].index = index; +} + /** * vmw_binding_transfer: Transfer a context binding tracking entry. * @@ -450,6 +502,10 @@ void vmw_binding_state_commit(struct vmw_ctx_binding_state *to, vmw_binding_transfer(to, from, entry); vmw_binding_drop(entry); } + + /* Also transfer uav splice indices */ + to->ua_views[0].index = from->ua_views[0].index; + to->ua_views[1].index = from->ua_views[1].index; } /** @@ -828,8 +884,8 @@ static void vmw_collect_so_targets(struct vmw_ctx_binding_state *cbs, const struct vmw_ctx_bindinfo *bi, u32 max_num) { - const struct vmw_ctx_bindinfo_so *biso = - container_of(bi, struct vmw_ctx_bindinfo_so, bi); + const struct vmw_ctx_bindinfo_so_target *biso = + container_of(bi, struct vmw_ctx_bindinfo_so_target, bi); unsigned long i; SVGA3dSoTarget *so_buffer = (SVGA3dSoTarget *) cbs->bind_cmd_buffer; @@ -854,11 +910,11 @@ static void vmw_collect_so_targets(struct vmw_ctx_binding_state *cbs, } /** - * vmw_binding_emit_set_so - Issue delayed streamout binding commands + * vmw_emit_set_so_target - Issue delayed streamout binding commands * * @cbs: Pointer to the context's struct vmw_ctx_binding_state */ -static int vmw_emit_set_so(struct vmw_ctx_binding_state *cbs) +static int vmw_emit_set_so_target(struct vmw_ctx_binding_state *cbs) { const struct vmw_ctx_bindinfo *loc = &cbs->so_targets[0].bi; struct { @@ -1005,6 +1061,66 @@ static int vmw_emit_set_vb(struct vmw_ctx_binding_state *cbs) return 0; } +static int vmw_emit_set_uav(struct vmw_ctx_binding_state *cbs) +{ + const struct vmw_ctx_bindinfo *loc = &cbs->ua_views[0].views[0].bi; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXSetUAViews body; + } *cmd; + size_t cmd_size, view_id_size; + const struct vmw_resource *ctx = vmw_cbs_context(cbs); + + vmw_collect_view_ids(cbs, loc, SVGA3D_MAX_UAVIEWS); + view_id_size = cbs->bind_cmd_count*sizeof(uint32); + cmd_size = sizeof(*cmd) + view_id_size; + cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id); + if (!cmd) + return -ENOMEM; + + cmd->header.id = SVGA_3D_CMD_DX_SET_UA_VIEWS; + cmd->header.size = sizeof(cmd->body) + view_id_size; + + /* Splice index is specified user-space */ + cmd->body.uavSpliceIndex = cbs->ua_views[0].index; + + memcpy(&cmd[1], cbs->bind_cmd_buffer, view_id_size); + + vmw_fifo_commit(ctx->dev_priv, cmd_size); + + return 0; +} + +static int vmw_emit_set_cs_uav(struct vmw_ctx_binding_state *cbs) +{ + const struct vmw_ctx_bindinfo *loc = &cbs->ua_views[1].views[0].bi; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXSetCSUAViews body; + } *cmd; + size_t cmd_size, view_id_size; + const struct vmw_resource *ctx = vmw_cbs_context(cbs); + + vmw_collect_view_ids(cbs, loc, SVGA3D_MAX_UAVIEWS); + view_id_size = cbs->bind_cmd_count*sizeof(uint32); + cmd_size = sizeof(*cmd) + view_id_size; + cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id); + if (!cmd) + return -ENOMEM; + + cmd->header.id = SVGA_3D_CMD_DX_SET_CS_UA_VIEWS; + cmd->header.size = sizeof(cmd->body) + view_id_size; + + /* Start index is specified user-space */ + cmd->body.startIndex = cbs->ua_views[1].index; + + memcpy(&cmd[1], cbs->bind_cmd_buffer, view_id_size); + + vmw_fifo_commit(ctx->dev_priv, cmd_size); + + return 0; +} + /** * vmw_binding_emit_dirty - Issue delayed binding commands * @@ -1030,12 +1146,18 @@ static int vmw_binding_emit_dirty(struct vmw_ctx_binding_state *cbs) case VMW_BINDING_PS_BIT: ret = vmw_binding_emit_dirty_ps(cbs); break; - case VMW_BINDING_SO_BIT: - ret = vmw_emit_set_so(cbs); + case VMW_BINDING_SO_T_BIT: + ret = vmw_emit_set_so_target(cbs); break; case VMW_BINDING_VB_BIT: ret = vmw_emit_set_vb(cbs); break; + case VMW_BINDING_UAV_BIT: + ret = vmw_emit_set_uav(cbs); + break; + case VMW_BINDING_CS_UAV_BIT: + ret = vmw_emit_set_cs_uav(cbs); + break; default: BUG(); } @@ -1089,18 +1211,18 @@ static int vmw_binding_scrub_dx_rt(struct vmw_ctx_bindinfo *bi, bool rebind) } /** - * vmw_binding_scrub_so - Schedule a dx streamoutput buffer binding + * vmw_binding_scrub_so_target - Schedule a dx streamoutput buffer binding * scrub from a context * * @bi: single binding information. * @rebind: Whether to issue a bind instead of scrub command. */ -static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind) +static int vmw_binding_scrub_so_target(struct vmw_ctx_bindinfo *bi, bool rebind) { struct vmw_ctx_binding_state *cbs = vmw_context_binding_state(bi->ctx); - __set_bit(VMW_BINDING_SO_BIT, &cbs->dirty); + __set_bit(VMW_BINDING_SO_T_BIT, &cbs->dirty); return 0; } @@ -1162,6 +1284,49 @@ static int vmw_binding_scrub_ib(struct vmw_ctx_bindinfo *bi, bool rebind) return 0; } +static int vmw_binding_scrub_uav(struct vmw_ctx_bindinfo *bi, bool rebind) +{ + struct vmw_ctx_binding_state *cbs = vmw_context_binding_state(bi->ctx); + + __set_bit(VMW_BINDING_UAV_BIT, &cbs->dirty); + return 0; +} + +static int vmw_binding_scrub_cs_uav(struct vmw_ctx_bindinfo *bi, bool rebind) +{ + struct vmw_ctx_binding_state *cbs = vmw_context_binding_state(bi->ctx); + + __set_bit(VMW_BINDING_CS_UAV_BIT, &cbs->dirty); + return 0; +} + +/** + * vmw_binding_scrub_so - Scrub a streamoutput binding from context. + * @bi: Single binding information. + * @rebind: Whether to issue a bind instead of scrub command. + */ +static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind) +{ + struct vmw_ctx_bindinfo_so *binding = + container_of(bi, typeof(*binding), bi); + struct vmw_private *dev_priv = bi->ctx->dev_priv; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXSetStreamOutput body; + } *cmd; + + cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), bi->ctx->id); + if (!cmd) + return -ENOMEM; + + cmd->header.id = SVGA_3D_CMD_DX_SET_STREAMOUTPUT; + cmd->header.size = sizeof(cmd->body); + cmd->body.soid = rebind ? bi->res->id : SVGA3D_INVALID_ID; + vmw_fifo_commit(dev_priv, sizeof(*cmd)); + + return 0; +} + /** * vmw_binding_state_alloc - Allocate a struct vmw_ctx_binding_state with * memory accounting. @@ -1248,8 +1413,8 @@ void vmw_binding_state_reset(struct vmw_ctx_binding_state *cbs) * Each time a resource is put on the validation list as the result of a * context binding referencing it, we need to determine whether that resource * will be dirtied (written to by the GPU) as a result of the corresponding - * GPU operation. Currently rendertarget-, depth-stencil-, and - * stream-output-target bindings are capable of dirtying its resource. + * GPU operation. Currently rendertarget-, depth-stencil-, stream-output-target + * and unordered access view bindings are capable of dirtying its resource. * * Return: Whether the binding type dirties the resource its binding points to. */ @@ -1259,11 +1424,13 @@ u32 vmw_binding_dirtying(enum vmw_ctx_binding_type binding_type) [vmw_ctx_binding_rt] = VMW_RES_DIRTY_SET, [vmw_ctx_binding_dx_rt] = VMW_RES_DIRTY_SET, [vmw_ctx_binding_ds] = VMW_RES_DIRTY_SET, - [vmw_ctx_binding_so] = VMW_RES_DIRTY_SET, + [vmw_ctx_binding_so_target] = VMW_RES_DIRTY_SET, + [vmw_ctx_binding_uav] = VMW_RES_DIRTY_SET, + [vmw_ctx_binding_cs_uav] = VMW_RES_DIRTY_SET, }; /* Review this function as new bindings are added. */ - BUILD_BUG_ON(vmw_ctx_binding_max != 11); + BUILD_BUG_ON(vmw_ctx_binding_max != 14); return is_binding_dirtying[binding_type]; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h index cd9805c045cb..dcb71fd0bb3b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h @@ -33,6 +33,8 @@ #define VMW_MAX_VIEW_BINDINGS 128 +#define VMW_MAX_UAV_BIND_TYPE 2 + struct vmw_private; struct vmw_ctx_binding_state; @@ -48,9 +50,12 @@ enum vmw_ctx_binding_type { vmw_ctx_binding_dx_rt, vmw_ctx_binding_sr, vmw_ctx_binding_ds, - vmw_ctx_binding_so, + vmw_ctx_binding_so_target, vmw_ctx_binding_vb, vmw_ctx_binding_ib, + vmw_ctx_binding_uav, + vmw_ctx_binding_cs_uav, + vmw_ctx_binding_so, vmw_ctx_binding_max }; @@ -128,14 +133,14 @@ struct vmw_ctx_bindinfo_view { }; /** - * struct vmw_ctx_bindinfo_so - StreamOutput binding metadata + * struct vmw_ctx_bindinfo_so_target - StreamOutput binding metadata * * @bi: struct vmw_ctx_bindinfo we derive from. * @offset: Device data used to reconstruct binding command. * @size: Device data used to reconstruct binding command. * @slot: Device data used to reconstruct binding command. */ -struct vmw_ctx_bindinfo_so { +struct vmw_ctx_bindinfo_so_target { struct vmw_ctx_bindinfo bi; uint32 offset; uint32 size; @@ -189,9 +194,31 @@ struct vmw_dx_shader_bindings { unsigned long dirty; }; +/** + * struct vmw_ctx_bindinfo_uav - UAV context binding state. + * @views: UAV view bindings. + * @splice_index: The device splice index set by user-space. + */ +struct vmw_ctx_bindinfo_uav { + struct vmw_ctx_bindinfo_view views[SVGA3D_MAX_UAVIEWS]; + uint32 index; +}; + +/** + * struct vmw_ctx_bindinfo_so - Stream output binding metadata. + * @bi: struct vmw_ctx_bindinfo we derive from. + * @slot: Device data used to reconstruct binding command. + */ +struct vmw_ctx_bindinfo_so { + struct vmw_ctx_bindinfo bi; + uint32 slot; +}; + extern void vmw_binding_add(struct vmw_ctx_binding_state *cbs, const struct vmw_ctx_bindinfo *ci, u32 shader_slot, u32 slot); +extern void vmw_binding_add_uav_index(struct vmw_ctx_binding_state *cbs, + uint32 slot, uint32 splice_index); extern void vmw_binding_state_commit(struct vmw_ctx_binding_state *to, struct vmw_ctx_binding_state *from); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c index a56c9d802382..61c246335e66 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c @@ -36,7 +36,7 @@ struct vmw_user_context { struct vmw_resource res; struct vmw_ctx_binding_state *cbs; struct vmw_cmdbuf_res_manager *man; - struct vmw_resource *cotables[SVGA_COTABLE_DX10_MAX]; + struct vmw_resource *cotables[SVGA_COTABLE_MAX]; spinlock_t cotable_lock; struct vmw_buffer_object *dx_query_mob; }; @@ -116,12 +116,15 @@ static const struct vmw_res_func vmw_dx_context_func = { * Context management: */ -static void vmw_context_cotables_unref(struct vmw_user_context *uctx) +static void vmw_context_cotables_unref(struct vmw_private *dev_priv, + struct vmw_user_context *uctx) { struct vmw_resource *res; int i; + u32 cotable_max = has_sm5_context(dev_priv) ? + SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX; - for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) { + for (i = 0; i < cotable_max; ++i) { spin_lock(&uctx->cotable_lock); res = uctx->cotables[i]; uctx->cotables[i] = NULL; @@ -155,7 +158,7 @@ static void vmw_hw_context_destroy(struct vmw_resource *res) !dev_priv->query_cid_valid) __vmw_execbuf_release_pinned_bo(dev_priv, NULL); mutex_unlock(&dev_priv->cmdbuf_mutex); - vmw_context_cotables_unref(uctx); + vmw_context_cotables_unref(dev_priv, uctx); return; } @@ -208,7 +211,9 @@ static int vmw_gb_context_init(struct vmw_private *dev_priv, spin_lock_init(&uctx->cotable_lock); if (dx) { - for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) { + u32 cotable_max = has_sm5_context(dev_priv) ? + SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX; + for (i = 0; i < cotable_max; ++i) { uctx->cotables[i] = vmw_cotable_alloc(dev_priv, &uctx->res, i); if (IS_ERR(uctx->cotables[i])) { @@ -222,7 +227,7 @@ static int vmw_gb_context_init(struct vmw_private *dev_priv, return 0; out_cotables: - vmw_context_cotables_unref(uctx); + vmw_context_cotables_unref(dev_priv, uctx); out_err: if (res_free) res_free(res); @@ -545,10 +550,12 @@ void vmw_dx_context_scrub_cotables(struct vmw_resource *ctx, { struct vmw_user_context *uctx = container_of(ctx, struct vmw_user_context, res); + u32 cotable_max = has_sm5_context(ctx->dev_priv) ? + SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX; int i; vmw_binding_state_scrub(uctx->cbs); - for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) { + for (i = 0; i < cotable_max; ++i) { struct vmw_resource *res; /* Avoid racing with ongoing cotable destruction. */ @@ -731,7 +738,7 @@ static int vmw_context_define(struct drm_device *dev, void *data, }; int ret; - if (!dev_priv->has_dx && dx) { + if (!has_sm4_context(dev_priv) && dx) { VMW_DEBUG_USER("DX contexts not supported by device.\n"); return -EINVAL; } @@ -839,7 +846,10 @@ struct vmw_cmdbuf_res_manager *vmw_context_res_man(struct vmw_resource *ctx) struct vmw_resource *vmw_context_cotable(struct vmw_resource *ctx, SVGACOTableType cotable_type) { - if (cotable_type >= SVGA_COTABLE_DX10_MAX) + u32 cotable_max = has_sm5_context(ctx->dev_priv) ? + SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX; + + if (cotable_type >= cotable_max) return ERR_PTR(-EINVAL); return container_of(ctx, struct vmw_user_context, res)-> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c index 3ca5cf375b01..65e8e7a97724 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c @@ -80,9 +80,10 @@ static const struct vmw_cotable_info co_info[] = { {1, sizeof(SVGACOTableDXDepthStencilEntry), NULL}, {1, sizeof(SVGACOTableDXRasterizerStateEntry), NULL}, {1, sizeof(SVGACOTableDXSamplerEntry), NULL}, - {1, sizeof(SVGACOTableDXStreamOutputEntry), NULL}, + {1, sizeof(SVGACOTableDXStreamOutputEntry), &vmw_dx_streamoutput_cotable_list_scrub}, {1, sizeof(SVGACOTableDXQueryEntry), NULL}, - {1, sizeof(SVGACOTableDXShaderEntry), &vmw_dx_shader_cotable_list_scrub} + {1, sizeof(SVGACOTableDXShaderEntry), &vmw_dx_shader_cotable_list_scrub}, + {1, sizeof(SVGACOTableDXUAViewEntry), &vmw_view_cotable_list_destroy} }; /* @@ -102,6 +103,7 @@ const SVGACOTableType vmw_cotable_scrub_order[] = { SVGA_COTABLE_SAMPLER, SVGA_COTABLE_STREAMOUTPUT, SVGA_COTABLE_DXQUERY, + SVGA_COTABLE_UAVIEW, }; static int vmw_cotable_bind(struct vmw_resource *res, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 4f58364421ce..71e45b568511 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -290,6 +290,8 @@ static void vmw_print_capabilities2(uint32_t capabilities2) DRM_INFO(" Grow oTable.\n"); if (capabilities2 & SVGA_CAP2_INTRA_SURFACE_COPY) DRM_INFO(" IntraSurface copy.\n"); + if (capabilities2 & SVGA_CAP2_DX3) + DRM_INFO(" DX3.\n"); } static void vmw_print_capabilities(uint32_t capabilities) @@ -449,7 +451,7 @@ static int vmw_request_device(struct vmw_private *dev_priv) dev_priv->cman = vmw_cmdbuf_man_create(dev_priv); if (IS_ERR(dev_priv->cman)) { dev_priv->cman = NULL; - dev_priv->has_dx = false; + dev_priv->sm_type = VMW_SM_LEGACY; } ret = vmw_request_device_late(dev_priv); @@ -718,9 +720,15 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) dev_priv->max_mob_pages = 0; dev_priv->max_mob_size = 0; if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) { - uint64_t mem_size = - vmw_read(dev_priv, - SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB); + uint64_t mem_size; + + if (dev_priv->capabilities2 & SVGA_CAP2_GB_MEMSIZE_2) + mem_size = vmw_read(dev_priv, + SVGA_REG_GBOBJECT_MEM_SIZE_KB); + else + mem_size = + vmw_read(dev_priv, + SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB); /* * Workaround for low memory 2D VMs to compensate for the @@ -883,14 +891,32 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) } } - if (dev_priv->has_mob) { + if (dev_priv->has_mob && (dev_priv->capabilities & SVGA_CAP_DX)) { spin_lock(&dev_priv->cap_lock); vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_DXCONTEXT); - dev_priv->has_dx = !!vmw_read(dev_priv, SVGA_REG_DEV_CAP); + if (vmw_read(dev_priv, SVGA_REG_DEV_CAP)) + dev_priv->sm_type = VMW_SM_4; spin_unlock(&dev_priv->cap_lock); } vmw_validation_mem_init_ttm(dev_priv, VMWGFX_VALIDATION_MEM_GRAN); + + /* SVGA_CAP2_DX2 (DefineGBSurface_v3) is needed for SM4_1 support */ + if (has_sm4_context(dev_priv) && + (dev_priv->capabilities2 & SVGA_CAP2_DX2)) { + vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_SM41); + + if (vmw_read(dev_priv, SVGA_REG_DEV_CAP)) + dev_priv->sm_type = VMW_SM_4_1; + + if (has_sm4_1_context(dev_priv) && + (dev_priv->capabilities2 & SVGA_CAP2_DX3)) { + vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_SM5); + if (vmw_read(dev_priv, SVGA_REG_DEV_CAP)) + dev_priv->sm_type = VMW_SM_5; + } + } + ret = vmw_kms_init(dev_priv); if (unlikely(ret != 0)) goto out_no_kms; @@ -900,23 +926,14 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) if (ret) goto out_no_fifo; - if (dev_priv->has_dx) { - /* - * SVGA_CAP2_DX2 (DefineGBSurface_v3) is needed for SM4_1 - * support - */ - if ((dev_priv->capabilities2 & SVGA_CAP2_DX2) != 0) { - vmw_write(dev_priv, SVGA_REG_DEV_CAP, - SVGA3D_DEVCAP_SM41); - dev_priv->has_sm4_1 = vmw_read(dev_priv, - SVGA_REG_DEV_CAP); - } - } - - DRM_INFO("DX: %s\n", dev_priv->has_dx ? "yes." : "no."); DRM_INFO("Atomic: %s\n", (dev->driver->driver_features & DRIVER_ATOMIC) ? "yes." : "no."); - DRM_INFO("SM4_1: %s\n", dev_priv->has_sm4_1 ? "yes." : "no."); + if (dev_priv->sm_type == VMW_SM_5) + DRM_INFO("SM5 support available.\n"); + if (dev_priv->sm_type == VMW_SM_4_1) + DRM_INFO("SM4_1 support available.\n"); + if (dev_priv->sm_type == VMW_SM_4) + DRM_INFO("SM4 support available.\n"); snprintf(host_log, sizeof(host_log), "vmwgfx: %s-%s", VMWGFX_REPO, VMWGFX_GIT_VERSION); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index b70d73225707..5ddbcb9f6df4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -58,7 +58,7 @@ #define VMWGFX_DRIVER_NAME "vmwgfx" #define VMWGFX_DRIVER_DATE "20200114" #define VMWGFX_DRIVER_MAJOR 2 -#define VMWGFX_DRIVER_MINOR 17 +#define VMWGFX_DRIVER_MINOR 18 #define VMWGFX_DRIVER_PATCHLEVEL 0 #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) #define VMWGFX_MAX_RELOCATIONS 2048 @@ -202,6 +202,7 @@ enum vmw_res_type { vmw_res_dx_context, vmw_res_cotable, vmw_res_view, + vmw_res_streamoutput, vmw_res_max }; @@ -210,7 +211,8 @@ enum vmw_res_type { */ enum vmw_cmdbuf_res_type { vmw_cmdbuf_res_shader, - vmw_cmdbuf_res_view + vmw_cmdbuf_res_view, + vmw_cmdbuf_res_streamoutput }; struct vmw_cmdbuf_res_manager; @@ -223,24 +225,58 @@ struct vmw_cursor_snooper { struct vmw_framebuffer; struct vmw_surface_offset; -struct vmw_surface { - struct vmw_resource res; - SVGA3dSurfaceAllFlags flags; - uint32_t format; - uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES]; +/** + * struct vmw_surface_metadata - Metadata describing a surface. + * + * @flags: Device flags. + * @format: Surface SVGA3D_x format. + * @mip_levels: Mip level for each face. For GB first index is used only. + * @multisample_count: Sample count. + * @multisample_pattern: Sample patterns. + * @quality_level: Quality level. + * @autogen_filter: Filter for automatically generated mipmaps. + * @array_size: Number of array elements for a 1D/2D texture. For cubemap + texture number of faces * array_size. This should be 0 for pre + SM4 device. + * @buffer_byte_stride: Buffer byte stride. + * @num_sizes: Size of @sizes. For GB surface this should always be 1. + * @base_size: Surface dimension. + * @sizes: Array representing mip sizes. Legacy only. + * @scanout: Whether this surface will be used for scanout. + * + * This tracks metadata for both legacy and guest backed surface. + */ +struct vmw_surface_metadata { + u64 flags; + u32 format; + u32 mip_levels[DRM_VMW_MAX_SURFACE_FACES]; + u32 multisample_count; + u32 multisample_pattern; + u32 quality_level; + u32 autogen_filter; + u32 array_size; + u32 num_sizes; + u32 buffer_byte_stride; struct drm_vmw_size base_size; struct drm_vmw_size *sizes; - uint32_t num_sizes; bool scanout; - uint32_t array_size; - /* TODO so far just a extra pointer */ +}; + +/** + * struct vmw_surface: Resource structure for a surface. + * + * @res: The base resource for this surface. + * @metadata: Metadata for this surface resource. + * @snooper: Cursor data. Legacy surface only. + * @offsets: Legacy surface only. + * @view_list: List of views bound to this surface. + */ +struct vmw_surface { + struct vmw_resource res; + struct vmw_surface_metadata metadata; struct vmw_cursor_snooper snooper; struct vmw_surface_offset *offsets; - SVGA3dTextureFilter autogen_filter; - uint32_t multisample_count; struct list_head view_list; - SVGA3dMSPattern multisample_pattern; - SVGA3dMSQualityLevel quality_level; }; struct vmw_marker_queue { @@ -441,6 +477,22 @@ enum { VMW_IRQTHREAD_MAX }; +/** + * enum vmw_sm_type - Graphics context capability supported by device. + * @VMW_SM_LEGACY: Pre DX context. + * @VMW_SM_4: Context support upto SM4. + * @VMW_SM_4_1: Context support upto SM4_1. + * @VMW_SM_5: Context support up to SM5. + * @VMW_SM_MAX: Should be the last. + */ +enum vmw_sm_type { + VMW_SM_LEGACY = 0, + VMW_SM_4, + VMW_SM_4_1, + VMW_SM_5, + VMW_SM_MAX +}; + struct vmw_private { struct ttm_bo_device bdev; @@ -475,9 +527,9 @@ struct vmw_private { bool has_mob; spinlock_t hw_lock; spinlock_t cap_lock; - bool has_dx; bool assume_16bpp; - bool has_sm4_1; + + enum vmw_sm_type sm_type; /* * Framebuffer info. @@ -648,6 +700,39 @@ static inline uint32_t vmw_read(struct vmw_private *dev_priv, return val; } +/** + * has_sm4_context - Does the device support SM4 context. + * @dev_priv: Device private. + * + * Return: Bool value if device support SM4 context or not. + */ +static inline bool has_sm4_context(const struct vmw_private *dev_priv) +{ + return (dev_priv->sm_type >= VMW_SM_4); +} + +/** + * has_sm4_1_context - Does the device support SM4_1 context. + * @dev_priv: Device private. + * + * Return: Bool value if device support SM4_1 context or not. + */ +static inline bool has_sm4_1_context(const struct vmw_private *dev_priv) +{ + return (dev_priv->sm_type >= VMW_SM_4_1); +} + +/** + * has_sm5_context - Does the device support SM5 context. + * @dev_priv: Device private. + * + * Return: Bool value if device support SM5 context or not. + */ +static inline bool has_sm5_context(const struct vmw_private *dev_priv) +{ + return (dev_priv->sm_type >= VMW_SM_5); +} + extern void vmw_svga_enable(struct vmw_private *dev_priv); extern void vmw_svga_disable(struct vmw_private *dev_priv); @@ -1226,6 +1311,11 @@ extern int vmw_gb_surface_reference_ext_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int vmw_gb_surface_define(struct vmw_private *dev_priv, + uint32_t user_accounting_size, + const struct vmw_surface_metadata *req, + struct vmw_surface **srf_out); + /* * Shader management - vmwgfx_shader.c */ @@ -1258,6 +1348,24 @@ extern struct vmw_resource * vmw_shader_lookup(struct vmw_cmdbuf_res_manager *man, u32 user_key, SVGA3dShaderType shader_type); +/* + * Streamoutput management + */ +struct vmw_resource * +vmw_dx_streamoutput_lookup(struct vmw_cmdbuf_res_manager *man, + u32 user_key); +int vmw_dx_streamoutput_add(struct vmw_cmdbuf_res_manager *man, + struct vmw_resource *ctx, + SVGA3dStreamOutputId user_key, + struct list_head *list); +void vmw_dx_streamoutput_set_size(struct vmw_resource *res, u32 size); +int vmw_dx_streamoutput_remove(struct vmw_cmdbuf_res_manager *man, + SVGA3dStreamOutputId user_key, + struct list_head *list); +void vmw_dx_streamoutput_cotable_list_scrub(struct vmw_private *dev_priv, + struct list_head *list, + bool readback); + /* * Command buffer managed resources - vmwgfx_cmdbuf_res.c */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 73489a45decb..367d5b87ee6a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -459,10 +459,13 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, int ret = 0; struct vmw_resource *res; u32 i; + u32 cotable_max = has_sm5_context(ctx->dev_priv) ? + SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX; /* Add all cotables to the validation list. */ - if (dev_priv->has_dx && vmw_res_type(ctx) == vmw_res_dx_context) { - for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) { + if (has_sm4_context(dev_priv) && + vmw_res_type(ctx) == vmw_res_dx_context) { + for (i = 0; i < cotable_max; ++i) { res = vmw_context_cotable(ctx, i); if (IS_ERR(res)) continue; @@ -489,7 +492,8 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, break; } - if (dev_priv->has_dx && vmw_res_type(ctx) == vmw_res_dx_context) { + if (has_sm4_context(dev_priv) && + vmw_res_type(ctx) == vmw_res_dx_context) { struct vmw_buffer_object *dx_query_mob; dx_query_mob = vmw_context_get_dx_query_mob(ctx); @@ -2116,6 +2120,9 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, SVGA3dCmdHeader *header) { VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetSingleConstantBuffer); + SVGA3dShaderType max_shader_num = has_sm5_context(dev_priv) ? + SVGA3D_NUM_SHADERTYPE : SVGA3D_NUM_SHADERTYPE_DX10; + struct vmw_resource *res = NULL; struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_ctx_bindinfo_cb binding; @@ -2139,7 +2146,7 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, binding.size = cmd->body.sizeInBytes; binding.slot = cmd->body.slot; - if (binding.shader_slot >= SVGA3D_NUM_SHADERTYPE_DX10 || + if (binding.shader_slot >= max_shader_num || binding.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) { VMW_DEBUG_USER("Illegal const buffer shader %u slot %u.\n", (unsigned int) cmd->body.type, @@ -2167,12 +2174,15 @@ static int vmw_cmd_dx_set_shader_res(struct vmw_private *dev_priv, { VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShaderResources) = container_of(header, typeof(*cmd), header); + SVGA3dShaderType max_allowed = has_sm5_context(dev_priv) ? + SVGA3D_SHADERTYPE_MAX : SVGA3D_SHADERTYPE_DX10_MAX; + u32 num_sr_view = (cmd->header.size - sizeof(cmd->body)) / sizeof(SVGA3dShaderResourceViewId); if ((u64) cmd->body.startView + (u64) num_sr_view > (u64) SVGA3D_DX_MAX_SRVIEWS || - cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX) { + cmd->body.type >= max_allowed) { VMW_DEBUG_USER("Invalid shader binding.\n"); return -EINVAL; } @@ -2196,6 +2206,8 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, SVGA3dCmdHeader *header) { VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShader); + SVGA3dShaderType max_allowed = has_sm5_context(dev_priv) ? + SVGA3D_SHADERTYPE_MAX : SVGA3D_SHADERTYPE_DX10_MAX; struct vmw_resource *res = NULL; struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_ctx_bindinfo_shader binding; @@ -2206,7 +2218,7 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, cmd = container_of(header, typeof(*cmd), header); - if (cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX || + if (cmd->body.type >= max_allowed || cmd->body.type < SVGA3D_SHADERTYPE_MIN) { VMW_DEBUG_USER("Illegal shader type %u.\n", (unsigned int) cmd->body.type); @@ -2467,7 +2479,7 @@ static int vmw_cmd_dx_set_so_targets(struct vmw_private *dev_priv, SVGA3dCmdHeader *header) { struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); - struct vmw_ctx_bindinfo_so binding; + struct vmw_ctx_bindinfo_so_target binding; struct vmw_resource *res; struct { SVGA3dCmdHeader header; @@ -2497,7 +2509,7 @@ static int vmw_cmd_dx_set_so_targets(struct vmw_private *dev_priv, binding.bi.ctx = ctx_node->ctx; binding.bi.res = res; - binding.bi.bt = vmw_ctx_binding_so, + binding.bi.bt = vmw_ctx_binding_so_target, binding.offset = cmd->targets[i].offset; binding.size = cmd->targets[i].sizeInBytes; binding.slot = i; @@ -2804,6 +2816,352 @@ static int vmw_cmd_intra_surface_copy(struct vmw_private *dev_priv, &cmd->body.surface.sid, NULL); } +static int vmw_cmd_sm5(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + return 0; +} + +static int vmw_cmd_sm5_view_define(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + return vmw_cmd_dx_view_define(dev_priv, sw_context, header); +} + +static int vmw_cmd_sm5_view_remove(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + return vmw_cmd_dx_view_remove(dev_priv, sw_context, header); +} + +static int vmw_cmd_clear_uav_uint(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXClearUAViewUint body; + } *cmd = container_of(header, typeof(*cmd), header); + struct vmw_resource *ret; + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + ret = vmw_view_id_val_add(sw_context, vmw_view_ua, + cmd->body.uaViewId); + + return PTR_ERR_OR_ZERO(ret); +} + +static int vmw_cmd_clear_uav_float(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXClearUAViewFloat body; + } *cmd = container_of(header, typeof(*cmd), header); + struct vmw_resource *ret; + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + ret = vmw_view_id_val_add(sw_context, vmw_view_ua, + cmd->body.uaViewId); + + return PTR_ERR_OR_ZERO(ret); +} + +static int vmw_cmd_set_uav(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXSetUAViews body; + } *cmd = container_of(header, typeof(*cmd), header); + u32 num_uav = (cmd->header.size - sizeof(cmd->body)) / + sizeof(SVGA3dUAViewId); + int ret; + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + if (num_uav > SVGA3D_MAX_UAVIEWS) { + VMW_DEBUG_USER("Invalid UAV binding.\n"); + return -EINVAL; + } + + ret = vmw_view_bindings_add(sw_context, vmw_view_ua, + vmw_ctx_binding_uav, 0, (void *)&cmd[1], + num_uav, 0); + if (ret) + return ret; + + vmw_binding_add_uav_index(sw_context->dx_ctx_node->staged, 0, + cmd->body.uavSpliceIndex); + + return ret; +} + +static int vmw_cmd_set_cs_uav(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXSetCSUAViews body; + } *cmd = container_of(header, typeof(*cmd), header); + u32 num_uav = (cmd->header.size - sizeof(cmd->body)) / + sizeof(SVGA3dUAViewId); + int ret; + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + if (num_uav > SVGA3D_MAX_UAVIEWS) { + VMW_DEBUG_USER("Invalid UAV binding.\n"); + return -EINVAL; + } + + ret = vmw_view_bindings_add(sw_context, vmw_view_ua, + vmw_ctx_binding_cs_uav, 0, (void *)&cmd[1], + num_uav, 0); + if (ret) + return ret; + + vmw_binding_add_uav_index(sw_context->dx_ctx_node->staged, 1, + cmd->body.startIndex); + + return ret; +} + +static int vmw_cmd_dx_define_streamoutput(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_resource *res; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXDefineStreamOutputWithMob body; + } *cmd = container_of(header, typeof(*cmd), header); + int ret; + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + if (!ctx_node) { + DRM_ERROR("DX Context not set.\n"); + return -EINVAL; + } + + res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_STREAMOUTPUT); + ret = vmw_cotable_notify(res, cmd->body.soid); + if (ret) + return ret; + + return vmw_dx_streamoutput_add(sw_context->man, ctx_node->ctx, + cmd->body.soid, + &sw_context->staged_cmd_res); +} + +static int vmw_cmd_dx_destroy_streamoutput(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_resource *res; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXDestroyStreamOutput body; + } *cmd = container_of(header, typeof(*cmd), header); + + if (!ctx_node) { + DRM_ERROR("DX Context not set.\n"); + return -EINVAL; + } + + /* + * When device does not support SM5 then streamoutput with mob command is + * not available to user-space. Simply return in this case. + */ + if (!has_sm5_context(dev_priv)) + return 0; + + /* + * With SM5 capable device if lookup fails then user-space probably used + * old streamoutput define command. Return without an error. + */ + res = vmw_dx_streamoutput_lookup(vmw_context_res_man(ctx_node->ctx), + cmd->body.soid); + if (IS_ERR(res)) + return 0; + + return vmw_dx_streamoutput_remove(sw_context->man, cmd->body.soid, + &sw_context->staged_cmd_res); +} + +static int vmw_cmd_dx_bind_streamoutput(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_resource *res; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXBindStreamOutput body; + } *cmd = container_of(header, typeof(*cmd), header); + int ret; + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + if (!ctx_node) { + DRM_ERROR("DX Context not set.\n"); + return -EINVAL; + } + + res = vmw_dx_streamoutput_lookup(vmw_context_res_man(ctx_node->ctx), + cmd->body.soid); + if (IS_ERR(res)) { + DRM_ERROR("Cound not find streamoutput to bind.\n"); + return PTR_ERR(res); + } + + vmw_dx_streamoutput_set_size(res, cmd->body.sizeInBytes); + + ret = vmw_execbuf_res_noctx_val_add(sw_context, res, + VMW_RES_DIRTY_NONE); + if (ret) { + DRM_ERROR("Error creating resource validation node.\n"); + return ret; + } + + return vmw_cmd_res_switch_backup(dev_priv, sw_context, res, + &cmd->body.mobid, + cmd->body.offsetInBytes); +} + +static int vmw_cmd_dx_set_streamoutput(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_resource *res; + struct vmw_ctx_bindinfo_so binding; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXSetStreamOutput body; + } *cmd = container_of(header, typeof(*cmd), header); + int ret; + + if (!ctx_node) { + DRM_ERROR("DX Context not set.\n"); + return -EINVAL; + } + + if (cmd->body.soid == SVGA3D_INVALID_ID) + return 0; + + /* + * When device does not support SM5 then streamoutput with mob command is + * not available to user-space. Simply return in this case. + */ + if (!has_sm5_context(dev_priv)) + return 0; + + /* + * With SM5 capable device if lookup fails then user-space probably used + * old streamoutput define command. Return without an error. + */ + res = vmw_dx_streamoutput_lookup(vmw_context_res_man(ctx_node->ctx), + cmd->body.soid); + if (IS_ERR(res)) { + return 0; + } + + ret = vmw_execbuf_res_noctx_val_add(sw_context, res, + VMW_RES_DIRTY_NONE); + if (ret) { + DRM_ERROR("Error creating resource validation node.\n"); + return ret; + } + + binding.bi.ctx = ctx_node->ctx; + binding.bi.res = res; + binding.bi.bt = vmw_ctx_binding_so; + binding.slot = 0; /* Only one SO set to context at a time. */ + + vmw_binding_add(sw_context->dx_ctx_node->staged, &binding.bi, 0, + binding.slot); + + return ret; +} + +static int vmw_cmd_indexed_instanced_indirect(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_draw_indexed_instanced_indirect_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdDXDrawIndexedInstancedIndirect body; + } *cmd = container_of(header, typeof(*cmd), header); + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, + VMW_RES_DIRTY_NONE, user_surface_converter, + &cmd->body.argsBufferSid, NULL); +} + +static int vmw_cmd_instanced_indirect(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_draw_instanced_indirect_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdDXDrawInstancedIndirect body; + } *cmd = container_of(header, typeof(*cmd), header); + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, + VMW_RES_DIRTY_NONE, user_surface_converter, + &cmd->body.argsBufferSid, NULL); +} + +static int vmw_cmd_dispatch_indirect(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_dispatch_indirect_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdDXDispatchIndirect body; + } *cmd = container_of(header, typeof(*cmd), header); + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, + VMW_RES_DIRTY_NONE, user_surface_converter, + &cmd->body.argsBufferSid, NULL); +} + static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, void *buf, uint32_t *size) @@ -2922,18 +3280,12 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { false, false, false), VMW_CMD_DEF(SVGA_3D_CMD_DEAD2, &vmw_cmd_invalid, false, false, false), - VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_BITBLT, &vmw_cmd_invalid, - false, false, false), - VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_TRANSBLT, &vmw_cmd_invalid, - false, false, false), - VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_STRETCHBLT, &vmw_cmd_invalid, - false, false, false), - VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_COLORFILL, &vmw_cmd_invalid, - false, false, false), - VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_ALPHABLEND, &vmw_cmd_invalid, - false, false, false), - VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND, &vmw_cmd_invalid, - false, false, false), + VMW_CMD_DEF(SVGA_3D_CMD_DEAD12, &vmw_cmd_invalid, false, false, false), + VMW_CMD_DEF(SVGA_3D_CMD_DEAD13, &vmw_cmd_invalid, false, false, false), + VMW_CMD_DEF(SVGA_3D_CMD_DEAD14, &vmw_cmd_invalid, false, false, false), + VMW_CMD_DEF(SVGA_3D_CMD_DEAD15, &vmw_cmd_invalid, false, false, false), + VMW_CMD_DEF(SVGA_3D_CMD_DEAD16, &vmw_cmd_invalid, false, false, false), + VMW_CMD_DEF(SVGA_3D_CMD_DEAD17, &vmw_cmd_invalid, false, false, false), VMW_CMD_DEF(SVGA_3D_CMD_SET_OTABLE_BASE, &vmw_cmd_invalid, false, false, true), VMW_CMD_DEF(SVGA_3D_CMD_READBACK_OTABLE, &vmw_cmd_invalid, @@ -3141,9 +3493,9 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT, &vmw_cmd_dx_so_define, true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT, - &vmw_cmd_dx_cid_check, true, false, true), - VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_STREAMOUTPUT, &vmw_cmd_dx_cid_check, - true, false, true), + &vmw_cmd_dx_destroy_streamoutput, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_STREAMOUTPUT, + &vmw_cmd_dx_set_streamoutput, true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_SOTARGETS, &vmw_cmd_dx_set_so_targets, true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_INPUT_LAYOUT, @@ -3159,6 +3511,37 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_INTRA_SURFACE_COPY, &vmw_cmd_intra_surface_copy, true, false, true), + + /* + * SM5 commands + */ + VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_UA_VIEW, &vmw_cmd_sm5_view_define, + true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_UA_VIEW, &vmw_cmd_sm5_view_remove, + true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_CLEAR_UA_VIEW_UINT, &vmw_cmd_clear_uav_uint, + true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_CLEAR_UA_VIEW_FLOAT, + &vmw_cmd_clear_uav_float, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_COPY_STRUCTURE_COUNT, &vmw_cmd_invalid, true, + false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_UA_VIEWS, &vmw_cmd_set_uav, true, false, + true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED_INDIRECT, + &vmw_cmd_indexed_instanced_indirect, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_INSTANCED_INDIRECT, + &vmw_cmd_instanced_indirect, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_DISPATCH, &vmw_cmd_sm5, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_DISPATCH_INDIRECT, + &vmw_cmd_dispatch_indirect, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_CS_UA_VIEWS, &vmw_cmd_set_cs_uav, true, + false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW_V2, + &vmw_cmd_sm5_view_define, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT_WITH_MOB, + &vmw_cmd_dx_define_streamoutput, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_BIND_STREAMOUTPUT, + &vmw_cmd_dx_bind_streamoutput, true, false, true), }; bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index a15375eb476e..f681b7b4df1b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -114,10 +114,13 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, (dev_priv->active_display_unit == vmw_du_screen_target); break; case DRM_VMW_PARAM_DX: - param->value = dev_priv->has_dx; + param->value = has_sm4_context(dev_priv); break; case DRM_VMW_PARAM_SM4_1: - param->value = dev_priv->has_sm4_1; + param->value = has_sm4_1_context(dev_priv); + break; + case DRM_VMW_PARAM_SM5: + param->value = has_sm5_context(dev_priv); break; default: return -EINVAL; @@ -126,14 +129,17 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, return 0; } -static u32 vmw_mask_multisample(unsigned int cap, u32 fmt_value) +static u32 vmw_mask_legacy_multisample(unsigned int cap, u32 fmt_value) { /* * A version of user-space exists which use MULTISAMPLE_MASKABLESAMPLES * to check the sample count supported by virtual device. Since there * never was support for multisample count for backing MOB return 0. + * + * MULTISAMPLE_MASKABLESAMPLES devcap is marked as deprecated by virtual + * device. */ - if (cap == SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES) + if (cap == SVGA3D_DEVCAP_DEAD5) return 0; return fmt_value; @@ -164,7 +170,7 @@ static int vmw_fill_compat_cap(struct vmw_private *dev_priv, void *bounce, for (i = 0; i < max_size; ++i) { vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); compat_cap->pairs[i][0] = i; - compat_cap->pairs[i][1] = vmw_mask_multisample + compat_cap->pairs[i][1] = vmw_mask_legacy_multisample (i, vmw_read(dev_priv, SVGA_REG_DEV_CAP)); } spin_unlock(&dev_priv->cap_lock); @@ -220,7 +226,7 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, spin_lock(&dev_priv->cap_lock); for (i = 0; i < num; ++i) { vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); - *bounce32++ = vmw_mask_multisample + *bounce32++ = vmw_mask_legacy_multisample (i, vmw_read(dev_priv, SVGA_REG_DEV_CAP)); } spin_unlock(&dev_priv->cap_lock); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 52e086a5691e..04d66592f605 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -905,14 +905,14 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, */ /* Surface must be marked as a scanout. */ - if (unlikely(!surface->scanout)) + if (unlikely(!surface->metadata.scanout)) return -EINVAL; - if (unlikely(surface->mip_levels[0] != 1 || - surface->num_sizes != 1 || - surface->base_size.width < mode_cmd->width || - surface->base_size.height < mode_cmd->height || - surface->base_size.depth != 1)) { + if (unlikely(surface->metadata.mip_levels[0] != 1 || + surface->metadata.num_sizes != 1 || + surface->metadata.base_size.width < mode_cmd->width || + surface->metadata.base_size.height < mode_cmd->height || + surface->metadata.base_size.depth != 1)) { DRM_ERROR("Incompatible surface dimensions " "for requested mode.\n"); return -EINVAL; @@ -941,7 +941,7 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, * For DX, surface format validation is done when surface->scanout * is set. */ - if (!dev_priv->has_dx && format != surface->format) { + if (!has_sm4_context(dev_priv) && format != surface->metadata.format) { DRM_ERROR("Invalid surface format for requested mode.\n"); return -EINVAL; } @@ -1144,8 +1144,8 @@ static int vmw_create_bo_proxy(struct drm_device *dev, struct vmw_buffer_object *bo_mob, struct vmw_surface **srf_out) { + struct vmw_surface_metadata metadata = {0}; uint32_t format; - struct drm_vmw_size content_base_size = {0}; struct vmw_resource *res; unsigned int bytes_pp; struct drm_format_name_buf format_name; @@ -1175,22 +1175,15 @@ static int vmw_create_bo_proxy(struct drm_device *dev, return -EINVAL; } - content_base_size.width = mode_cmd->pitches[0] / bytes_pp; - content_base_size.height = mode_cmd->height; - content_base_size.depth = 1; + metadata.format = format; + metadata.mip_levels[0] = 1; + metadata.num_sizes = 1; + metadata.base_size.width = mode_cmd->pitches[0] / bytes_pp; + metadata.base_size.height = mode_cmd->height; + metadata.base_size.depth = 1; + metadata.scanout = true; - ret = vmw_surface_gb_priv_define(dev, - 0, /* kernel visible only */ - 0, /* flags */ - format, - true, /* can be a scanout buffer */ - 1, /* num of mip levels */ - 0, - 0, - content_base_size, - SVGA3D_MS_PATTERN_NONE, - SVGA3D_MS_QUALITY_NONE, - srf_out); + ret = vmw_gb_surface_define(vmw_priv(dev), 0, &metadata, srf_out); if (ret) { DRM_ERROR("Failed to allocate proxy content buffer\n"); return ret; @@ -2516,7 +2509,7 @@ int vmw_kms_update_proxy(struct vmw_resource *res, int increment) { struct vmw_private *dev_priv = res->dev_priv; - struct drm_vmw_size *size = &vmw_res_to_srf(res)->base_size; + struct drm_vmw_size *size = &vmw_res_to_srf(res)->metadata.base_size; struct { SVGA3dCmdHeader header; SVGA3dCmdUpdateGBImage body; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c index 0a6bbac00896..e8eb42933ca2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c @@ -320,7 +320,7 @@ int vmw_otables_setup(struct vmw_private *dev_priv) struct vmw_otable **otables = &dev_priv->otable_batch.otables; int ret; - if (dev_priv->has_dx) { + if (has_sm4_context(dev_priv)) { *otables = kmemdup(dx_tables, sizeof(dx_tables), GFP_KERNEL); if (!(*otables)) return -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c index 63807361e16f..3f97b61dd5d8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c @@ -319,7 +319,8 @@ int vmw_view_add(struct vmw_cmdbuf_res_manager *man, static const size_t vmw_view_define_sizes[] = { [vmw_view_sr] = sizeof(SVGA3dCmdDXDefineShaderResourceView), [vmw_view_rt] = sizeof(SVGA3dCmdDXDefineRenderTargetView), - [vmw_view_ds] = sizeof(SVGA3dCmdDXDefineDepthStencilView) + [vmw_view_ds] = sizeof(SVGA3dCmdDXDefineDepthStencilView), + [vmw_view_ua] = sizeof(SVGA3dCmdDXDefineUAView) }; struct vmw_private *dev_priv = ctx->dev_priv; @@ -499,8 +500,8 @@ struct vmw_resource *vmw_view_lookup(struct vmw_cmdbuf_res_manager *man, * Each time a resource is put on the validation list as the result of a * view pointing to it, we need to determine whether that resource will * be dirtied (written to by the GPU) as a result of the corresponding - * GPU operation. Currently only rendertarget- and depth-stencil views are - * capable of dirtying its resource. + * GPU operation. Currently only rendertarget-, depth-stencil and unordered + * access views are capable of dirtying its resource. * * Return: Whether the view type of @res dirties the resource it points to. */ @@ -509,10 +510,11 @@ u32 vmw_view_dirtying(struct vmw_resource *res) static u32 view_is_dirtying[vmw_view_max] = { [vmw_view_rt] = VMW_RES_DIRTY_SET, [vmw_view_ds] = VMW_RES_DIRTY_SET, + [vmw_view_ua] = VMW_RES_DIRTY_SET, }; /* Update this function as we add more view types */ - BUILD_BUG_ON(vmw_view_max != 3); + BUILD_BUG_ON(vmw_view_max != 4); return view_is_dirtying[vmw_view(res)->view_type]; } @@ -520,12 +522,14 @@ const u32 vmw_view_destroy_cmds[] = { [vmw_view_sr] = SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW, [vmw_view_rt] = SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW, [vmw_view_ds] = SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW, + [vmw_view_ua] = SVGA_3D_CMD_DX_DESTROY_UA_VIEW, }; const SVGACOTableType vmw_view_cotables[] = { [vmw_view_sr] = SVGA_COTABLE_SRVIEW, [vmw_view_rt] = SVGA_COTABLE_RTVIEW, [vmw_view_ds] = SVGA_COTABLE_DSVIEW, + [vmw_view_ua] = SVGA_COTABLE_UAVIEW, }; const SVGACOTableType vmw_so_cotables[] = { diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_so.h b/drivers/gpu/drm/vmwgfx/vmwgfx_so.h index 12565047bc55..f48b84bfeeac 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_so.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_so.h @@ -30,6 +30,7 @@ enum vmw_view_type { vmw_view_sr, vmw_view_rt, vmw_view_ds, + vmw_view_ua, vmw_view_max, }; @@ -61,6 +62,7 @@ union vmw_view_destroy { struct SVGA3dCmdDXDestroyRenderTargetView rtv; struct SVGA3dCmdDXDestroyShaderResourceView srv; struct SVGA3dCmdDXDestroyDepthStencilView dsv; + struct SVGA3dCmdDXDestroyUAView uav; u32 view_id; }; @@ -87,6 +89,10 @@ static inline enum vmw_view_type vmw_view_cmd_to_type(u32 id) { u32 tmp = (id - SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW) / 2; + if (id == SVGA_3D_CMD_DX_DEFINE_UA_VIEW || + id == SVGA_3D_CMD_DX_DESTROY_UA_VIEW) + return vmw_view_ua; + if (tmp > (u32)vmw_view_max) return vmw_view_max; @@ -123,6 +129,7 @@ static inline enum vmw_so_type vmw_so_cmd_to_type(u32 id) case SVGA_3D_CMD_DX_DESTROY_SAMPLER_STATE: return vmw_so_ss; case SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT: + case SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT_WITH_MOB: case SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT: return vmw_so_so; default: diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 68aecb6d9f87..9ffa9c75a5da 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -590,7 +590,7 @@ static void vmw_stdu_bo_cpu_commit(struct vmw_kms_dirty *dirty) return; /* Assume we are blitting from Guest (bo) to Host (display_srf) */ - dst_pitch = stdu->display_srf->base_size.width * stdu->cpp; + dst_pitch = stdu->display_srf->metadata.base_size.width * stdu->cpp; dst_bo = &stdu->display_srf->res.backup->base; dst_offset = ddirty->top * dst_pitch + ddirty->left * stdu->cpp; @@ -1041,7 +1041,6 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state); enum stdu_content_type new_content_type; struct vmw_framebuffer_surface *new_vfbs; - struct drm_crtc *crtc = new_state->crtc; uint32_t hdisplay = new_state->crtc_w, vdisplay = new_state->crtc_h; int ret; @@ -1058,8 +1057,9 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, vfb = vmw_framebuffer_to_vfb(new_fb); new_vfbs = (vfb->bo) ? NULL : vmw_framebuffer_to_vfbs(new_fb); - if (new_vfbs && new_vfbs->surface->base_size.width == hdisplay && - new_vfbs->surface->base_size.height == vdisplay) + if (new_vfbs && + new_vfbs->surface->metadata.base_size.width == hdisplay && + new_vfbs->surface->metadata.base_size.height == vdisplay) new_content_type = SAME_AS_DISPLAY; else if (vfb->bo) new_content_type = SEPARATE_BO; @@ -1067,12 +1067,11 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, new_content_type = SEPARATE_SURFACE; if (new_content_type != SAME_AS_DISPLAY) { - struct vmw_surface content_srf; - struct drm_vmw_size display_base_size = {0}; + struct vmw_surface_metadata metadata = {0}; - display_base_size.width = hdisplay; - display_base_size.height = vdisplay; - display_base_size.depth = 1; + metadata.base_size.width = hdisplay; + metadata.base_size.height = vdisplay; + metadata.base_size.depth = 1; /* * If content buffer is a buffer object, then we have to @@ -1082,15 +1081,15 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, switch (new_fb->format->cpp[0]*8) { case 32: - content_srf.format = SVGA3D_X8R8G8B8; + metadata.format = SVGA3D_X8R8G8B8; break; case 16: - content_srf.format = SVGA3D_R5G6B5; + metadata.format = SVGA3D_R5G6B5; break; case 8: - content_srf.format = SVGA3D_P8; + metadata.format = SVGA3D_P8; break; default: @@ -1098,22 +1097,20 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, return -EINVAL; } - content_srf.flags = 0; - content_srf.mip_levels[0] = 1; - content_srf.multisample_count = 0; - content_srf.multisample_pattern = - SVGA3D_MS_PATTERN_NONE; - content_srf.quality_level = SVGA3D_MS_QUALITY_NONE; + metadata.mip_levels[0] = 1; + metadata.num_sizes = 1; + metadata.scanout = true; } else { - content_srf = *new_vfbs->surface; + metadata = new_vfbs->surface->metadata; } if (vps->surf) { - struct drm_vmw_size cur_base_size = vps->surf->base_size; + struct drm_vmw_size cur_base_size = + vps->surf->metadata.base_size; - if (cur_base_size.width != display_base_size.width || - cur_base_size.height != display_base_size.height || - vps->surf->format != content_srf.format) { + if (cur_base_size.width != metadata.base_size.width || + cur_base_size.height != metadata.base_size.height || + vps->surf->metadata.format != metadata.format) { WARN_ON(vps->pinned != 0); vmw_surface_unreference(&vps->surf); } @@ -1121,20 +1118,8 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, } if (!vps->surf) { - ret = vmw_surface_gb_priv_define - (crtc->dev, - /* Kernel visible only */ - 0, - content_srf.flags, - content_srf.format, - true, /* a scanout buffer */ - content_srf.mip_levels[0], - content_srf.multisample_count, - 0, - display_base_size, - content_srf.multisample_pattern, - content_srf.quality_level, - &vps->surf); + ret = vmw_gb_surface_define(dev_priv, 0, &metadata, + &vps->surf); if (ret != 0) { DRM_ERROR("Couldn't allocate STDU surface.\n"); return ret; @@ -1311,7 +1296,7 @@ vmw_stdu_bo_populate_update_cpu(struct vmw_du_update_plane *update, void *cmd, diff.cpp = stdu->cpp; dst_bo = &stdu->display_srf->res.backup->base; - dst_pitch = stdu->display_srf->base_size.width * stdu->cpp; + dst_pitch = stdu->display_srf->metadata.base_size.width * stdu->cpp; dst_offset = bb->y1 * dst_pitch + bb->x1 * stdu->cpp; src_bo = &vfbbo->buffer->base; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c b/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c new file mode 100644 index 000000000000..193192456663 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c @@ -0,0 +1,387 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/************************************************************************** + * + * Copyright © 2018-2019 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include + +#include "vmwgfx_drv.h" +#include "vmwgfx_resource_priv.h" +#include "vmwgfx_binding.h" + +/** + * struct vmw_dx_streamoutput - Streamoutput resource metadata. + * @res: Base resource struct. + * @ctx: Non-refcounted context to which @res belong. + * @cotable: Refcounted cotable holding this Streamoutput. + * @cotable_head: List head for cotable-so_res list. + * @id: User-space provided identifier. + * @size: User-space provided mob size. + * @committed: Whether streamoutput is actually created or pending creation. + */ +struct vmw_dx_streamoutput { + struct vmw_resource res; + struct vmw_resource *ctx; + struct vmw_resource *cotable; + struct list_head cotable_head; + u32 id; + u32 size; + bool committed; +}; + +static int vmw_dx_streamoutput_create(struct vmw_resource *res); +static int vmw_dx_streamoutput_bind(struct vmw_resource *res, + struct ttm_validate_buffer *val_buf); +static int vmw_dx_streamoutput_unbind(struct vmw_resource *res, bool readback, + struct ttm_validate_buffer *val_buf); +static void vmw_dx_streamoutput_commit_notify(struct vmw_resource *res, + enum vmw_cmdbuf_res_state state); + +static size_t vmw_streamoutput_size; + +static const struct vmw_res_func vmw_dx_streamoutput_func = { + .res_type = vmw_res_streamoutput, + .needs_backup = true, + .may_evict = false, + .type_name = "DX streamoutput", + .backup_placement = &vmw_mob_placement, + .create = vmw_dx_streamoutput_create, + .destroy = NULL, /* Command buffer managed resource. */ + .bind = vmw_dx_streamoutput_bind, + .unbind = vmw_dx_streamoutput_unbind, + .commit_notify = vmw_dx_streamoutput_commit_notify, +}; + +static inline struct vmw_dx_streamoutput * +vmw_res_to_dx_streamoutput(struct vmw_resource *res) +{ + return container_of(res, struct vmw_dx_streamoutput, res); +} + +/** + * vmw_dx_streamoutput_unscrub - Reattach the MOB to streamoutput. + * @res: The streamoutput resource. + * + * Return: 0 on success, negative error code on failure. + */ +static int vmw_dx_streamoutput_unscrub(struct vmw_resource *res) +{ + struct vmw_dx_streamoutput *so = vmw_res_to_dx_streamoutput(res); + struct vmw_private *dev_priv = res->dev_priv; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXBindStreamOutput body; + } *cmd; + + if (!list_empty(&so->cotable_head) || !so->committed ) + return 0; + + cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), so->ctx->id); + if (!cmd) + return -ENOMEM; + + cmd->header.id = SVGA_3D_CMD_DX_BIND_STREAMOUTPUT; + cmd->header.size = sizeof(cmd->body); + cmd->body.soid = so->id; + cmd->body.mobid = res->backup->base.mem.start; + cmd->body.offsetInBytes = res->backup_offset; + cmd->body.sizeInBytes = so->size; + vmw_fifo_commit(dev_priv, sizeof(*cmd)); + + vmw_cotable_add_resource(so->cotable, &so->cotable_head); + + return 0; +} + +static int vmw_dx_streamoutput_create(struct vmw_resource *res) +{ + struct vmw_private *dev_priv = res->dev_priv; + struct vmw_dx_streamoutput *so = vmw_res_to_dx_streamoutput(res); + int ret = 0; + + WARN_ON_ONCE(!so->committed); + + if (vmw_resource_mob_attached(res)) { + mutex_lock(&dev_priv->binding_mutex); + ret = vmw_dx_streamoutput_unscrub(res); + mutex_unlock(&dev_priv->binding_mutex); + } + + res->id = so->id; + + return ret; +} + +static int vmw_dx_streamoutput_bind(struct vmw_resource *res, + struct ttm_validate_buffer *val_buf) +{ + struct vmw_private *dev_priv = res->dev_priv; + struct ttm_buffer_object *bo = val_buf->bo; + int ret; + + if (WARN_ON(bo->mem.mem_type != VMW_PL_MOB)) + return -EINVAL; + + mutex_lock(&dev_priv->binding_mutex); + ret = vmw_dx_streamoutput_unscrub(res); + mutex_unlock(&dev_priv->binding_mutex); + + return ret; +} + +/** + * vmw_dx_streamoutput_scrub - Unbind the MOB from streamoutput. + * @res: The streamoutput resource. + * + * Return: 0 on success, negative error code on failure. + */ +static int vmw_dx_streamoutput_scrub(struct vmw_resource *res) +{ + struct vmw_private *dev_priv = res->dev_priv; + struct vmw_dx_streamoutput *so = vmw_res_to_dx_streamoutput(res); + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXBindStreamOutput body; + } *cmd; + + if (list_empty(&so->cotable_head)) + return 0; + + WARN_ON_ONCE(!so->committed); + + cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), so->ctx->id); + if (!cmd) + return -ENOMEM; + + cmd->header.id = SVGA_3D_CMD_DX_BIND_STREAMOUTPUT; + cmd->header.size = sizeof(cmd->body); + cmd->body.soid = res->id; + cmd->body.mobid = SVGA3D_INVALID_ID; + cmd->body.offsetInBytes = 0; + cmd->body.sizeInBytes = so->size; + vmw_fifo_commit(dev_priv, sizeof(*cmd)); + + res->id = -1; + list_del_init(&so->cotable_head); + + return 0; +} + +static int vmw_dx_streamoutput_unbind(struct vmw_resource *res, bool readback, + struct ttm_validate_buffer *val_buf) +{ + struct vmw_private *dev_priv = res->dev_priv; + struct vmw_fence_obj *fence; + int ret; + + if (WARN_ON(res->backup->base.mem.mem_type != VMW_PL_MOB)) + return -EINVAL; + + mutex_lock(&dev_priv->binding_mutex); + ret = vmw_dx_streamoutput_scrub(res); + mutex_unlock(&dev_priv->binding_mutex); + + if (ret) + return ret; + + (void) vmw_execbuf_fence_commands(NULL, dev_priv, &fence, NULL); + vmw_bo_fence_single(val_buf->bo, fence); + + if (fence != NULL) + vmw_fence_obj_unreference(&fence); + + return 0; +} + +static void vmw_dx_streamoutput_commit_notify(struct vmw_resource *res, + enum vmw_cmdbuf_res_state state) +{ + struct vmw_private *dev_priv = res->dev_priv; + struct vmw_dx_streamoutput *so = vmw_res_to_dx_streamoutput(res); + + if (state == VMW_CMDBUF_RES_ADD) { + mutex_lock(&dev_priv->binding_mutex); + vmw_cotable_add_resource(so->cotable, &so->cotable_head); + so->committed = true; + res->id = so->id; + mutex_unlock(&dev_priv->binding_mutex); + } else { + mutex_lock(&dev_priv->binding_mutex); + list_del_init(&so->cotable_head); + so->committed = false; + res->id = -1; + mutex_unlock(&dev_priv->binding_mutex); + } +} + +/** + * vmw_dx_streamoutput_lookup - Do a streamoutput resource lookup by user key. + * @man: Command buffer managed resource manager for current context. + * @user_key: User-space identifier for lookup. + * + * Return: Valid refcounted vmw_resource on success, error pointer on failure. + */ +struct vmw_resource * +vmw_dx_streamoutput_lookup(struct vmw_cmdbuf_res_manager *man, + u32 user_key) +{ + return vmw_cmdbuf_res_lookup(man, vmw_cmdbuf_res_streamoutput, + user_key); +} + +static void vmw_dx_streamoutput_res_free(struct vmw_resource *res) +{ + struct vmw_private *dev_priv = res->dev_priv; + struct vmw_dx_streamoutput *so = vmw_res_to_dx_streamoutput(res); + + vmw_resource_unreference(&so->cotable); + kfree(so); + ttm_mem_global_free(vmw_mem_glob(dev_priv), vmw_streamoutput_size); +} + +static void vmw_dx_streamoutput_hw_destroy(struct vmw_resource *res) +{ + /* Destroyed by user-space cmd buf or as part of context takedown. */ + res->id = -1; +} + +/** + * vmw_dx_streamoutput_add - Add a streamoutput as a cmd buf managed resource. + * @man: Command buffer managed resource manager for current context. + * @ctx: Pointer to context resource. + * @user_key: The identifier for this streamoutput. + * @list: The list of staged command buffer managed resources. + * + * Return: 0 on success, negative error code on failure. + */ +int vmw_dx_streamoutput_add(struct vmw_cmdbuf_res_manager *man, + struct vmw_resource *ctx, u32 user_key, + struct list_head *list) +{ + struct vmw_dx_streamoutput *so; + struct vmw_resource *res; + struct vmw_private *dev_priv = ctx->dev_priv; + struct ttm_operation_ctx ttm_opt_ctx = { + .interruptible = true, + .no_wait_gpu = false + }; + int ret; + + if (!vmw_streamoutput_size) + vmw_streamoutput_size = ttm_round_pot(sizeof(*so)); + + ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), + vmw_streamoutput_size, &ttm_opt_ctx); + if (ret) { + if (ret != -ERESTARTSYS) + DRM_ERROR("Out of graphics memory for streamout.\n"); + return ret; + } + + so = kmalloc(sizeof(*so), GFP_KERNEL); + if (!so) { + ttm_mem_global_free(vmw_mem_glob(dev_priv), + vmw_streamoutput_size); + return -ENOMEM; + } + + res = &so->res; + so->ctx = ctx; + so->cotable = vmw_resource_reference + (vmw_context_cotable(ctx, SVGA_COTABLE_STREAMOUTPUT)); + so->id = user_key; + so->committed = false; + INIT_LIST_HEAD(&so->cotable_head); + ret = vmw_resource_init(dev_priv, res, true, + vmw_dx_streamoutput_res_free, + &vmw_dx_streamoutput_func); + if (ret) + goto out_resource_init; + + ret = vmw_cmdbuf_res_add(man, vmw_cmdbuf_res_streamoutput, user_key, + res, list); + if (ret) + goto out_resource_init; + + res->id = so->id; + res->hw_destroy = vmw_dx_streamoutput_hw_destroy; + +out_resource_init: + vmw_resource_unreference(&res); + + return ret; +} + +/** + * vmw_dx_streamoutput_set_size - Sets streamoutput mob size in res struct. + * @res: The streamoutput res for which need to set size. + * @size: The size provided by user-space to set. + */ +void vmw_dx_streamoutput_set_size(struct vmw_resource *res, u32 size) +{ + struct vmw_dx_streamoutput *so = vmw_res_to_dx_streamoutput(res); + + so->size = size; +} + +/** + * vmw_dx_streamoutput_remove - Stage streamoutput for removal. + * @man: Command buffer managed resource manager for current context. + * @user_key: The identifier for this streamoutput. + * @list: The list of staged command buffer managed resources. + * + * Return: 0 on success, negative error code on failure. + */ +int vmw_dx_streamoutput_remove(struct vmw_cmdbuf_res_manager *man, + u32 user_key, + struct list_head *list) +{ + struct vmw_resource *r; + + return vmw_cmdbuf_res_remove(man, vmw_cmdbuf_res_streamoutput, + (u32)user_key, list, &r); +} + +/** + * vmw_dx_streamoutput_cotable_list_scrub - cotable unbind_func callback. + * @dev_priv: Device private. + * @list: The list of cotable resources. + * @readback: Whether the call was part of a readback unbind. + */ +void vmw_dx_streamoutput_cotable_list_scrub(struct vmw_private *dev_priv, + struct list_head *list, + bool readback) +{ + struct vmw_dx_streamoutput *entry, *next; + + lockdep_assert_held_once(&dev_priv->binding_mutex); + + list_for_each_entry_safe(entry, next, list, cotable_head) { + WARN_ON(vmw_dx_streamoutput_scrub(&entry->res)); + if (!readback) + entry->committed =false; + } +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index ec893cd17b50..7ef51fa84b01 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -199,7 +199,7 @@ struct vmw_surface_destroy { */ static inline uint32_t vmw_surface_dma_size(const struct vmw_surface *srf) { - return srf->num_sizes * sizeof(struct vmw_surface_dma); + return srf->metadata.num_sizes * sizeof(struct vmw_surface_dma); } @@ -213,7 +213,7 @@ static inline uint32_t vmw_surface_dma_size(const struct vmw_surface *srf) */ static inline uint32_t vmw_surface_define_size(const struct vmw_surface *srf) { - return sizeof(struct vmw_surface_define) + srf->num_sizes * + return sizeof(struct vmw_surface_define) + srf->metadata.num_sizes * sizeof(SVGA3dSize); } @@ -262,7 +262,8 @@ static void vmw_surface_define_encode(const struct vmw_surface *srf, uint32_t cmd_len; int i; - cmd_len = sizeof(cmd->body) + srf->num_sizes * sizeof(SVGA3dSize); + cmd_len = sizeof(cmd->body) + srf->metadata.num_sizes * + sizeof(SVGA3dSize); cmd->header.id = SVGA_3D_CMD_SURFACE_DEFINE; cmd->header.size = cmd_len; @@ -272,16 +273,16 @@ static void vmw_surface_define_encode(const struct vmw_surface *srf, * since driver internally stores as 64 bit. * For legacy surface define only 32 bit flag is supported. */ - cmd->body.surfaceFlags = (SVGA3dSurface1Flags)srf->flags; - cmd->body.format = srf->format; + cmd->body.surfaceFlags = (SVGA3dSurface1Flags)srf->metadata.flags; + cmd->body.format = srf->metadata.format; for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) - cmd->body.face[i].numMipLevels = srf->mip_levels[i]; + cmd->body.face[i].numMipLevels = srf->metadata.mip_levels[i]; cmd += 1; cmd_size = (SVGA3dSize *) cmd; - src_size = srf->sizes; + src_size = srf->metadata.sizes; - for (i = 0; i < srf->num_sizes; ++i, cmd_size++, src_size++) { + for (i = 0; i < srf->metadata.num_sizes; ++i, cmd_size++, src_size++) { cmd_size->width = src_size->width; cmd_size->height = src_size->height; cmd_size->depth = src_size->depth; @@ -305,15 +306,15 @@ static void vmw_surface_dma_encode(struct vmw_surface *srf, uint32_t i; struct vmw_surface_dma *cmd = (struct vmw_surface_dma *)cmd_space; const struct svga3d_surface_desc *desc = - svga3dsurface_get_desc(srf->format); + svga3dsurface_get_desc(srf->metadata.format); - for (i = 0; i < srf->num_sizes; ++i) { + for (i = 0; i < srf->metadata.num_sizes; ++i) { SVGA3dCmdHeader *header = &cmd->header; SVGA3dCmdSurfaceDMA *body = &cmd->body; SVGA3dCopyBox *cb = &cmd->cb; SVGA3dCmdSurfaceDMASuffix *suffix = &cmd->suffix; const struct vmw_surface_offset *cur_offset = &srf->offsets[i]; - const struct drm_vmw_size *cur_size = &srf->sizes[i]; + const struct drm_vmw_size *cur_size = &srf->metadata.sizes[i]; header->id = SVGA_3D_CMD_SURFACE_DMA; header->size = sizeof(*body) + sizeof(*cb) + sizeof(*suffix); @@ -669,7 +670,7 @@ static void vmw_user_surface_free(struct vmw_resource *res) if (user_srf->master) drm_master_put(&user_srf->master); kfree(srf->offsets); - kfree(srf->sizes); + kfree(srf->metadata.sizes); kfree(srf->snooper.image); ttm_prime_object_kfree(user_srf, prime); ttm_mem_global_free(vmw_mem_glob(dev_priv), size); @@ -728,6 +729,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, struct vmw_private *dev_priv = vmw_priv(dev); struct vmw_user_surface *user_srf; struct vmw_surface *srf; + struct vmw_surface_metadata *metadata; struct vmw_resource *res; struct vmw_resource *tmp; union drm_vmw_surface_create_arg *arg = @@ -793,43 +795,45 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, } srf = &user_srf->srf; + metadata = &srf->metadata; res = &srf->res; /* Driver internally stores as 64-bit flags */ - srf->flags = (SVGA3dSurfaceAllFlags)req->flags; - srf->format = req->format; - srf->scanout = req->scanout; + metadata->flags = (SVGA3dSurfaceAllFlags)req->flags; + metadata->format = req->format; + metadata->scanout = req->scanout; - memcpy(srf->mip_levels, req->mip_levels, sizeof(srf->mip_levels)); - srf->num_sizes = num_sizes; + memcpy(metadata->mip_levels, req->mip_levels, + sizeof(metadata->mip_levels)); + metadata->num_sizes = num_sizes; user_srf->size = size; - srf->sizes = memdup_user((struct drm_vmw_size __user *)(unsigned long) - req->size_addr, - sizeof(*srf->sizes) * srf->num_sizes); - if (IS_ERR(srf->sizes)) { - ret = PTR_ERR(srf->sizes); + metadata->sizes = + memdup_user((struct drm_vmw_size __user *)(unsigned long) + req->size_addr, + sizeof(*metadata->sizes) * metadata->num_sizes); + if (IS_ERR(metadata->sizes)) { + ret = PTR_ERR(metadata->sizes); goto out_no_sizes; } - srf->offsets = kmalloc_array(srf->num_sizes, - sizeof(*srf->offsets), + srf->offsets = kmalloc_array(metadata->num_sizes, sizeof(*srf->offsets), GFP_KERNEL); if (unlikely(!srf->offsets)) { ret = -ENOMEM; goto out_no_offsets; } - srf->base_size = *srf->sizes; - srf->autogen_filter = SVGA3D_TEX_FILTER_NONE; - srf->multisample_count = 0; - srf->multisample_pattern = SVGA3D_MS_PATTERN_NONE; - srf->quality_level = SVGA3D_MS_QUALITY_NONE; + metadata->base_size = *srf->metadata.sizes; + metadata->autogen_filter = SVGA3D_TEX_FILTER_NONE; + metadata->multisample_count = 0; + metadata->multisample_pattern = SVGA3D_MS_PATTERN_NONE; + metadata->quality_level = SVGA3D_MS_QUALITY_NONE; cur_bo_offset = 0; cur_offset = srf->offsets; - cur_size = srf->sizes; + cur_size = metadata->sizes; for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) { - for (j = 0; j < srf->mip_levels[i]; ++j) { + for (j = 0; j < metadata->mip_levels[i]; ++j) { uint32_t stride = svga3dsurface_calculate_pitch (desc, cur_size); @@ -843,11 +847,11 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, } } res->backup_size = cur_bo_offset; - if (srf->scanout && - srf->num_sizes == 1 && - srf->sizes[0].width == 64 && - srf->sizes[0].height == 64 && - srf->format == SVGA3D_A8R8G8B8) { + if (metadata->scanout && + metadata->num_sizes == 1 && + metadata->sizes[0].width == 64 && + metadata->sizes[0].height == 64 && + metadata->format == SVGA3D_A8R8G8B8) { srf->snooper.image = kzalloc(64 * 64 * 4, GFP_KERNEL); if (!srf->snooper.image) { @@ -911,7 +915,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, out_no_copy: kfree(srf->offsets); out_no_offsets: - kfree(srf->sizes); + kfree(metadata->sizes); out_no_sizes: ttm_prime_object_kfree(user_srf, prime); out_no_user_srf: @@ -1031,18 +1035,19 @@ int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, srf = &user_srf->srf; /* Downcast of flags when sending back to user space */ - rep->flags = (uint32_t)srf->flags; - rep->format = srf->format; - memcpy(rep->mip_levels, srf->mip_levels, sizeof(srf->mip_levels)); + rep->flags = (uint32_t)srf->metadata.flags; + rep->format = srf->metadata.format; + memcpy(rep->mip_levels, srf->metadata.mip_levels, + sizeof(srf->metadata.mip_levels)); user_sizes = (struct drm_vmw_size __user *)(unsigned long) rep->size_addr; if (user_sizes) - ret = copy_to_user(user_sizes, &srf->base_size, - sizeof(srf->base_size)); + ret = copy_to_user(user_sizes, &srf->metadata.base_size, + sizeof(srf->metadata.base_size)); if (unlikely(ret != 0)) { VMW_DEBUG_USER("copy_to_user failed %p %u\n", user_sizes, - srf->num_sizes); + srf->metadata.num_sizes); ttm_ref_object_base_unref(tfile, base->handle, TTM_REF_USAGE); ret = -EFAULT; } @@ -1062,6 +1067,7 @@ static int vmw_gb_surface_create(struct vmw_resource *res) { struct vmw_private *dev_priv = res->dev_priv; struct vmw_surface *srf = vmw_res_to_srf(res); + struct vmw_surface_metadata *metadata = &srf->metadata; uint32_t cmd_len, cmd_id, submit_len; int ret; struct { @@ -1076,6 +1082,10 @@ static int vmw_gb_surface_create(struct vmw_resource *res) SVGA3dCmdHeader header; SVGA3dCmdDefineGBSurface_v3 body; } *cmd3; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDefineGBSurface_v4 body; + } *cmd4; if (likely(res->id != -1)) return 0; @@ -1092,12 +1102,16 @@ static int vmw_gb_surface_create(struct vmw_resource *res) goto out_no_fifo; } - if (dev_priv->has_sm4_1 && srf->array_size > 0) { + if (has_sm5_context(dev_priv) && metadata->array_size > 0) { + cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V4; + cmd_len = sizeof(cmd4->body); + submit_len = sizeof(*cmd4); + } else if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) { cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V3; cmd_len = sizeof(cmd3->body); submit_len = sizeof(*cmd3); - } else if (srf->array_size > 0) { - /* has_dx checked on creation time. */ + } else if (metadata->array_size > 0) { + /* VMW_SM_4 support verified at creation time. */ cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V2; cmd_len = sizeof(cmd2->body); submit_len = sizeof(*cmd2); @@ -1110,51 +1124,68 @@ static int vmw_gb_surface_create(struct vmw_resource *res) cmd = VMW_FIFO_RESERVE(dev_priv, submit_len); cmd2 = (typeof(cmd2))cmd; cmd3 = (typeof(cmd3))cmd; + cmd4 = (typeof(cmd4))cmd; if (unlikely(!cmd)) { ret = -ENOMEM; goto out_no_fifo; } - if (dev_priv->has_sm4_1 && srf->array_size > 0) { + if (has_sm5_context(dev_priv) && metadata->array_size > 0) { + cmd4->header.id = cmd_id; + cmd4->header.size = cmd_len; + cmd4->body.sid = srf->res.id; + cmd4->body.surfaceFlags = metadata->flags; + cmd4->body.format = metadata->format; + cmd4->body.numMipLevels = metadata->mip_levels[0]; + cmd4->body.multisampleCount = metadata->multisample_count; + cmd4->body.multisamplePattern = metadata->multisample_pattern; + cmd4->body.qualityLevel = metadata->quality_level; + cmd4->body.autogenFilter = metadata->autogen_filter; + cmd4->body.size.width = metadata->base_size.width; + cmd4->body.size.height = metadata->base_size.height; + cmd4->body.size.depth = metadata->base_size.depth; + cmd4->body.arraySize = metadata->array_size; + cmd4->body.bufferByteStride = metadata->buffer_byte_stride; + } else if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) { cmd3->header.id = cmd_id; cmd3->header.size = cmd_len; cmd3->body.sid = srf->res.id; - cmd3->body.surfaceFlags = srf->flags; - cmd3->body.format = srf->format; - cmd3->body.numMipLevels = srf->mip_levels[0]; - cmd3->body.multisampleCount = srf->multisample_count; - cmd3->body.multisamplePattern = srf->multisample_pattern; - cmd3->body.qualityLevel = srf->quality_level; - cmd3->body.autogenFilter = srf->autogen_filter; - cmd3->body.size.width = srf->base_size.width; - cmd3->body.size.height = srf->base_size.height; - cmd3->body.size.depth = srf->base_size.depth; - cmd3->body.arraySize = srf->array_size; - } else if (srf->array_size > 0) { + cmd3->body.surfaceFlags = metadata->flags; + cmd3->body.format = metadata->format; + cmd3->body.numMipLevels = metadata->mip_levels[0]; + cmd3->body.multisampleCount = metadata->multisample_count; + cmd3->body.multisamplePattern = metadata->multisample_pattern; + cmd3->body.qualityLevel = metadata->quality_level; + cmd3->body.autogenFilter = metadata->autogen_filter; + cmd3->body.size.width = metadata->base_size.width; + cmd3->body.size.height = metadata->base_size.height; + cmd3->body.size.depth = metadata->base_size.depth; + cmd3->body.arraySize = metadata->array_size; + } else if (metadata->array_size > 0) { cmd2->header.id = cmd_id; cmd2->header.size = cmd_len; cmd2->body.sid = srf->res.id; - cmd2->body.surfaceFlags = srf->flags; - cmd2->body.format = srf->format; - cmd2->body.numMipLevels = srf->mip_levels[0]; - cmd2->body.multisampleCount = srf->multisample_count; - cmd2->body.autogenFilter = srf->autogen_filter; - cmd2->body.size.width = srf->base_size.width; - cmd2->body.size.height = srf->base_size.height; - cmd2->body.size.depth = srf->base_size.depth; - cmd2->body.arraySize = srf->array_size; + cmd2->body.surfaceFlags = metadata->flags; + cmd2->body.format = metadata->format; + cmd2->body.numMipLevels = metadata->mip_levels[0]; + cmd2->body.multisampleCount = metadata->multisample_count; + cmd2->body.autogenFilter = metadata->autogen_filter; + cmd2->body.size.width = metadata->base_size.width; + cmd2->body.size.height = metadata->base_size.height; + cmd2->body.size.depth = metadata->base_size.depth; + cmd2->body.arraySize = metadata->array_size; } else { cmd->header.id = cmd_id; cmd->header.size = cmd_len; cmd->body.sid = srf->res.id; - cmd->body.surfaceFlags = srf->flags; - cmd->body.format = srf->format; - cmd->body.numMipLevels = srf->mip_levels[0]; - cmd->body.multisampleCount = srf->multisample_count; - cmd->body.autogenFilter = srf->autogen_filter; - cmd->body.size.width = srf->base_size.width; - cmd->body.size.height = srf->base_size.height; - cmd->body.size.depth = srf->base_size.depth; + cmd->body.surfaceFlags = metadata->flags; + cmd->body.format = metadata->format; + cmd->body.numMipLevels = metadata->mip_levels[0]; + cmd->body.multisampleCount = metadata->multisample_count; + cmd->body.autogenFilter = metadata->autogen_filter; + cmd->body.size.width = metadata->base_size.width; + cmd->body.size.height = metadata->base_size.height; + cmd->body.size.depth = metadata->base_size.depth; } vmw_fifo_commit(dev_priv, submit_len); @@ -1314,7 +1345,6 @@ static int vmw_gb_surface_destroy(struct vmw_resource *res) return 0; } - /** * vmw_gb_surface_define_ioctl - Ioctl function implementing * the user surface define functionality. @@ -1336,6 +1366,7 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data, req_ext.svga3d_flags_upper_32_bits = 0; req_ext.multisample_pattern = SVGA3D_MS_PATTERN_NONE; req_ext.quality_level = SVGA3D_MS_QUALITY_NONE; + req_ext.buffer_byte_stride = 0; req_ext.must_be_zero = 0; return vmw_gb_surface_define_internal(dev, &req_ext, rep, file_priv); @@ -1370,171 +1401,6 @@ int vmw_gb_surface_reference_ioctl(struct drm_device *dev, void *data, return ret; } -/** - * vmw_surface_gb_priv_define - Define a private GB surface - * - * @dev: Pointer to a struct drm_device - * @user_accounting_size: Used to track user-space memory usage, set - * to 0 for kernel mode only memory - * @svga3d_flags: SVGA3d surface flags for the device - * @format: requested surface format - * @for_scanout: true if inteded to be used for scanout buffer - * @num_mip_levels: number of MIP levels - * @multisample_count: - * @array_size: Surface array size. - * @size: width, heigh, depth of the surface requested - * @multisample_pattern: Multisampling pattern when msaa is supported - * @quality_level: Precision settings - * @user_srf_out: allocated user_srf. Set to NULL on failure. - * - * GB surfaces allocated by this function will not have a user mode handle, and - * thus will only be visible to vmwgfx. For optimization reasons the - * surface may later be given a user mode handle by another function to make - * it available to user mode drivers. - */ -int vmw_surface_gb_priv_define(struct drm_device *dev, - uint32_t user_accounting_size, - SVGA3dSurfaceAllFlags svga3d_flags, - SVGA3dSurfaceFormat format, - bool for_scanout, - uint32_t num_mip_levels, - uint32_t multisample_count, - uint32_t array_size, - struct drm_vmw_size size, - SVGA3dMSPattern multisample_pattern, - SVGA3dMSQualityLevel quality_level, - struct vmw_surface **srf_out) -{ - struct vmw_private *dev_priv = vmw_priv(dev); - struct vmw_user_surface *user_srf; - struct ttm_operation_ctx ctx = { - .interruptible = true, - .no_wait_gpu = false - }; - struct vmw_surface *srf; - int ret; - u32 num_layers = 1; - u32 sample_count = 1; - - *srf_out = NULL; - - if (for_scanout) { - if (!svga3dsurface_is_screen_target_format(format)) { - VMW_DEBUG_USER("Invalid Screen Target surface format."); - return -EINVAL; - } - - if (size.width > dev_priv->texture_max_width || - size.height > dev_priv->texture_max_height) { - VMW_DEBUG_USER("%ux%u\n, exceeds max surface size %ux%u", - size.width, size.height, - dev_priv->texture_max_width, - dev_priv->texture_max_height); - return -EINVAL; - } - } else { - const struct svga3d_surface_desc *desc; - - desc = svga3dsurface_get_desc(format); - if (unlikely(desc->block_desc == SVGA3DBLOCKDESC_NONE)) { - VMW_DEBUG_USER("Invalid surface format.\n"); - return -EINVAL; - } - } - - /* array_size must be null for non-GL3 host. */ - if (array_size > 0 && !dev_priv->has_dx) { - VMW_DEBUG_USER("Tried to create DX surface on non-DX host.\n"); - return -EINVAL; - } - - ret = ttm_read_lock(&dev_priv->reservation_sem, true); - if (unlikely(ret != 0)) - return ret; - - ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), - user_accounting_size, &ctx); - if (unlikely(ret != 0)) { - if (ret != -ERESTARTSYS) - DRM_ERROR("Out of graphics memory for surface" - " creation.\n"); - goto out_unlock; - } - - user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL); - if (unlikely(!user_srf)) { - ret = -ENOMEM; - goto out_no_user_srf; - } - - *srf_out = &user_srf->srf; - user_srf->size = user_accounting_size; - user_srf->prime.base.shareable = false; - user_srf->prime.base.tfile = NULL; - - srf = &user_srf->srf; - srf->flags = svga3d_flags; - srf->format = format; - srf->scanout = for_scanout; - srf->mip_levels[0] = num_mip_levels; - srf->num_sizes = 1; - srf->sizes = NULL; - srf->offsets = NULL; - srf->base_size = size; - srf->autogen_filter = SVGA3D_TEX_FILTER_NONE; - srf->array_size = array_size; - srf->multisample_count = multisample_count; - srf->multisample_pattern = multisample_pattern; - srf->quality_level = quality_level; - - if (array_size) - num_layers = array_size; - else if (svga3d_flags & SVGA3D_SURFACE_CUBEMAP) - num_layers = SVGA3D_MAX_SURFACE_FACES; - - if (srf->flags & SVGA3D_SURFACE_MULTISAMPLE) - sample_count = srf->multisample_count; - - srf->res.backup_size = - svga3dsurface_get_serialized_size_extended(srf->format, - srf->base_size, - srf->mip_levels[0], - num_layers, - sample_count); - - if (srf->flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) - srf->res.backup_size += sizeof(SVGA3dDXSOState); - - /* - * Don't set SVGA3D_SURFACE_SCREENTARGET flag for a scanout surface with - * size greater than STDU max width/height. This is really a workaround - * to support creation of big framebuffer requested by some user-space - * for whole topology. That big framebuffer won't really be used for - * binding with screen target as during prepare_fb a separate surface is - * created so it's safe to ignore SVGA3D_SURFACE_SCREENTARGET flag. - */ - if (dev_priv->active_display_unit == vmw_du_screen_target && - for_scanout && size.width <= dev_priv->stdu_max_width && - size.height <= dev_priv->stdu_max_height) - srf->flags |= SVGA3D_SURFACE_SCREENTARGET; - - /* - * From this point, the generic resource management functions - * destroy the object on failure. - */ - ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free); - - ttm_read_unlock(&dev_priv->reservation_sem); - return ret; - -out_no_user_srf: - ttm_mem_global_free(vmw_mem_glob(dev_priv), user_accounting_size); - -out_unlock: - ttm_read_unlock(&dev_priv->reservation_sem); - return ret; -} - /** * vmw_gb_surface_define_ext_ioctl - Ioctl function implementing * the user surface define functionality. @@ -1588,43 +1454,60 @@ vmw_gb_surface_define_internal(struct drm_device *dev, struct drm_vmw_gb_surface_create_rep *rep, struct drm_file *file_priv) { + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; struct vmw_private *dev_priv = vmw_priv(dev); struct vmw_user_surface *user_srf; + struct vmw_surface_metadata metadata = {0}; struct vmw_surface *srf; struct vmw_resource *res; struct vmw_resource *tmp; - struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; - int ret; + int ret = 0; uint32_t size; uint32_t backup_handle = 0; SVGA3dSurfaceAllFlags svga3d_flags_64 = SVGA3D_FLAGS_64(req->svga3d_flags_upper_32_bits, req->base.svga3d_flags); - if (!dev_priv->has_sm4_1) { - /* - * If SM4_1 is not support then cannot send 64-bit flag to - * device. - */ + /* array_size must be null for non-GL3 host. */ + if (req->base.array_size > 0 && !has_sm4_context(dev_priv)) { + VMW_DEBUG_USER("SM4 surface not supported.\n"); + return -EINVAL; + } + + if (!has_sm4_1_context(dev_priv)) { if (req->svga3d_flags_upper_32_bits != 0) - return -EINVAL; + ret = -EINVAL; if (req->base.multisample_count != 0) - return -EINVAL; + ret = -EINVAL; if (req->multisample_pattern != SVGA3D_MS_PATTERN_NONE) - return -EINVAL; + ret = -EINVAL; if (req->quality_level != SVGA3D_MS_QUALITY_NONE) - return -EINVAL; + ret = -EINVAL; + + if (ret) { + VMW_DEBUG_USER("SM4.1 surface not supported.\n"); + return ret; + } + } + + if (req->buffer_byte_stride > 0 && !has_sm5_context(dev_priv)) { + VMW_DEBUG_USER("SM5 surface not supported.\n"); + return -EINVAL; } if ((svga3d_flags_64 & SVGA3D_SURFACE_MULTISAMPLE) && - req->base.multisample_count == 0) + req->base.multisample_count == 0) { + VMW_DEBUG_USER("Invalid sample count.\n"); return -EINVAL; + } - if (req->base.mip_levels > DRM_VMW_MAX_MIP_LEVELS) + if (req->base.mip_levels > DRM_VMW_MAX_MIP_LEVELS) { + VMW_DEBUG_USER("Invalid mip level.\n"); return -EINVAL; + } if (unlikely(vmw_user_surface_size == 0)) vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) + @@ -1632,22 +1515,25 @@ vmw_gb_surface_define_internal(struct drm_device *dev, size = vmw_user_surface_size; + metadata.flags = svga3d_flags_64; + metadata.format = req->base.format; + metadata.mip_levels[0] = req->base.mip_levels; + metadata.multisample_count = req->base.multisample_count; + metadata.multisample_pattern = req->multisample_pattern; + metadata.quality_level = req->quality_level; + metadata.array_size = req->base.array_size; + metadata.buffer_byte_stride = req->buffer_byte_stride; + metadata.num_sizes = 1; + metadata.base_size = req->base.base_size; + metadata.scanout = req->base.drm_surface_flags & + drm_vmw_surface_flag_scanout; + /* Define a surface based on the parameters. */ - ret = vmw_surface_gb_priv_define(dev, - size, - svga3d_flags_64, - req->base.format, - req->base.drm_surface_flags & - drm_vmw_surface_flag_scanout, - req->base.mip_levels, - req->base.multisample_count, - req->base.array_size, - req->base.base_size, - req->multisample_pattern, - req->quality_level, - &srf); - if (unlikely(ret != 0)) + ret = vmw_gb_surface_define(dev_priv, size, &metadata, &srf); + if (ret != 0) { + VMW_DEBUG_USER("Failed to define surface.\n"); return ret; + } user_srf = container_of(srf, struct vmw_user_surface, srf); if (drm_is_primary_client(file_priv)) @@ -1762,6 +1648,7 @@ vmw_gb_surface_reference_internal(struct drm_device *dev, struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; struct vmw_surface *srf; struct vmw_user_surface *user_srf; + struct vmw_surface_metadata *metadata; struct ttm_base_object *base; uint32_t backup_handle; int ret = -EINVAL; @@ -1777,6 +1664,7 @@ vmw_gb_surface_reference_internal(struct drm_device *dev, DRM_ERROR("Shared GB surface is missing a backup buffer.\n"); goto out_bad_resource; } + metadata = &srf->metadata; mutex_lock(&dev_priv->cmdbuf_mutex); /* Protect res->backup */ ret = vmw_user_bo_reference(tfile, srf->res.backup, &backup_handle); @@ -1790,15 +1678,15 @@ vmw_gb_surface_reference_internal(struct drm_device *dev, goto out_bad_resource; } - rep->creq.base.svga3d_flags = SVGA3D_FLAGS_LOWER_32(srf->flags); - rep->creq.base.format = srf->format; - rep->creq.base.mip_levels = srf->mip_levels[0]; + rep->creq.base.svga3d_flags = SVGA3D_FLAGS_LOWER_32(metadata->flags); + rep->creq.base.format = metadata->format; + rep->creq.base.mip_levels = metadata->mip_levels[0]; rep->creq.base.drm_surface_flags = 0; - rep->creq.base.multisample_count = srf->multisample_count; - rep->creq.base.autogen_filter = srf->autogen_filter; - rep->creq.base.array_size = srf->array_size; + rep->creq.base.multisample_count = metadata->multisample_count; + rep->creq.base.autogen_filter = metadata->autogen_filter; + rep->creq.base.array_size = metadata->array_size; rep->creq.base.buffer_handle = backup_handle; - rep->creq.base.base_size = srf->base_size; + rep->creq.base.base_size = metadata->base_size; rep->crep.handle = user_srf->prime.base.handle; rep->crep.backup_size = srf->res.backup_size; rep->crep.buffer_handle = backup_handle; @@ -1808,9 +1696,9 @@ vmw_gb_surface_reference_internal(struct drm_device *dev, rep->creq.version = drm_vmw_gb_surface_v1; rep->creq.svga3d_flags_upper_32_bits = - SVGA3D_FLAGS_UPPER_32(srf->flags); - rep->creq.multisample_pattern = srf->multisample_pattern; - rep->creq.quality_level = srf->quality_level; + SVGA3D_FLAGS_UPPER_32(metadata->flags); + rep->creq.multisample_pattern = metadata->multisample_pattern; + rep->creq.quality_level = metadata->quality_level; rep->creq.must_be_zero = 0; out_bad_resource: @@ -1968,7 +1856,7 @@ static void vmw_surface_dirty_range_add(struct vmw_resource *res, size_t start, start >= res->backup_offset + res->backup_size)) return; - if (srf->format == SVGA3D_BUFFER) + if (srf->metadata.format == SVGA3D_BUFFER) vmw_surface_buf_dirty_range_add(res, start, end); else vmw_surface_tex_dirty_range_add(res, start, end); @@ -2058,6 +1946,7 @@ static int vmw_surface_dirty_sync(struct vmw_resource *res) static int vmw_surface_dirty_alloc(struct vmw_resource *res) { struct vmw_surface *srf = vmw_res_to_srf(res); + const struct vmw_surface_metadata *metadata = &srf->metadata; struct vmw_surface_dirty *dirty; u32 num_layers = 1; u32 num_mip; @@ -2070,12 +1959,12 @@ static int vmw_surface_dirty_alloc(struct vmw_resource *res) }; int ret; - if (srf->array_size) - num_layers = srf->array_size; - else if (srf->flags & SVGA3D_SURFACE_CUBEMAP) + if (metadata->array_size) + num_layers = metadata->array_size; + else if (metadata->flags & SVGA3D_SURFACE_CUBEMAP) num_layers *= SVGA3D_MAX_SURFACE_FACES; - num_mip = srf->mip_levels[0]; + num_mip = metadata->mip_levels[0]; if (!num_mip) num_mip = 1; @@ -2096,9 +1985,10 @@ static int vmw_surface_dirty_alloc(struct vmw_resource *res) goto out_no_dirty; } - num_samples = max_t(u32, 1, srf->multisample_count); - ret = svga3dsurface_setup_cache(&srf->base_size, srf->format, num_mip, - num_layers, num_samples, &dirty->cache); + num_samples = max_t(u32, 1, metadata->multisample_count); + ret = svga3dsurface_setup_cache(&metadata->base_size, metadata->format, + num_mip, num_layers, num_samples, + &dirty->cache); if (ret) goto out_no_cache; @@ -2153,3 +2043,147 @@ static int vmw_surface_clean(struct vmw_resource *res) return 0; } + +/* + * vmw_gb_surface_define - Define a private GB surface + * + * @dev_priv: Pointer to a device private. + * @user_accounting_size: Used to track user-space memory usage, set + * to 0 for kernel mode only memory + * @metadata: Metadata representing the surface to create. + * @user_srf_out: allocated user_srf. Set to NULL on failure. + * + * GB surfaces allocated by this function will not have a user mode handle, and + * thus will only be visible to vmwgfx. For optimization reasons the + * surface may later be given a user mode handle by another function to make + * it available to user mode drivers. + */ +int vmw_gb_surface_define(struct vmw_private *dev_priv, + uint32_t user_accounting_size, + const struct vmw_surface_metadata *req, + struct vmw_surface **srf_out) +{ + struct vmw_surface_metadata *metadata; + struct vmw_user_surface *user_srf; + struct vmw_surface *srf; + struct ttm_operation_ctx ctx = { + .interruptible = true, + .no_wait_gpu = false + }; + u32 sample_count = 1; + u32 num_layers = 1; + int ret; + + *srf_out = NULL; + + if (req->scanout) { + if (!svga3dsurface_is_screen_target_format(req->format)) { + VMW_DEBUG_USER("Invalid Screen Target surface format."); + return -EINVAL; + } + + if (req->base_size.width > dev_priv->texture_max_width || + req->base_size.height > dev_priv->texture_max_height) { + VMW_DEBUG_USER("%ux%u\n, exceed max surface size %ux%u", + req->base_size.width, + req->base_size.height, + dev_priv->texture_max_width, + dev_priv->texture_max_height); + return -EINVAL; + } + } else { + const struct svga3d_surface_desc *desc = + svga3dsurface_get_desc(req->format); + + if (desc->block_desc == SVGA3DBLOCKDESC_NONE) { + VMW_DEBUG_USER("Invalid surface format.\n"); + return -EINVAL; + } + } + + if (req->autogen_filter != SVGA3D_TEX_FILTER_NONE) + return -EINVAL; + + if (req->num_sizes != 1) + return -EINVAL; + + if (req->sizes != NULL) + return -EINVAL; + + ret = ttm_read_lock(&dev_priv->reservation_sem, true); + if (unlikely(ret != 0)) + return ret; + + ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), + user_accounting_size, &ctx); + if (ret != 0) { + if (ret != -ERESTARTSYS) + DRM_ERROR("Out of graphics memory for surface.\n"); + goto out_unlock; + } + + user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL); + if (unlikely(!user_srf)) { + ret = -ENOMEM; + goto out_no_user_srf; + } + + *srf_out = &user_srf->srf; + user_srf->size = user_accounting_size; + user_srf->prime.base.shareable = false; + user_srf->prime.base.tfile = NULL; + + srf = &user_srf->srf; + srf->metadata = *req; + srf->offsets = NULL; + + metadata = &srf->metadata; + + if (metadata->array_size) + num_layers = req->array_size; + else if (metadata->flags & SVGA3D_SURFACE_CUBEMAP) + num_layers = SVGA3D_MAX_SURFACE_FACES; + + if (metadata->flags & SVGA3D_SURFACE_MULTISAMPLE) + sample_count = metadata->multisample_count; + + srf->res.backup_size = + svga3dsurface_get_serialized_size_extended(metadata->format, + metadata->base_size, + metadata->mip_levels[0], + num_layers, + sample_count); + + if (metadata->flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) + srf->res.backup_size += sizeof(SVGA3dDXSOState); + + /* + * Don't set SVGA3D_SURFACE_SCREENTARGET flag for a scanout surface with + * size greater than STDU max width/height. This is really a workaround + * to support creation of big framebuffer requested by some user-space + * for whole topology. That big framebuffer won't really be used for + * binding with screen target as during prepare_fb a separate surface is + * created so it's safe to ignore SVGA3D_SURFACE_SCREENTARGET flag. + */ + if (dev_priv->active_display_unit == vmw_du_screen_target && + metadata->scanout && + metadata->base_size.width <= dev_priv->stdu_max_width && + metadata->base_size.height <= dev_priv->stdu_max_height) + metadata->flags |= SVGA3D_SURFACE_SCREENTARGET; + + /* + * From this point, the generic resource management functions + * destroy the object on failure. + */ + ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free); + + ttm_read_unlock(&dev_priv->reservation_sem); + return ret; + +out_no_user_srf: + ttm_mem_global_free(vmw_mem_glob(dev_priv), user_accounting_size); + +out_unlock: + ttm_read_unlock(&dev_priv->reservation_sem); + return ret; +} diff --git a/include/uapi/drm/vmwgfx_drm.h b/include/uapi/drm/vmwgfx_drm.h index fcb741e3068f..02e917507479 100644 --- a/include/uapi/drm/vmwgfx_drm.h +++ b/include/uapi/drm/vmwgfx_drm.h @@ -86,6 +86,9 @@ extern "C" { * * DRM_VMW_PARAM_SM4_1 * SM4_1 support is enabled. + * + * DRM_VMW_PARAM_SM5 + * SM5 support is enabled. */ #define DRM_VMW_PARAM_NUM_STREAMS 0 @@ -103,6 +106,7 @@ extern "C" { #define DRM_VMW_PARAM_DX 12 #define DRM_VMW_PARAM_HW_CAPS2 13 #define DRM_VMW_PARAM_SM4_1 14 +#define DRM_VMW_PARAM_SM5 15 /** * enum drm_vmw_handle_type - handle type for ref ioctls @@ -1133,7 +1137,7 @@ struct drm_vmw_handle_close_arg { * svga3d surface flags split into 2, upper half and lower half. */ enum drm_vmw_surface_version { - drm_vmw_gb_surface_v1 + drm_vmw_gb_surface_v1, }; /** @@ -1144,6 +1148,7 @@ enum drm_vmw_surface_version { * @svga3d_flags_upper_32_bits: Upper 32 bits of svga3d flags. * @multisample_pattern: Multisampling pattern when msaa is supported. * @quality_level: Precision settings for each sample. + * @buffer_byte_stride: Buffer byte stride. * @must_be_zero: Reserved for future usage. * * Input argument to the DRM_VMW_GB_SURFACE_CREATE_EXT Ioctl. @@ -1152,10 +1157,11 @@ enum drm_vmw_surface_version { struct drm_vmw_gb_surface_create_ext_req { struct drm_vmw_gb_surface_create_req base; enum drm_vmw_surface_version version; - uint32_t svga3d_flags_upper_32_bits; - SVGA3dMSPattern multisample_pattern; - SVGA3dMSQualityLevel quality_level; - uint64_t must_be_zero; + __u32 svga3d_flags_upper_32_bits; + __u32 multisample_pattern; + __u32 quality_level; + __u32 buffer_byte_stride; + __u32 must_be_zero; }; /**