/** * Create a new svga_screen object */ struct pipe_screen * svga_screen_create(struct svga_winsys_screen *sws) { struct svga_screen *svgascreen; struct pipe_screen *screen; #ifdef DEBUG SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 ); #endif svgascreen = CALLOC_STRUCT(svga_screen); if (!svgascreen) goto error1; svgascreen->debug.force_level_surface_view = debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE); svgascreen->debug.force_surface_view = debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE); svgascreen->debug.force_sampler_view = debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE); svgascreen->debug.no_surface_view = debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE); svgascreen->debug.no_sampler_view = debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE); screen = &svgascreen->screen; screen->destroy = svga_destroy_screen; screen->get_name = svga_get_name; screen->get_vendor = svga_get_vendor; screen->get_device_vendor = svga_get_vendor; // TODO actual device vendor 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; screen->fence_finish = svga_fence_finish; screen->get_driver_query_info = svga_get_driver_query_info; svgascreen->sws = sws; svga_init_screen_resource_functions(svgascreen); if (sws->get_hw_version) { svgascreen->hw_version = sws->get_hw_version(sws); } else { svgascreen->hw_version = SVGA3D_HWVERSION_WS65_B1; } /* * 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 * we prefer the later when available. * * This mimics hardware vendors extensions for D3D depth sampling. See also * http://aras-p.info/texts/D3D9GPUHacks.html */ { boolean has_df16, has_df24, has_d24s8_int; SVGA3dSurfaceFormatCaps caps; SVGA3dSurfaceFormatCaps mask; mask.value = 0; mask.zStencil = 1; mask.texture = 1; svgascreen->depth.z16 = SVGA3D_Z_D16; svgascreen->depth.x8z24 = SVGA3D_Z_D24X8; svgascreen->depth.s8z24 = SVGA3D_Z_D24S8; svga_get_format_cap(svgascreen, SVGA3D_Z_DF16, &caps); has_df16 = (caps.value & mask.value) == mask.value; svga_get_format_cap(svgascreen, SVGA3D_Z_DF24, &caps); has_df24 = (caps.value & mask.value) == mask.value; svga_get_format_cap(svgascreen, SVGA3D_Z_D24S8_INT, &caps); has_d24s8_int = (caps.value & mask.value) == mask.value; /* XXX: We might want some other logic here. * Like if we only have d24s8_int we should * emulate the other formats with that. */ if (has_df16) { svgascreen->depth.z16 = SVGA3D_Z_DF16; } if (has_df24) { svgascreen->depth.x8z24 = SVGA3D_Z_DF24; } if (has_d24s8_int) { svgascreen->depth.s8z24 = SVGA3D_Z_D24S8_INT; } } /* Query device caps */ 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 */ svgascreen->ms_samples = get_uint_cap(sws, SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES, 0); /* 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; } svgascreen->haveProvokingVertex = FALSE; 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) { debug_printf("svga: haveProvokingVertex %u\n", svgascreen->haveProvokingVertex); debug_printf("svga: haveLineStip %u " "haveLineSmooth %u maxLineWidth %f\n", svgascreen->haveLineStipple, svgascreen->haveLineSmooth, svgascreen->maxLineWidth); debug_printf("svga: maxPointSize %g\n", svgascreen->maxPointSize); } pipe_mutex_init(svgascreen->tex_mutex); pipe_mutex_init(svgascreen->swc_mutex); svga_screen_cache_init(svgascreen); return screen; error2: FREE(svgascreen); error1: return NULL; }
/** * Implement pipe_screen::is_format_supported(). * \param bindings bitmask of PIPE_BIND_x flags */ static boolean svga_is_format_supported( struct pipe_screen *screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, unsigned bindings) { struct svga_screen *ss = svga_screen(screen); SVGA3dSurfaceFormat svga_format; SVGA3dSurfaceFormatCaps caps; SVGA3dSurfaceFormatCaps mask; assert(bindings); if (sample_count > 1) { /* 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); if (svga_format == SVGA3D_FORMAT_INVALID) { 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. */ if (bindings & PIPE_BIND_DISPLAY_TARGET) { switch (svga_format) { case SVGA3D_A8R8G8B8: case SVGA3D_X8R8G8B8: 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. */ case SVGA3D_A4R4G4B4: case SVGA3D_A1R5G5B5: return FALSE; default: return FALSE; } } /* * Query the host capabilities. */ 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.value |= SVGA3DFORMAT_OP_OFFSCREEN_RENDERTARGET; } if (bindings & PIPE_BIND_DEPTH_STENCIL) { mask.value |= SVGA3DFORMAT_OP_ZSTENCIL; } if (bindings & PIPE_BIND_SAMPLER_VIEW) { mask.value |= SVGA3DFORMAT_OP_TEXTURE; } if (target == PIPE_TEXTURE_CUBE) { mask.value |= SVGA3DFORMAT_OP_CUBETEXTURE; } else if (target == PIPE_TEXTURE_3D) { mask.value |= SVGA3DFORMAT_OP_VOLUMETEXTURE; } return (caps.value & mask.value) == mask.value; }
/** * Implemnt pipe_screen::is_format_supported(). * \param bindings bitmask of PIPE_BIND_x flags */ static boolean svga_is_format_supported( struct pipe_screen *screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, unsigned bindings) { struct svga_screen *ss = svga_screen(screen); SVGA3dSurfaceFormat svga_format; SVGA3dSurfaceFormatCaps caps; SVGA3dSurfaceFormatCaps mask; assert(bindings); if (sample_count > 1) { return FALSE; } svga_format = svga_translate_format(ss, format, bindings); if (svga_format == SVGA3D_FORMAT_INVALID) { return FALSE; } /* * Override host capabilities, so that we end up with the same * visuals for all virtual hardware implementations. */ if (bindings & PIPE_BIND_DISPLAY_TARGET) { switch (svga_format) { case SVGA3D_A8R8G8B8: case SVGA3D_X8R8G8B8: case SVGA3D_R5G6B5: break; /* Often unsupported/problematic. This means we end up with the same * visuals for all virtual hardware implementations. */ case SVGA3D_A4R4G4B4: case SVGA3D_A1R5G5B5: return FALSE; default: return FALSE; } } /* * Query the host capabilities. */ svga_get_format_cap(ss, svga_format, &caps); mask.value = 0; if (bindings & PIPE_BIND_RENDER_TARGET) { mask.offscreenRenderTarget = 1; } if (bindings & PIPE_BIND_DEPTH_STENCIL) { mask.zStencil = 1; } if (bindings & PIPE_BIND_SAMPLER_VIEW) { mask.texture = 1; } if (target == PIPE_TEXTURE_CUBE) { mask.cubeTexture = 1; } if (target == PIPE_TEXTURE_3D) { mask.volumeTexture = 1; } return (caps.value & mask.value) == mask.value; }
/** * Create a new svga_screen object */ struct pipe_screen * 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 ); #endif svgascreen = CALLOC_STRUCT(svga_screen); if (!svgascreen) goto error1; svgascreen->debug.force_level_surface_view = debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE); svgascreen->debug.force_surface_view = debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE); svgascreen->debug.force_sampler_view = debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE); svgascreen->debug.no_surface_view = debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE); svgascreen->debug.no_sampler_view = debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE); screen = &svgascreen->screen; screen->destroy = svga_destroy_screen; screen->get_name = svga_get_name; screen->get_vendor = svga_get_vendor; screen->get_param = svga_get_param; screen->get_shader_param = svga_get_shader_param; screen->get_paramf = svga_get_paramf; screen->is_format_supported = svga_is_format_supported; screen->context_create = svga_context_create; screen->fence_reference = svga_fence_reference; screen->fence_signalled = svga_fence_signalled; screen->fence_finish = svga_fence_finish; screen->get_driver_query_info = svga_get_driver_query_info; svgascreen->sws = sws; svga_init_screen_resource_functions(svgascreen); if (sws->get_hw_version) { svgascreen->hw_version = sws->get_hw_version(sws); } else { 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 * we prefer the later when available. * * This mimics hardware vendors extensions for D3D depth sampling. See also * http://aras-p.info/texts/D3D9GPUHacks.html */ { boolean has_df16, has_df24, has_d24s8_int; SVGA3dSurfaceFormatCaps caps; SVGA3dSurfaceFormatCaps mask; mask.value = 0; mask.zStencil = 1; mask.texture = 1; svgascreen->depth.z16 = SVGA3D_Z_D16; svgascreen->depth.x8z24 = SVGA3D_Z_D24X8; svgascreen->depth.s8z24 = SVGA3D_Z_D24S8; svga_get_format_cap(svgascreen, SVGA3D_Z_DF16, &caps); has_df16 = (caps.value & mask.value) == mask.value; svga_get_format_cap(svgascreen, SVGA3D_Z_DF24, &caps); has_df24 = (caps.value & mask.value) == mask.value; svga_get_format_cap(svgascreen, SVGA3D_Z_D24S8_INT, &caps); has_d24s8_int = (caps.value & mask.value) == mask.value; /* XXX: We might want some other logic here. * Like if we only have d24s8_int we should * emulate the other formats with that. */ if (has_df16) { svgascreen->depth.z16 = SVGA3D_Z_DF16; } if (has_df24) { svgascreen->depth.x8z24 = SVGA3D_Z_DF24; } if (has_d24s8_int) { svgascreen->depth.s8z24 = SVGA3D_Z_D24S8_INT; } } /* Query device caps */ if (!sws->get_cap(sws, SVGA3D_DEVCAP_LINE_STIPPLE, &result)) svgascreen->haveLineStipple = FALSE; else svgascreen->haveLineStipple = result.u; if (!sws->get_cap(sws, SVGA3D_DEVCAP_LINE_AA, &result)) svgascreen->haveLineSmooth = FALSE; else svgascreen->haveLineSmooth = result.u; if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_LINE_WIDTH, &result)) svgascreen->maxLineWidth = 1.0F; else svgascreen->maxLineWidth = result.f; if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH, &result)) svgascreen->maxLineWidthAA = 1.0F; else svgascreen->maxLineWidthAA = result.f; if (0) 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); } /* 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); svga_screen_cache_init(svgascreen); return screen; error2: FREE(svgascreen); error1: return NULL; }
/** * Create a new svga_screen object */ struct pipe_screen * 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 ); #endif svgascreen = CALLOC_STRUCT(svga_screen); if (!svgascreen) goto error1; svgascreen->debug.force_level_surface_view = debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE); svgascreen->debug.force_surface_view = debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE); svgascreen->debug.force_sampler_view = debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE); svgascreen->debug.no_surface_view = debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE); svgascreen->debug.no_sampler_view = debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE); screen = &svgascreen->screen; screen->destroy = svga_destroy_screen; screen->get_name = svga_get_name; screen->get_vendor = svga_get_vendor; screen->get_param = svga_get_param; screen->get_shader_param = svga_get_shader_param; screen->get_paramf = svga_get_paramf; screen->is_format_supported = svga_is_format_supported; screen->context_create = svga_context_create; screen->fence_reference = svga_fence_reference; screen->fence_signalled = svga_fence_signalled; screen->fence_finish = svga_fence_finish; svgascreen->sws = sws; svga_init_screen_resource_functions(svgascreen); if (sws->get_hw_version) { svgascreen->hw_version = sws->get_hw_version(sws); } else { 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 * we prefer the later when available. * * This mimics hardware vendors extensions for D3D depth sampling. See also * http://aras-p.info/texts/D3D9GPUHacks.html */ { boolean has_df16, has_df24, has_d24s8_int; SVGA3dSurfaceFormatCaps caps; SVGA3dSurfaceFormatCaps mask; mask.value = 0; mask.zStencil = 1; mask.texture = 1; svgascreen->depth.z16 = SVGA3D_Z_D16; svgascreen->depth.x8z24 = SVGA3D_Z_D24X8; svgascreen->depth.s8z24 = SVGA3D_Z_D24S8; svga_get_format_cap(svgascreen, SVGA3D_Z_DF16, &caps); has_df16 = (caps.value & mask.value) == mask.value; svga_get_format_cap(svgascreen, SVGA3D_Z_DF24, &caps); has_df24 = (caps.value & mask.value) == mask.value; svga_get_format_cap(svgascreen, SVGA3D_Z_D24S8_INT, &caps); has_d24s8_int = (caps.value & mask.value) == mask.value; /* XXX: We might want some other logic here. * Like if we only have d24s8_int we should * emulate the other formats with that. */ if (has_df16) { svgascreen->depth.z16 = SVGA3D_Z_DF16; } if (has_df24) { svgascreen->depth.x8z24 = SVGA3D_Z_DF24; } if (has_d24s8_int) { svgascreen->depth.s8z24 = SVGA3D_Z_D24S8_INT; } } pipe_mutex_init(svgascreen->tex_mutex); pipe_mutex_init(svgascreen->swc_mutex); svga_screen_cache_init(svgascreen); return screen; error2: FREE(svgascreen); error1: return NULL; }