/** * Translate the vertex element types to SVGA3dDeclType and check * for VS-based vertex attribute adjustments. */ static void translate_vertex_decls(struct svga_context *svga, struct svga_velems_state *velems) { unsigned i; assert(!svga_have_vgpu10(svga)); for (i = 0; i < velems->count; i++) { const enum pipe_format f = velems->velem[i].src_format; SVGA3dSurfaceFormat svga_format; unsigned vf_flags; svga_translate_vertex_format_vgpu10(f, &svga_format, &vf_flags); velems->decl_type[i] = translate_vertex_format_to_decltype(f); if (velems->decl_type[i] == SVGA3D_DECLTYPE_MAX) { /* Unsupported format - use software fetch */ velems->need_swvfetch = TRUE; } /* Check for VS-based adjustments */ if (attrib_needs_range_adjustment(f)) { velems->adjust_attrib_range |= (1 << i); } if (vf_flags & VF_W_TO_1) { velems->adjust_attrib_w_1 |= (1 << i); } } }
/** * 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; }
static void define_input_element_object(struct svga_context *svga, struct svga_velems_state *velems) { SVGA3dInputElementDesc elements[PIPE_MAX_ATTRIBS]; enum pipe_error ret; unsigned i; assert(velems->count <= PIPE_MAX_ATTRIBS); assert(svga_have_vgpu10(svga)); for (i = 0; i < velems->count; i++) { const struct pipe_vertex_element *elem = velems->velem + i; SVGA3dSurfaceFormat svga_format; unsigned vf_flags; svga_translate_vertex_format_vgpu10(elem->src_format, &svga_format, &vf_flags); velems->decl_type[i] = translate_vertex_format_to_decltype(elem->src_format); elements[i].inputSlot = elem->vertex_buffer_index; elements[i].alignedByteOffset = elem->src_offset; elements[i].format = svga_format; if (elem->instance_divisor) { elements[i].inputSlotClass = SVGA3D_INPUT_PER_INSTANCE_DATA; elements[i].instanceDataStepRate = elem->instance_divisor; } else { elements[i].inputSlotClass = SVGA3D_INPUT_PER_VERTEX_DATA; elements[i].instanceDataStepRate = 0; } elements[i].inputRegister = i; if (elements[i].format == SVGA3D_FORMAT_INVALID) { velems->need_swvfetch = TRUE; } if (util_format_is_pure_integer(elem->src_format)) { velems->attrib_is_pure_int |= (1 << i); } if (vf_flags & VF_W_TO_1) { velems->adjust_attrib_w_1 |= (1 << i); } if (vf_flags & VF_U_TO_F_CAST) { velems->adjust_attrib_utof |= (1 << i); } else if (vf_flags & VF_I_TO_F_CAST) { velems->adjust_attrib_itof |= (1 << i); } if (vf_flags & VF_BGRA) { velems->attrib_is_bgra |= (1 << i); } if (vf_flags & VF_PUINT_TO_SNORM) { velems->attrib_puint_to_snorm |= (1 << i); } else if (vf_flags & VF_PUINT_TO_USCALED) { velems->attrib_puint_to_uscaled |= (1 << i); } else if (vf_flags & VF_PUINT_TO_SSCALED) { velems->attrib_puint_to_sscaled |= (1 << i); } } velems->id = util_bitmask_add(svga->input_element_object_id_bm); ret = SVGA3D_vgpu10_DefineElementLayout(svga->swc, velems->count, velems->id, elements); if (ret != PIPE_OK) { svga_context_flush(svga, NULL); ret = SVGA3D_vgpu10_DefineElementLayout(svga->swc, velems->count, velems->id, elements); assert(ret == PIPE_OK); } }