public override void Load(ChunkMeta meta, BinaryReader br) { base.Load(meta, br); uint Buffer = br.ReadUInt32(); resourceId = br.ReadUInt64(); // SwapbufferID BackbufferDescriptor = D3D11Reader.Read_D3D11_TEXTURE2D_DESC(br) as D3D11_TEXTURE2D_DESC; name = "Serialised Swap Chain Buffer"; // fakeBB }
public virtual void GetDesc( out D3D11_TEXTURE2D_DESC pDesc ) { var fp = GetFunctionPointer(10); if (m_GetDescFunc == null) { m_GetDescFunc = (GetDescFunc)Marshal.GetDelegateForFunctionPointer(fp, typeof(GetDescFunc)); } m_GetDescFunc(m_ptr, out pDesc); }
public virtual int CreateTexture2D( ref D3D11_TEXTURE2D_DESC pDesc, ref D3D11_SUBRESOURCE_DATA pInitialData, out ID3D11Texture2D ppTexture2D ) { var fp = GetFunctionPointer(5); if (m_CreateTexture2DFunc == null) { m_CreateTexture2DFunc = (CreateTexture2DFunc)Marshal.GetDelegateForFunctionPointer(fp, typeof(CreateTexture2DFunc)); } ppTexture2D = new ID3D11Texture2D(); return(m_CreateTexture2DFunc(m_ptr, ref pDesc, ref pInitialData, out ppTexture2D.PtrForNew)); }
ID3D11RenderTargetView Begin(HWND hWnd, out float width, out float height) { using (var texture = m_swapchain.GetBackbuffer(m_d3d11.Device, hWnd.Value)) { var desc = new D3D11_TEXTURE2D_DESC(); texture.GetDesc(ref desc); width = (float)desc.Width; height = (float)desc.Height; var rtv_desc = new D3D11_RENDER_TARGET_VIEW_DESC { Format = desc.Format, ViewDimension = D3D11_RTV_DIMENSION.TEXTURE2D }; var rtv = new ID3D11RenderTargetView(); m_d3d11.Device.CreateRenderTargetView(texture.Ptr, ref rtv_desc, ref rtv.PtrForNew).ThrowIfFailed(); return(rtv); } }
public override void Load(ChunkMeta meta, BinaryReader br) { base.Load(meta, br); Descriptor = D3D11Reader.Read_D3D11_TEXTURE2D_DESC(br) as D3D11_TEXTURE2D_DESC; // unused, just for the sake of the user { uint numSubresources = Descriptor.MipLevels != 0 ? Descriptor.MipLevels : Common.CalcNumMips(Descriptor.Width, Descriptor.Height, 1); numSubresources *= Descriptor.ArraySize; pInitialDatas = D3D11Reader.Read_D3D11_Array <D3D11_SUBRESOURCE_DATA>(br); // 初始化第一步 resourceId = br.ReadUInt64(); if (pInitialDatas != null) { D3D11Reader.Read_CreateTextureData(br, pInitialDatas, Descriptor.Width, Descriptor.Height, 1, Descriptor.Format, Descriptor.MipLevels, Descriptor.ArraySize, pInitialDatas != null); // 初始化第二步 } } }
public static object Read_D3D11_TEXTURE2D_DESC(BinaryReader br) { D3D11_TEXTURE2D_DESC desc = new D3D11_TEXTURE2D_DESC(); desc.offset = br.BaseStream.Position; desc.Width = br.ReadUInt32(); desc.Height = br.ReadUInt32(); desc.MipLevels = br.ReadUInt32(); desc.ArraySize = br.ReadUInt32(); desc.Format = (DXGI_FORMAT)br.ReadUInt32(); desc.SampleDesc = new DXGI_SAMPLE_DESC(); desc.SampleDesc.Count = br.ReadUInt32(); desc.SampleDesc.Quality = br.ReadUInt32(); desc.Usage = (D3D11_USAGE)br.ReadUInt32(); desc.BindFlags = br.ReadUInt32(); desc.CPUAccessFlags = br.ReadUInt32(); desc.MiscFlags = br.ReadUInt32(); desc.length = br.BaseStream.Position - desc.offset; return(desc); }
private void Init() { // this code is ported from https://gist.github.com/d7samurai/261c69490cce0620d0bfc93003cd1052 var fac = DXGIFunctions.CreateDXGIFactory2(); var flags = D3D11_CREATE_DEVICE_FLAG.D3D11_CREATE_DEVICE_BGRA_SUPPORT; #if DEBUG flags |= D3D11_CREATE_DEVICE_FLAG.D3D11_CREATE_DEVICE_DEBUG; #endif var d3D11Device = D3D11Functions.D3D11CreateDevice(null, D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_HARDWARE, flags, out _deviceContext); var mt = d3D11Device.As <ID3D11Multithread>(); mt?.SetMultithreadProtected(true); var desc = new DXGI_SWAP_CHAIN_DESC1(); desc.Format = DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; desc.SampleDesc.Count = 1; desc.BufferUsage = Constants.DXGI_USAGE_RENDER_TARGET_OUTPUT; desc.BufferCount = 2; // note: this causes a warning in debug // DXGI WARNING: IDXGIFactory::CreateSwapChain: Blt-model swap effects (DXGI_SWAP_EFFECT_DISCARD and DXGI_SWAP_EFFECT_SEQUENTIAL) are legacy swap effects that are predominantly superceded by their flip-model counterparts (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD). Please consider updating your application to leverage flip-model swap effects to benefit from modern presentation enhancements. More information is available at http://aka.ms/dxgiflipmodel. [ MISCELLANEOUS WARNING #294: ] _swapChain = fac.CreateSwapChainForHwnd <IDXGISwapChain1>(d3D11Device, Handle, desc); var frameBuffer = _swapChain.GetBuffer <ID3D11Texture2D>(0); _renderTargetView = d3D11Device.CreateRenderTargetView(frameBuffer); frameBuffer.Object.GetDesc(out var depthBufferDesc); _width = depthBufferDesc.Width; _height = depthBufferDesc.Height; depthBufferDesc.Format = DXGI_FORMAT.DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.BindFlags = (uint)D3D11_BIND_FLAG.D3D11_BIND_DEPTH_STENCIL; var depthBuffer = d3D11Device.CreateTexture2D <ID3D11Texture2D>(depthBufferDesc); _depthBufferView = d3D11Device.CreateDepthStencilView(depthBuffer); var vsBlob = D3D11Functions.D3DCompileFromFile("shaders.hlsl", "vs_main", "vs_5_0"); _vertexShader = d3D11Device.CreateVertexShader(vsBlob); var inputElements = new D3D11_INPUT_ELEMENT_DESC[] { new D3D11_INPUT_ELEMENT_DESC { SemanticName = "POS", Format = DXGI_FORMAT.DXGI_FORMAT_R32G32B32_FLOAT }, new D3D11_INPUT_ELEMENT_DESC { SemanticName = "NOR", Format = DXGI_FORMAT.DXGI_FORMAT_R32G32B32_FLOAT, AlignedByteOffset = unchecked ((uint)Constants.D3D11_APPEND_ALIGNED_ELEMENT) }, new D3D11_INPUT_ELEMENT_DESC { SemanticName = "TEX", Format = DXGI_FORMAT.DXGI_FORMAT_R32G32_FLOAT, AlignedByteOffset = unchecked ((uint)Constants.D3D11_APPEND_ALIGNED_ELEMENT) }, new D3D11_INPUT_ELEMENT_DESC { SemanticName = "COL", Format = DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT, AlignedByteOffset = unchecked ((uint)Constants.D3D11_APPEND_ALIGNED_ELEMENT) }, }; _inputLayout = d3D11Device.CreateInputLayout(inputElements, vsBlob); var psBlob = D3D11Functions.D3DCompileFromFile("shaders.hlsl", "ps_main", "ps_5_0"); _pixelShader = d3D11Device.CreatePixelShader(psBlob); var rasterizerDesc = new D3D11_RASTERIZER_DESC(); rasterizerDesc.FillMode = D3D11_FILL_MODE.D3D11_FILL_SOLID; rasterizerDesc.CullMode = D3D11_CULL_MODE.D3D11_CULL_BACK; _rasterizerState = d3D11Device.CreateRasterizerState(rasterizerDesc); var samplerDesc = new D3D11_SAMPLER_DESC(); samplerDesc.Filter = D3D11_FILTER.D3D11_FILTER_MIN_MAG_MIP_POINT; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_MODE.D3D11_TEXTURE_ADDRESS_BORDER; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_MODE.D3D11_TEXTURE_ADDRESS_BORDER; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_MODE.D3D11_TEXTURE_ADDRESS_BORDER; samplerDesc.BorderColor = new float[4]; samplerDesc.BorderColor[0] = 1; samplerDesc.BorderColor[1] = 1; samplerDesc.BorderColor[2] = 1; samplerDesc.BorderColor[3] = 1; samplerDesc.ComparisonFunc = D3D11_COMPARISON_FUNC.D3D11_COMPARISON_NEVER; _samplerState = d3D11Device.CreateSamplerState(samplerDesc); var depthStencilDesc = new D3D11_DEPTH_STENCIL_DESC(); depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK.D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_FUNC.D3D11_COMPARISON_LESS; _depthStencilState = d3D11Device.CreateDepthStencilState(depthStencilDesc); var blendDesc = new D3D11_BLEND_DESC(); blendDesc.RenderTarget = new D3D11_RENDER_TARGET_BLEND_DESC[8]; blendDesc.RenderTarget[0].BlendEnable = true; blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND.D3D11_BLEND_SRC_ALPHA; blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND.D3D11_BLEND_INV_SRC_ALPHA; blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP.D3D11_BLEND_OP_ADD; blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND.D3D11_BLEND_ZERO; blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND.D3D11_BLEND_ZERO; blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP.D3D11_BLEND_OP_ADD; blendDesc.RenderTarget[0].RenderTargetWriteMask = (byte)(D3D11_COLOR_WRITE_ENABLE.D3D11_COLOR_WRITE_ENABLE_ALL); _blendState = d3D11Device.CreateBlendState(blendDesc); var constantBufferDesc = new D3D11_BUFFER_DESC(); constantBufferDesc.ByteWidth = (uint)Marshal.SizeOf <VS_CONSTANT_BUFFER>(); constantBufferDesc.Usage = D3D11_USAGE.D3D11_USAGE_DYNAMIC; constantBufferDesc.BindFlags = (uint)D3D11_BIND_FLAG.D3D11_BIND_CONSTANT_BUFFER; constantBufferDesc.CPUAccessFlags = (uint)D3D11_CPU_ACCESS_FLAG.D3D11_CPU_ACCESS_WRITE; if ((constantBufferDesc.ByteWidth % 16) != 0) { throw new InvalidOperationException("Constant buffer size must be a multiple of 16."); } _constantBuffer = d3D11Device.CreateBuffer(constantBufferDesc); var vertexBufferDesc = new D3D11_BUFFER_DESC(); var gc = GCHandle.Alloc(Data.VertexData, GCHandleType.Pinned); vertexBufferDesc.ByteWidth = (uint)Data.VertexData.SizeOf(); vertexBufferDesc.Usage = D3D11_USAGE.D3D11_USAGE_IMMUTABLE; vertexBufferDesc.BindFlags = (uint)D3D11_BIND_FLAG.D3D11_BIND_VERTEX_BUFFER; var vertexData = new D3D11_SUBRESOURCE_DATA(); vertexData.pSysMem = gc.AddrOfPinnedObject(); _vertexBuffer = d3D11Device.CreateBuffer(vertexBufferDesc, vertexData); gc.Free(); var indexBufferDesc = new D3D11_BUFFER_DESC(); gc = GCHandle.Alloc(Data.IndexData, GCHandleType.Pinned); indexBufferDesc.ByteWidth = (uint)Data.IndexData.SizeOf(); indexBufferDesc.Usage = D3D11_USAGE.D3D11_USAGE_IMMUTABLE; indexBufferDesc.BindFlags = (uint)D3D11_BIND_FLAG.D3D11_BIND_INDEX_BUFFER; var indexData = new D3D11_SUBRESOURCE_DATA(); indexData.pSysMem = gc.AddrOfPinnedObject(); _indexBuffer = d3D11Device.CreateBuffer(indexBufferDesc, indexData); gc.Free(); var textureDesc = new D3D11_TEXTURE2D_DESC(); textureDesc.Width = 20; textureDesc.Height = 20; textureDesc.MipLevels = 1; textureDesc.ArraySize = 1; textureDesc.Format = DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; textureDesc.SampleDesc.Count = 1; textureDesc.Usage = D3D11_USAGE.D3D11_USAGE_IMMUTABLE; textureDesc.BindFlags = (uint)D3D11_BIND_FLAG.D3D11_BIND_SHADER_RESOURCE; gc = GCHandle.Alloc(Data.TextureData, GCHandleType.Pinned); var textureData = new D3D11_SUBRESOURCE_DATA(); textureData.pSysMem = gc.AddrOfPinnedObject(); textureData.SysMemPitch = 20 * 4; // 4 bytes per pixel gc.Free(); var texture = d3D11Device.CreateTexture2D <ID3D11Texture2D>(textureDesc, textureData); _shaderResourceView = d3D11Device.CreateShaderResourceView(texture); }
static bool UpdateOuput(IntPtr opaque, RenderConfig *config, ref OutputConfig output) { ReleaseTextures(); var renderFormat = DXGI_FORMAT_R8G8B8A8_UNORM; var texDesc = new D3D11_TEXTURE2D_DESC { MipLevels = 1, SampleDesc = new DXGI_SAMPLE_DESC { Count = 1 }, BindFlags = (uint)(D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE), Usage = D3D11_USAGE_DEFAULT, CPUAccessFlags = 0, ArraySize = 1, Format = renderFormat, Height = config->Height, Width = config->Width, MiscFlags = (uint)(D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_NTHANDLE) }; fixed(ID3D11Texture2D **texture = &_texture) ThrowIfFailed(_d3dDevice->CreateTexture2D(&texDesc, null, texture)); IDXGIResource1 *sharedResource = null; var iid = IID_IDXGIResource1; _texture->QueryInterface(&iid, (void **)&sharedResource); fixed(void *handle = &_sharedHandle) ThrowIfFailed(sharedResource->CreateSharedHandle(null, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, null, (IntPtr *)handle)); sharedResource->Release(); ID3D11Device1 *d3d11VLC1; iid = IID_ID3D11Device1; _d3deviceVLC->QueryInterface(&iid, (void **)&d3d11VLC1); iid = IID_ID3D11Texture2D; fixed(ID3D11Texture2D **texture = &_textureVLC) ThrowIfFailed(d3d11VLC1->OpenSharedResource1(_sharedHandle, &iid, (void **)texture)); d3d11VLC1->Release(); var shaderResourceViewDesc = new D3D11_SHADER_RESOURCE_VIEW_DESC { ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D, Format = texDesc.Format }; shaderResourceViewDesc.Texture2D.MipLevels = 1; ID3D11Resource *res; iid = IID_ID3D11Resource; _texture->QueryInterface(&iid, (void **)&res); fixed(ID3D11ShaderResourceView **tsi = &_textureShaderInput) { ThrowIfFailed(_d3dDevice->CreateShaderResourceView(res, &shaderResourceViewDesc, tsi)); res->Release(); _d3dctx->PSSetShaderResources(0, 1, tsi); } var renderTargetViewDesc = new D3D11_RENDER_TARGET_VIEW_DESC { Format = texDesc.Format, ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D }; iid = IID_ID3D11Resource; _textureVLC->QueryInterface(&iid, (void **)&res); fixed(ID3D11RenderTargetView **trt = &_textureRenderTarget) { ThrowIfFailed(_d3deviceVLC->CreateRenderTargetView(res, &renderTargetViewDesc, trt)); res->Release(); _d3dctxVLC->OMSetRenderTargets(1, trt, null); } output.Union.DxgiFormat = (int)renderFormat; output.FullRange = true; output.ColorSpace = ColorSpace.BT709; output.ColorPrimaries = ColorPrimaries.BT709; output.TransferFunction = TransferFunction.SRGB; return(true); }
/// <summary> /// 从文件加载贴图数据 /// </summary> /// <param name="subDatas"></param> /// <param name="desc"></param> /// <param name="section"></param> /// <param name="path"></param> public static void LoadTextureDataFromFile(D3D11_SUBRESOURCE_DATA[] subDatas, D3D11_TEXTURE2D_DESC desc, Section section, string path) { FREE_IMAGE_FORMAT fiFormat = default; string ext = Path.GetExtension(path).ToLower(); if (ext == ".bmp") { fiFormat = FREE_IMAGE_FORMAT.FIF_BMP; } else if (ext == ".tga") { fiFormat = FREE_IMAGE_FORMAT.FIF_TARGA; } else { Console.WriteLine($"unsupported format {ext}"); return; } FIBITMAP bmp = FreeImage.Load(fiFormat, path, FREE_IMAGE_LOAD_FLAGS.DEFAULT); if (bmp == null || bmp.IsNull) { Console.WriteLine($"加载图片文件失败 {path}"); return; } try { DXGI_FORMAT format = desc.Format; if (Common.IsBlockFormat(format)) // 暂时不支持压缩格式 { return; } uint fiBpp = FreeImage.GetBPP(bmp) / 8; uint width = FreeImage.GetWidth(bmp); uint height = FreeImage.GetHeight(bmp); if (width != desc.Width || height != desc.Height) { Console.WriteLine($"size unmatch of file {path}, should be {desc.Width}*{desc.Height}"); return; } if (format == DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_SNORM || format == DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_TYPELESS || format == DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) // 4通道保存成tga以方便编辑A通道 { Debug.Assert(subDatas[0].sysMemLength >= desc.Width * desc.Height); fixed(void *p = §ion.uncompressedData[subDatas[0].sysMemDataOffset]) { byte *rawData = (byte *)p; for (int h = (int)(desc.Height - 1); h >= 0; h--) // bitmap 存储方向与 dx 相反 { byte *scanLine = (byte *)FreeImage.GetScanLine(bmp, h); for (int w = 0; w < desc.Width; w++) { rawData[w * 4] = *scanLine++; rawData[w * 4 + 1] = *scanLine++; rawData[w * 4 + 2] = *scanLine++; rawData[w * 4 + 3] = *scanLine++; } rawData += subDatas[0].SysMemPitch; } } } else if (format == DXGI_FORMAT.DXGI_FORMAT_R8_SNORM || format == DXGI_FORMAT.DXGI_FORMAT_R8_TYPELESS || format == DXGI_FORMAT.DXGI_FORMAT_R8_UNORM || format == DXGI_FORMAT.DXGI_FORMAT_A8_UNORM) // 经过测试单通道无论指定哪个通道数据都只存了一个通道, 单通道保存成png24 { Debug.Assert(subDatas[0].sysMemLength >= desc.Width * desc.Height); fixed(void *p = §ion.uncompressedData[subDatas[0].sysMemDataOffset]) { byte *rawData = (byte *)p; for (int h = (int)(desc.Height - 1); h >= 0; h--) // bitmap 存储方向与 dx 相反 { byte *scanLine = (byte *)FreeImage.GetScanLine(bmp, h); for (int w = 0; w < desc.Width; w++) { rawData[w] = *scanLine; scanLine += fiBpp; } rawData += subDatas[0].SysMemPitch; } } } } finally { FreeImage.Unload(bmp); } }
/// <summary> /// 保存贴图到文件,适用于 Chunk_CreateTexture2D 及 Chunk_CreateSwapBuffer /// </summary> /// <param name="subDatas"></param> /// <param name="desc"></param> /// <param name="section"></param> public static void SaveTextureToFile(D3D11_SUBRESOURCE_DATA[] subDatas, D3D11_TEXTURE2D_DESC desc, Section section, string path) { DXGI_FORMAT format = desc.Format; if (Common.IsBlockFormat(format)) // 暂时不支持导出压缩格式 { return; } if (format == DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_SNORM || format == DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_TYPELESS || format == DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) // 4通道保存成tga以方便编辑A通道 { FIBITMAP bmp = FreeImage.AllocateT(FREE_IMAGE_TYPE.FIT_BITMAP, (int)desc.Width, (int)desc.Height, 32); Debug.Assert(subDatas[0].sysMemLength >= desc.Width * desc.Height * 4); // sysMemLength 是对齐的,因此可能大于真实数据大小 fixed(void *p = §ion.uncompressedData[subDatas[0].sysMemDataOffset]) { byte *rawData = (byte *)p; for (int h = (int)(desc.Height - 1); h >= 0; h--) // bitmap 存储方向与 dx 相反 { byte *scanLine = (byte *)FreeImage.GetScanLine(bmp, h); for (int w = 0; w < desc.Width; w++) { *scanLine++ = rawData[w * 4]; *scanLine++ = rawData[w * 4 + 1]; *scanLine++ = rawData[w * 4 + 2]; *scanLine++ = rawData[w * 4 + 3]; } rawData += subDatas[0].SysMemPitch; } } path = $"{path}.tga"; File.Delete(path); FreeImage.Save(FREE_IMAGE_FORMAT.FIF_TARGA, bmp, path, FREE_IMAGE_SAVE_FLAGS.DEFAULT); FreeImage.Unload(bmp); } else if (format == DXGI_FORMAT.DXGI_FORMAT_R8_SNORM || format == DXGI_FORMAT.DXGI_FORMAT_R8_TYPELESS || format == DXGI_FORMAT.DXGI_FORMAT_R8_UNORM || format == DXGI_FORMAT.DXGI_FORMAT_A8_UNORM) // 经过测试单通道无论指定哪个通道数据都只存了一个通道, 单通道保存成png24 { FIBITMAP bmp = FreeImage.AllocateT(FREE_IMAGE_TYPE.FIT_BITMAP, (int)desc.Width, (int)desc.Height, 24); Debug.Assert(subDatas[0].sysMemLength >= desc.Width * desc.Height); fixed(void *p = §ion.uncompressedData[subDatas[0].sysMemDataOffset]) { byte *rawData = (byte *)p; for (int h = (int)(desc.Height - 1); h >= 0; h--) // bitmap 存储方向与 dx 相反 { byte *scanLine = (byte *)FreeImage.GetScanLine(bmp, h); for (int w = 0; w < desc.Width; w++) { byte val = rawData[w]; * scanLine++ = val; * scanLine++ = val; * scanLine++ = val; } rawData += subDatas[0].SysMemPitch; } } path = $"{path}.bmp"; File.Delete(path); FreeImage.Save(FREE_IMAGE_FORMAT.FIF_BMP, bmp, path, FREE_IMAGE_SAVE_FLAGS.BMP_SAVE_RLE); FreeImage.Unload(bmp); } }