X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsvga%2Fsvga_screen.c;h=479b6fc522faa5bce532794485d6ffb47fd4bc1d;hb=75b47dda0c8895afe77858cbb67efa38e17e1838;hp=66c3deaa9e7be6774f0f60b3f5c4890794c6ae9d;hpb=3b7800e75089d4dc8ed9b2a0ce994760c167b93a;p=mesa.git diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index 66c3deaa9e7..479b6fc522f 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -34,31 +34,37 @@ #include "svga_context.h" #include "svga_format.h" #include "svga_screen.h" +#include "svga_tgsi.h" #include "svga_resource_texture.h" #include "svga_resource.h" #include "svga_debug.h" #include "svga3d_shaderdefs.h" +#include "VGPU10ShaderTokens.h" +/* NOTE: this constant may get moved into a svga3d*.h header file */ +#define SVGA3D_DX_MAX_RESOURCE_SIZE (128 * 1024 * 1024) #ifdef DEBUG int SVGA_DEBUG = 0; static const struct debug_named_value svga_debug_flags[] = { - { "dma", DEBUG_DMA, NULL }, - { "tgsi", DEBUG_TGSI, NULL }, - { "pipe", DEBUG_PIPE, NULL }, - { "state", DEBUG_STATE, NULL }, - { "screen", DEBUG_SCREEN, NULL }, - { "tex", DEBUG_TEX, NULL }, - { "swtnl", DEBUG_SWTNL, NULL }, - { "const", DEBUG_CONSTS, NULL }, - { "viewport", DEBUG_VIEWPORT, NULL }, - { "views", DEBUG_VIEWS, NULL }, - { "perf", DEBUG_PERF, NULL }, - { "flush", DEBUG_FLUSH, NULL }, - { "sync", DEBUG_SYNC, NULL }, - { "cache", DEBUG_CACHE, NULL }, + { "dma", DEBUG_DMA, NULL }, + { "tgsi", DEBUG_TGSI, NULL }, + { "pipe", DEBUG_PIPE, NULL }, + { "state", DEBUG_STATE, NULL }, + { "screen", DEBUG_SCREEN, NULL }, + { "tex", DEBUG_TEX, NULL }, + { "swtnl", DEBUG_SWTNL, NULL }, + { "const", DEBUG_CONSTS, NULL }, + { "viewport", DEBUG_VIEWPORT, NULL }, + { "views", DEBUG_VIEWS, NULL }, + { "perf", DEBUG_PERF, NULL }, + { "flush", DEBUG_FLUSH, NULL }, + { "sync", DEBUG_SYNC, NULL }, + { "cache", DEBUG_CACHE, NULL }, + { "streamout", DEBUG_STREAMOUT, NULL }, + { "query", DEBUG_QUERY, NULL }, DEBUG_NAMED_VALUE_END }; #endif @@ -80,18 +86,54 @@ svga_get_name( struct pipe_screen *pscreen ) */ build = "build: DEBUG;"; mutex = "mutex: " PIPE_ATOMIC ";"; -#ifdef HAVE_LLVM - llvm = "LLVM;"; -#endif +#elif defined(VMX86_STATS) + build = "build: OPT;"; #else build = "build: RELEASE;"; #endif +#ifdef HAVE_LLVM + llvm = "LLVM;"; +#endif util_snprintf(name, sizeof(name), "SVGA3D; %s %s %s", build, mutex, llvm); return name; } +/** Helper for querying float-valued device cap */ +static float +get_float_cap(struct svga_winsys_screen *sws, unsigned cap, float defaultVal) +{ + SVGA3dDevCapResult result; + if (sws->get_cap(sws, cap, &result)) + return result.f; + else + return defaultVal; +} + + +/** Helper for querying uint-valued device cap */ +static unsigned +get_uint_cap(struct svga_winsys_screen *sws, unsigned cap, unsigned defaultVal) +{ + SVGA3dDevCapResult result; + if (sws->get_cap(sws, cap, &result)) + return result.u; + else + return defaultVal; +} + + +/** Helper for querying boolean-valued device cap */ +static boolean +get_bool_cap(struct svga_winsys_screen *sws, unsigned cap, boolean defaultVal) +{ + SVGA3dDevCapResult result; + if (sws->get_cap(sws, cap, &result)) + return result.b; + else + return defaultVal; +} static float @@ -99,7 +141,6 @@ svga_get_paramf(struct pipe_screen *screen, enum pipe_capf param) { struct svga_screen *svgascreen = svga_screen(screen); struct svga_winsys_screen *sws = svgascreen->sws; - SVGA3dDevCapResult result; switch (param) { case PIPE_CAPF_MAX_LINE_WIDTH: @@ -113,12 +154,11 @@ svga_get_paramf(struct pipe_screen *screen, enum pipe_capf param) return svgascreen->maxPointSize; case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: - if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, &result)) - return 4.0f; - return (float) result.u; + return (float) get_uint_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, 4); case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: return 15.0; + case PIPE_CAPF_GUARD_BAND_LEFT: case PIPE_CAPF_GUARD_BAND_TOP: case PIPE_CAPF_GUARD_BAND_RIGHT: @@ -141,11 +181,17 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) switch (param) { case PIPE_CAP_NPOT_TEXTURES: case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: + case PIPE_CAP_MIXED_COLOR_DEPTH_BITS: return 1; case PIPE_CAP_TWO_SIDED_STENCIL: return 1; case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: - return 0; + /* + * "In virtually every OpenGL implementation and hardware, + * GL_MAX_DUAL_SOURCE_DRAW_BUFFERS is 1" + * http://www.opengl.org/wiki/Blending + */ + return sws->have_vgpu10 ? 1 : 0; case PIPE_CAP_ANISOTROPIC_FILTER: return 1; case PIPE_CAP_POINT_SPRITE: @@ -158,6 +204,8 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) return 1; case PIPE_CAP_QUERY_TIME_ELAPSED: return 0; + case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: + return sws->have_vgpu10; case PIPE_CAP_TEXTURE_SHADOW_MAP: return 1; case PIPE_CAP_TEXTURE_SWIZZLE: @@ -165,12 +213,11 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: return 0; case PIPE_CAP_USER_VERTEX_BUFFERS: - case PIPE_CAP_USER_INDEX_BUFFERS: return 0; case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: - return 16; + return 256; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: { @@ -199,17 +246,20 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) return MIN2(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS), 12 /* 2048x2048 */); + case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: + return sws->have_vgpu10 ? SVGA3D_MAX_SURFACE_ARRAYSIZE : 0; + case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */ return 1; case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: return 1; case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: - return 0; + return sws->have_vgpu10; case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: return 0; case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: - return 1; + return !sws->have_vgpu10; case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: return 1; /* The color outputs of vertex shaders are not clamped */ @@ -222,7 +272,7 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) return 1; /* expected for GL_ARB_framebuffer_object */ case PIPE_CAP_GLSL_FEATURE_LEVEL: - return 120; + return sws->have_vgpu10 ? 330 : 120; case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: return 0; @@ -230,54 +280,76 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_SM3: return 1; - /* Unsupported features */ - case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: - case PIPE_CAP_TEXTURE_MIRROR_CLAMP: - case PIPE_CAP_SHADER_STENCIL_EXPORT: case PIPE_CAP_DEPTH_CLIP_DISABLE: - case PIPE_CAP_SEAMLESS_CUBE_MAP: - case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: case PIPE_CAP_INDEP_BLEND_ENABLE: - case PIPE_CAP_INDEP_BLEND_FUNC: - case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: - case PIPE_CAP_PRIMITIVE_RESTART: + case PIPE_CAP_CONDITIONAL_RENDER: + case PIPE_CAP_QUERY_TIMESTAMP: case PIPE_CAP_TGSI_INSTANCEID: case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: - case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: + case PIPE_CAP_SEAMLESS_CUBE_MAP: + case PIPE_CAP_FAKE_SW_MSAA: + return sws->have_vgpu10; + + case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: + return sws->have_vgpu10 ? SVGA3D_DX_MAX_SOTARGETS : 0; + case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: + return sws->have_vgpu10 ? 4 : 0; + case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: + return sws->have_vgpu10 ? SVGA3D_MAX_STREAMOUT_DECLS : 0; + case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: + case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS: + return 0; + case PIPE_CAP_TEXTURE_MULTISAMPLE: + return svgascreen->ms_samples ? 1 : 0; + + case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE: + return SVGA3D_DX_MAX_RESOURCE_SIZE; + case PIPE_CAP_MIN_TEXEL_OFFSET: + return sws->have_vgpu10 ? VGPU10_MIN_TEXEL_FETCH_OFFSET : 0; case PIPE_CAP_MAX_TEXEL_OFFSET: + return sws->have_vgpu10 ? VGPU10_MAX_TEXEL_FETCH_OFFSET : 0; + case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET: case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: - case PIPE_CAP_CONDITIONAL_RENDER: - case PIPE_CAP_TEXTURE_BARRIER: - case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: - case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: - case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: + return 0; + case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES: + return sws->have_vgpu10 ? 256 : 0; case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: + return sws->have_vgpu10 ? 1024 : 0; + + case PIPE_CAP_PRIMITIVE_RESTART: + return 1; /* may be a sw fallback, depending on restart index */ + + case PIPE_CAP_GENERATE_MIPMAP: + return sws->have_generate_mipmap_cmd; + + /* Unsupported features */ + case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: + case PIPE_CAP_TEXTURE_MIRROR_CLAMP: + case PIPE_CAP_SHADER_STENCIL_EXPORT: + case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: + case PIPE_CAP_INDEP_BLEND_FUNC: + case PIPE_CAP_TEXTURE_BARRIER: case PIPE_CAP_MAX_VERTEX_STREAMS: case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: - case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: - case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: case PIPE_CAP_COMPUTE: case PIPE_CAP_START_INSTANCE: - case PIPE_CAP_QUERY_TIMESTAMP: - case PIPE_CAP_TEXTURE_MULTISAMPLE: case PIPE_CAP_CUBE_MAP_ARRAY: - case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: case PIPE_CAP_QUERY_PIPELINE_STATISTICS: - case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE: case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT: case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: case PIPE_CAP_TEXTURE_GATHER_SM5: case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: - case PIPE_CAP_FAKE_SW_MSAA: case PIPE_CAP_TEXTURE_QUERY_LOD: case PIPE_CAP_SAMPLE_SHADING: case PIPE_CAP_TEXTURE_GATHER_OFFSETS: case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION: case PIPE_CAP_DRAW_INDIRECT: + case PIPE_CAP_MULTI_DRAW_INDIRECT: + case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS: case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE: case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: case PIPE_CAP_SAMPLER_VIEW_TARGET: @@ -285,11 +357,25 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_VERTEXID_NOBASE: case PIPE_CAP_POLYGON_OFFSET_CLAMP: case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: + case PIPE_CAP_TGSI_PACK_HALF_FLOAT: + case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT: + case PIPE_CAP_INVALIDATE_BUFFER: + case PIPE_CAP_STRING_MARKER: + case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS: + case PIPE_CAP_QUERY_MEMORY_INFO: + case PIPE_CAP_PCI_GROUP: + case PIPE_CAP_PCI_BUS: + case PIPE_CAP_PCI_DEVICE: + case PIPE_CAP_PCI_FUNCTION: + case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR: + case PIPE_CAP_NATIVE_FENCE_FD: return 0; case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: return 64; + case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: + case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: - return 1; + return 1; /* need 4-byte alignment for all offsets and strides */ case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE: return 2048; case PIPE_CAP_MAX_VIEWPORTS: @@ -306,6 +392,10 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_VIDEO_MEMORY: /* XXX: Query the host ? */ return 1; + case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS: + return sws->have_vgpu10; + case PIPE_CAP_CLEAR_TEXTURE: + return sws->have_vgpu10; case PIPE_CAP_UMA: case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: @@ -313,6 +403,29 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_TEXTURE_FLOAT_LINEAR: case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR: case PIPE_CAP_DEPTH_BOUNDS_TEST: + case PIPE_CAP_TGSI_TXQS: + case PIPE_CAP_FORCE_PERSAMPLE_INTERP: + case PIPE_CAP_SHAREABLE_SHADERS: + case PIPE_CAP_DRAW_PARAMETERS: + case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL: + case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL: + case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY: + case PIPE_CAP_QUERY_BUFFER_OBJECT: + case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT: + case PIPE_CAP_CULL_DISTANCE: + case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES: + case PIPE_CAP_TGSI_VOTE: + case PIPE_CAP_MAX_WINDOW_RECTANGLES: + case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED: + case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS: + case PIPE_CAP_TGSI_ARRAY_COMPONENTS: + case PIPE_CAP_TGSI_CAN_READ_OUTPUTS: + case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY: + case PIPE_CAP_TGSI_FS_FBFETCH: + case PIPE_CAP_TGSI_MUL_ZERO_WINS: + case PIPE_CAP_DOUBLES: + case PIPE_CAP_INT64: + case PIPE_CAP_INT64_DIVMOD: return 0; } @@ -320,11 +433,16 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) return 0; } -static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param) + +static int +vgpu9_get_shader_param(struct pipe_screen *screen, unsigned shader, + enum pipe_shader_cap param) { struct svga_screen *svgascreen = svga_screen(screen); struct svga_winsys_screen *sws = svgascreen->sws; - SVGA3dDevCapResult result; + unsigned val; + + assert(!sws->have_vgpu10); switch (shader) { @@ -333,6 +451,9 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en { case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: + return get_uint_cap(sws, + SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS, + 512); case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: return 512; @@ -347,9 +468,8 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: return 1; case PIPE_SHADER_CAP_MAX_TEMPS: - if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS, &result)) - return 32; - return MIN2(result.u, SVGA3D_TEMPREG_MAX); + val = get_uint_cap(sws, SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS, 32); + return MIN2(val, SVGA3D_TEMPREG_MAX); case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: /* * Although PS 3.0 has some addressing abilities it can only represent @@ -377,12 +497,18 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en return 16; case PIPE_SHADER_CAP_PREFERRED_IR: return PIPE_SHADER_IR_TGSI; - case PIPE_SHADER_CAP_DOUBLES: + case PIPE_SHADER_CAP_SUPPORTED_IRS: + return 0; case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED: case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED: case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED: case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: + case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: + case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: + case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD: return 0; + case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT: + return 32; } /* If we get here, we failed to handle a cap above */ debug_printf("Unexpected fragment shader query %u\n", param); @@ -392,9 +518,8 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en { case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: - if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS, &result)) - return 512; - return result.u; + return get_uint_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS, + 512); case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: /* XXX: until we have vertex texture support */ @@ -410,9 +535,8 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: return 1; case PIPE_SHADER_CAP_MAX_TEMPS: - if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS, &result)) - return 32; - return MIN2(result.u, SVGA3D_TEMPREG_MAX); + val = get_uint_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS, 32); + return MIN2(val, SVGA3D_TEMPREG_MAX); case PIPE_SHADER_CAP_MAX_PREDS: return 1; case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: @@ -435,12 +559,18 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en return 0; case PIPE_SHADER_CAP_PREFERRED_IR: return PIPE_SHADER_IR_TGSI; - case PIPE_SHADER_CAP_DOUBLES: + case PIPE_SHADER_CAP_SUPPORTED_IRS: + return 0; case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED: case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED: case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED: case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: + case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: + case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: + case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD: return 0; + case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT: + return 32; } /* If we get here, we failed to handle a cap above */ debug_printf("Unexpected vertex shader query %u\n", param); @@ -459,8 +589,108 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en } +static int +vgpu10_get_shader_param(struct pipe_screen *screen, unsigned shader, + enum pipe_shader_cap param) +{ + struct svga_screen *svgascreen = svga_screen(screen); + struct svga_winsys_screen *sws = svgascreen->sws; + + assert(sws->have_vgpu10); + (void) sws; /* silence unused var warnings in non-debug builds */ + + /* Only VS, GS, FS supported */ + if (shader != PIPE_SHADER_VERTEX && + shader != PIPE_SHADER_GEOMETRY && + shader != PIPE_SHADER_FRAGMENT) { + return 0; + } + + /* NOTE: we do not query the device for any caps/limits at this time */ + + /* Generally the same limits for vertex, geometry and fragment shaders */ + switch (param) { + case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: + case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: + case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: + case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: + return 64 * 1024; + case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: + return 64; + case PIPE_SHADER_CAP_MAX_INPUTS: + if (shader == PIPE_SHADER_FRAGMENT) + return VGPU10_MAX_FS_INPUTS; + else if (shader == PIPE_SHADER_GEOMETRY) + return VGPU10_MAX_GS_INPUTS; + else + return VGPU10_MAX_VS_INPUTS; + case PIPE_SHADER_CAP_MAX_OUTPUTS: + if (shader == PIPE_SHADER_FRAGMENT) + return VGPU10_MAX_FS_OUTPUTS; + else if (shader == PIPE_SHADER_GEOMETRY) + return VGPU10_MAX_GS_OUTPUTS; + else + return VGPU10_MAX_VS_OUTPUTS; + case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE: + return VGPU10_MAX_CONSTANT_BUFFER_ELEMENT_COUNT * sizeof(float[4]); + case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: + return svgascreen->max_const_buffers; + case PIPE_SHADER_CAP_MAX_TEMPS: + return VGPU10_MAX_TEMPS; + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: + case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: + return TRUE; /* XXX verify */ + case PIPE_SHADER_CAP_MAX_PREDS: + return 0; + case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: + case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: + case PIPE_SHADER_CAP_SUBROUTINES: + case PIPE_SHADER_CAP_INTEGERS: + return TRUE; + case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: + case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: + return SVGA3D_DX_MAX_SAMPLERS; + case PIPE_SHADER_CAP_PREFERRED_IR: + return PIPE_SHADER_IR_TGSI; + case PIPE_SHADER_CAP_SUPPORTED_IRS: + return 0; + case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED: + case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED: + case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED: + case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: + case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: + case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: + case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD: + return 0; + case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT: + return 32; + default: + debug_printf("Unexpected vgpu10 shader query %u\n", param); + return 0; + } + return 0; +} + + +static int +svga_get_shader_param(struct pipe_screen *screen, unsigned shader, + enum pipe_shader_cap param) +{ + struct svga_screen *svgascreen = svga_screen(screen); + struct svga_winsys_screen *sws = svgascreen->sws; + if (sws->have_vgpu10) { + return vgpu10_get_shader_param(screen, shader, param); + } + else { + return vgpu9_get_shader_param(screen, shader, param); + } +} + + /** - * Implemnt pipe_screen::is_format_supported(). + * Implement pipe_screen::is_format_supported(). * \param bindings bitmask of PIPE_BIND_x flags */ static boolean @@ -478,7 +708,12 @@ svga_is_format_supported( struct pipe_screen *screen, assert(bindings); if (sample_count > 1) { - return FALSE; + /* In ms_samples, if bit N is set it means that we support + * multisample with N+1 samples per pixel. + */ + if ((ss->ms_samples & (1 << (sample_count - 1))) == 0) { + return FALSE; + } } svga_format = svga_translate_format(ss, format, bindings); @@ -486,6 +721,22 @@ svga_is_format_supported( struct pipe_screen *screen, return FALSE; } + /* we don't support sRGB rendering into display targets */ + if (util_format_is_srgb(format) && (bindings & PIPE_BIND_DISPLAY_TARGET)) { + return FALSE; + } + + /* + * For VGPU10 vertex formats, skip querying host capabilities + */ + + if (ss->sws->have_vgpu10 && (bindings & PIPE_BIND_VERTEX_BUFFER)) { + SVGA3dSurfaceFormat svga_format; + unsigned flags; + svga_translate_vertex_format_vgpu10(format, &svga_format, &flags); + return svga_format != SVGA3D_FORMAT_INVALID; + } + /* * Override host capabilities, so that we end up with the same * visuals for all virtual hardware implementations. @@ -498,6 +749,12 @@ svga_is_format_supported( struct pipe_screen *screen, case SVGA3D_R5G6B5: break; + /* VGPU10 formats */ + case SVGA3D_B8G8R8A8_UNORM: + case SVGA3D_B8G8R8X8_UNORM: + case SVGA3D_B5G6R5_UNORM: + break; + /* Often unsupported/problematic. This means we end up with the same * visuals for all virtual hardware implementations. */ @@ -516,22 +773,32 @@ svga_is_format_supported( struct pipe_screen *screen, svga_get_format_cap(ss, svga_format, &caps); + if (bindings & PIPE_BIND_RENDER_TARGET) { + /* Check that the color surface is blendable, unless it's an + * integer format. + */ + if (!svga_format_is_integer(svga_format) && + (caps.value & SVGA3DFORMAT_OP_NOALPHABLEND)) { + return FALSE; + } + } + mask.value = 0; if (bindings & PIPE_BIND_RENDER_TARGET) { - mask.offscreenRenderTarget = 1; + mask.value |= SVGA3DFORMAT_OP_OFFSCREEN_RENDERTARGET; } if (bindings & PIPE_BIND_DEPTH_STENCIL) { - mask.zStencil = 1; + mask.value |= SVGA3DFORMAT_OP_ZSTENCIL; } if (bindings & PIPE_BIND_SAMPLER_VIEW) { - mask.texture = 1; + mask.value |= SVGA3DFORMAT_OP_TEXTURE; } if (target == PIPE_TEXTURE_CUBE) { - mask.cubeTexture = 1; + mask.value |= SVGA3DFORMAT_OP_CUBETEXTURE; } - if (target == PIPE_TEXTURE_3D) { - mask.volumeTexture = 1; + else if (target == PIPE_TEXTURE_3D) { + mask.value |= SVGA3DFORMAT_OP_VOLUMETEXTURE; } return (caps.value & mask.value) == mask.value; @@ -550,18 +817,28 @@ svga_fence_reference(struct pipe_screen *screen, static boolean svga_fence_finish(struct pipe_screen *screen, + struct pipe_context *ctx, struct pipe_fence_handle *fence, uint64_t timeout) { struct svga_winsys_screen *sws = svga_screen(screen)->sws; + boolean retVal; + + SVGA_STATS_TIME_PUSH(sws, SVGA_STATS_TIME_FENCEFINISH); - if (!timeout) - return sws->fence_signalled(sws, fence, 0) == 0; + if (!timeout) { + retVal = sws->fence_signalled(sws, fence, 0) == 0; + } + else { + SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n", + __FUNCTION__, fence); + + retVal = sws->fence_finish(sws, fence, 0) == 0; + } - SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n", - __FUNCTION__, fence); + SVGA_STATS_TIME_POP(sws); - return sws->fence_finish(sws, fence, 0) == 0; + return retVal; } @@ -570,16 +847,64 @@ svga_get_driver_query_info(struct pipe_screen *screen, unsigned index, struct pipe_driver_query_info *info) { +#define QUERY(NAME, ENUM, UNITS) \ + {NAME, ENUM, {0}, UNITS, PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE, 0, 0x0} + static const struct pipe_driver_query_info queries[] = { - {"draw-calls", SVGA_QUERY_DRAW_CALLS, {0}}, - {"fallbacks", SVGA_QUERY_FALLBACKS, {0}}, - {"memory-used", SVGA_QUERY_MEMORY_USED, {0}, PIPE_DRIVER_QUERY_TYPE_BYTES} + /* per-frame counters */ + QUERY("num-draw-calls", SVGA_QUERY_NUM_DRAW_CALLS, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("num-fallbacks", SVGA_QUERY_NUM_FALLBACKS, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("num-flushes", SVGA_QUERY_NUM_FLUSHES, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("num-validations", SVGA_QUERY_NUM_VALIDATIONS, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("map-buffer-time", SVGA_QUERY_MAP_BUFFER_TIME, + PIPE_DRIVER_QUERY_TYPE_MICROSECONDS), + QUERY("num-buffers-mapped", SVGA_QUERY_NUM_BUFFERS_MAPPED, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("num-textures-mapped", SVGA_QUERY_NUM_TEXTURES_MAPPED, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("num-bytes-uploaded", SVGA_QUERY_NUM_BYTES_UPLOADED, + PIPE_DRIVER_QUERY_TYPE_BYTES), + QUERY("command-buffer-size", SVGA_QUERY_COMMAND_BUFFER_SIZE, + PIPE_DRIVER_QUERY_TYPE_BYTES), + QUERY("flush-time", SVGA_QUERY_FLUSH_TIME, + PIPE_DRIVER_QUERY_TYPE_MICROSECONDS), + QUERY("surface-write-flushes", SVGA_QUERY_SURFACE_WRITE_FLUSHES, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("num-readbacks", SVGA_QUERY_NUM_READBACKS, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("num-resource-updates", SVGA_QUERY_NUM_RESOURCE_UPDATES, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("num-buffer-uploads", SVGA_QUERY_NUM_BUFFER_UPLOADS, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("num-const-buf-updates", SVGA_QUERY_NUM_CONST_BUF_UPDATES, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("num-const-updates", SVGA_QUERY_NUM_CONST_UPDATES, + PIPE_DRIVER_QUERY_TYPE_UINT64), + + /* running total counters */ + QUERY("memory-used", SVGA_QUERY_MEMORY_USED, + PIPE_DRIVER_QUERY_TYPE_BYTES), + QUERY("num-shaders", SVGA_QUERY_NUM_SHADERS, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("num-resources", SVGA_QUERY_NUM_RESOURCES, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("num-state-objects", SVGA_QUERY_NUM_STATE_OBJECTS, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("num-surface-views", SVGA_QUERY_NUM_SURFACE_VIEWS, + PIPE_DRIVER_QUERY_TYPE_UINT64), + QUERY("num-generate-mipmap", SVGA_QUERY_NUM_GENERATE_MIPMAP, + PIPE_DRIVER_QUERY_TYPE_UINT64), }; +#undef QUERY if (!info) - return Elements(queries); + return ARRAY_SIZE(queries); - if (index >= Elements(queries)) + if (index >= ARRAY_SIZE(queries)) return 0; *info = queries[index]; @@ -611,8 +936,6 @@ svga_screen_create(struct svga_winsys_screen *sws) { struct svga_screen *svgascreen; struct pipe_screen *screen; - SVGA3dDevCapResult result; - boolean use_vs30, use_ps30; #ifdef DEBUG SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 ); @@ -632,6 +955,8 @@ svga_screen_create(struct svga_winsys_screen *sws) debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE); svgascreen->debug.no_sampler_view = debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE); + svgascreen->debug.no_cache_index_buffers = + debug_get_bool_option("SVGA_NO_CACHE_INDEX_BUFFERS", FALSE); screen = &svgascreen->screen; @@ -642,6 +967,7 @@ svga_screen_create(struct svga_winsys_screen *sws) screen->get_param = svga_get_param; screen->get_shader_param = svga_get_shader_param; screen->get_paramf = svga_get_paramf; + screen->get_timestamp = NULL; screen->is_format_supported = svga_is_format_supported; screen->context_create = svga_context_create; screen->fence_reference = svga_fence_reference; @@ -657,18 +983,6 @@ svga_screen_create(struct svga_winsys_screen *sws) svgascreen->hw_version = SVGA3D_HWVERSION_WS65_B1; } - use_ps30 = - sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) && - result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE; - - use_vs30 = - sws->get_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION, &result) && - result.u >= SVGA3DVSVERSION_30 ? TRUE : FALSE; - - /* we require Shader model 3.0 or later */ - if (!use_ps30 || !use_vs30) - goto error2; - /* * The D16, D24X8, and D24S8 formats always do an implicit shadow compare * when sampled from, where as the DF16, DF24, and D24S8_INT do not. So @@ -716,48 +1030,82 @@ svga_screen_create(struct svga_winsys_screen *sws) /* Query device caps */ - if (!sws->get_cap(sws, SVGA3D_DEVCAP_LINE_STIPPLE, &result)) - svgascreen->haveLineStipple = FALSE; - else - svgascreen->haveLineStipple = result.u; + if (sws->have_vgpu10) { + svgascreen->haveProvokingVertex + = get_bool_cap(sws, SVGA3D_DEVCAP_DX_PROVOKING_VERTEX, FALSE); + svgascreen->haveLineSmooth = TRUE; + svgascreen->maxPointSize = 80.0F; + svgascreen->max_color_buffers = SVGA3D_DX_MAX_RENDER_TARGETS; + + /* Multisample samples per pixel */ + if (debug_get_bool_option("SVGA_MSAA", TRUE)) { + svgascreen->ms_samples = + get_uint_cap(sws, SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES, 0); + } - if (!sws->get_cap(sws, SVGA3D_DEVCAP_LINE_AA, &result)) - svgascreen->haveLineSmooth = FALSE; - else - svgascreen->haveLineSmooth = result.u; + /* Maximum number of constant buffers */ + svgascreen->max_const_buffers = + get_uint_cap(sws, SVGA3D_DEVCAP_DX_MAX_CONSTANT_BUFFERS, 1); + assert(svgascreen->max_const_buffers <= SVGA_MAX_CONST_BUFS); + } + else { + /* VGPU9 */ + unsigned vs_ver = get_uint_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION, + SVGA3DVSVERSION_NONE); + unsigned fs_ver = get_uint_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, + SVGA3DPSVERSION_NONE); + + /* we require Shader model 3.0 or later */ + if (fs_ver < SVGA3DPSVERSION_30 || vs_ver < SVGA3DVSVERSION_30) { + goto error2; + } - if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_LINE_WIDTH, &result)) - svgascreen->maxLineWidth = 1.0F; - else - svgascreen->maxLineWidth = result.f; + svgascreen->haveProvokingVertex = FALSE; - if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH, &result)) - svgascreen->maxLineWidthAA = 1.0F; - else - svgascreen->maxLineWidthAA = result.f; + svgascreen->haveLineSmooth = + get_bool_cap(sws, SVGA3D_DEVCAP_LINE_AA, FALSE); + + svgascreen->maxPointSize = + get_float_cap(sws, SVGA3D_DEVCAP_MAX_POINT_SIZE, 1.0f); + /* Keep this to a reasonable size to avoid failures in conform/pntaa.c */ + svgascreen->maxPointSize = MIN2(svgascreen->maxPointSize, 80.0f); + + /* The SVGA3D device always supports 4 targets at this time, regardless + * of what querying SVGA3D_DEVCAP_MAX_RENDER_TARGETS might return. + */ + svgascreen->max_color_buffers = 4; + + /* Only support one constant buffer + */ + svgascreen->max_const_buffers = 1; + + /* No multisampling */ + svgascreen->ms_samples = 0; + } + + /* common VGPU9 / VGPU10 caps */ + svgascreen->haveLineStipple = + get_bool_cap(sws, SVGA3D_DEVCAP_LINE_STIPPLE, FALSE); + + svgascreen->maxLineWidth = + get_float_cap(sws, SVGA3D_DEVCAP_MAX_LINE_WIDTH, 1.0f); + + svgascreen->maxLineWidthAA = + get_float_cap(sws, SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH, 1.0f); - if (0) + if (0) { + debug_printf("svga: haveProvokingVertex %u\n", + svgascreen->haveProvokingVertex); debug_printf("svga: haveLineStip %u " "haveLineSmooth %u maxLineWidth %f\n", svgascreen->haveLineStipple, svgascreen->haveLineSmooth, svgascreen->maxLineWidth); - - if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_POINT_SIZE, &result)) { - svgascreen->maxPointSize = 1.0F; - } else { - /* Keep this to a reasonable size to avoid failures in - * conform/pntaa.c: - */ - svgascreen->maxPointSize = MIN2(result.f, 80.0f); + debug_printf("svga: maxPointSize %g\n", svgascreen->maxPointSize); + debug_printf("svga: msaa samples mask: 0x%x\n", svgascreen->ms_samples); } - /* The SVGA3D device always supports 4 targets at this time, regardless - * of what querying SVGA3D_DEVCAP_MAX_RENDER_TARGETS might return. - */ - svgascreen->max_color_buffers = 4; - - pipe_mutex_init(svgascreen->tex_mutex); - pipe_mutex_init(svgascreen->swc_mutex); + (void) mtx_init(&svgascreen->tex_mutex, mtx_plain); + (void) mtx_init(&svgascreen->swc_mutex, mtx_plain); svga_screen_cache_init(svgascreen);