public void Validate() { for (int attribIndex = 0; attribIndex < _vertexAttribsCount; attribIndex++) { VertexAttribDescriptor attrib = _vertexAttribs[attribIndex]; if (!attrib.IsZero) { if ((uint)attrib.BufferIndex >= _vertexBuffersCount) { DisableVertexAttrib(attribIndex); continue; } if (_vertexBuffers[attrib.BufferIndex].Buffer.Handle == BufferHandle.Null) { DisableVertexAttrib(attribIndex); continue; } if (_needsAttribsUpdate) { EnableVertexAttrib(attribIndex); } } } _needsAttribsUpdate = false; }
public void Validate() { for (int attribIndex = 0; attribIndex < _vertexAttribs.Length; attribIndex++) { VertexAttribDescriptor attrib = _vertexAttribs[attribIndex]; if ((uint)attrib.BufferIndex >= _vertexBuffers.Length) { GL.DisableVertexAttribArray(attribIndex); continue; } if (_vertexBuffers[attrib.BufferIndex].Buffer.Buffer == null) { GL.DisableVertexAttribArray(attribIndex); continue; } if (_needsAttribsUpdate && !attrib.IsZero) { GL.EnableVertexAttribArray(attribIndex); } } _needsAttribsUpdate = false; }
public void SetVertexAttributes(ReadOnlySpan <VertexAttribDescriptor> vertexAttribs) { int index = 0; for (; index < vertexAttribs.Length; index++) { VertexAttribDescriptor attrib = vertexAttribs[index]; if (attrib.Equals(_vertexAttribs[index])) { continue; } FormatInfo fmtInfo = FormatTable.GetFormatInfo(attrib.Format); if (attrib.IsZero) { // Disabling the attribute causes the shader to read a constant value. // The value is configurable, but by default is a vector of (0, 0, 0, 1). DisableVertexAttrib(index); } else { EnableVertexAttrib(index); } int offset = attrib.Offset; int size = fmtInfo.Components; bool isFloat = fmtInfo.PixelType == PixelType.Float || fmtInfo.PixelType == PixelType.HalfFloat; if (isFloat || fmtInfo.Normalized || fmtInfo.Scaled) { VertexAttribType type = (VertexAttribType)fmtInfo.PixelType; GL.VertexAttribFormat(index, size, type, fmtInfo.Normalized, offset); } else { VertexAttribIntegerType type = (VertexAttribIntegerType)fmtInfo.PixelType; GL.VertexAttribIFormat(index, size, type, offset); } GL.VertexAttribBinding(index, attrib.BufferIndex); _vertexAttribs[index] = attrib; } _vertexAttribsCount = index; for (; index < Constants.MaxVertexAttribs; index++) { DisableVertexAttrib(index); } }
/// <summary> /// Updates host vertex attributes based on guest GPU state. /// </summary> /// <param name="state">Current GPU state</param> private void UpdateVertexAttribState(GpuState state) { VertexAttribDescriptor[] vertexAttribs = new VertexAttribDescriptor[16]; for (int index = 0; index < 16; index++) { var vertexAttrib = state.Get <VertexAttribState>(MethodOffset.VertexAttribState, index); if (!FormatTable.TryGetAttribFormat(vertexAttrib.UnpackFormat(), out Format format)) { Logger.PrintDebug(LogClass.Gpu, $"Invalid attribute format 0x{vertexAttrib.UnpackFormat():X}."); format = Format.R32G32B32A32Float; } vertexAttribs[index] = new VertexAttribDescriptor( vertexAttrib.UnpackBufferIndex(), vertexAttrib.UnpackOffset(), format); } _context.Renderer.Pipeline.SetVertexAttribs(vertexAttribs); }
/// <summary> /// Updates host vertex attributes based on guest GPU state. /// </summary> private void UpdateVertexAttribState() { Span <VertexAttribDescriptor> vertexAttribs = stackalloc VertexAttribDescriptor[Constants.TotalVertexAttribs]; for (int index = 0; index < Constants.TotalVertexAttribs; index++) { var vertexAttrib = _state.State.VertexAttribState[index]; if (!FormatTable.TryGetAttribFormat(vertexAttrib.UnpackFormat(), out Format format)) { Logger.Debug?.Print(LogClass.Gpu, $"Invalid attribute format 0x{vertexAttrib.UnpackFormat():X}."); format = Format.R32G32B32A32Float; } vertexAttribs[index] = new VertexAttribDescriptor( vertexAttrib.UnpackBufferIndex(), vertexAttrib.UnpackOffset(), vertexAttrib.UnpackIsConstant(), format); } _context.Renderer.Pipeline.SetVertexAttribs(vertexAttribs); }