//---------------------------------------------------------------------------------------------------------------------------------- void RosUmdAdapter::Open( D3D10DDIARG_OPENADAPTER* pArgs ) { m_hRTAdapter = pArgs->hRTAdapter; m_Interface = pArgs->Interface; m_Version = pArgs->Version; m_pMSCallbacks = pArgs->pAdapterCallbacks; D3DDDICB_QUERYADAPTERINFO queryAdapterInfo = { 0 }; HRESULT hr; queryAdapterInfo.pPrivateDriverData = &m_rosAdapterInfo; queryAdapterInfo.PrivateDriverDataSize = sizeof(m_rosAdapterInfo); hr = m_pMSCallbacks->pfnQueryAdapterInfoCb( m_hRTAdapter.handle, &queryAdapterInfo); if (FAILED(hr)) { throw RosUmdException(hr); } const D3D10_2DDI_ADAPTERFUNCS AdapterFuncs = { CalcPrivateDeviceSize, CreateDevice, CloseAdapter, GetSupportedVersions, GetCaps, }; *pArgs->pAdapterFuncs_2 = AdapterFuncs; pArgs->hAdapter = CastTo(); }
_Use_decl_annotations_ void RosUmdResource::CopyTFormatToLinear ( const void* Source, UINT SourceWidthTiles, // width in 4k tiles UINT SourceHeightTiles, // height in 4k tiles void* Dest, UINT DestPitch, UINT DestHeight ) { if (DestPitch % VC4_MICRO_TILE_WIDTH_BYTES) { ROS_LOG_ERROR( "Destination pitch is not aligned to microtile width. " "(DestPitch = %d, VC4_MICRO_TILE_WIDTH_BYTES = %d)", DestPitch, VC4_MICRO_TILE_WIDTH_BYTES); throw RosUmdException(E_INVALIDARG); } const BYTE* const destEnd = static_cast<BYTE*>(Dest) + (DestPitch * DestHeight); const BYTE* const srcEnd = static_cast<const BYTE*>(Source) + (SourceWidthTiles * SourceHeightTiles * VC4_4KB_TILE_SIZE_BYTES); // build destination image in scanline order for (UINT y = 0; y < DestHeight; ++y) { const UINT offsetWithinMicrotile = (y % VC4_MICRO_TILE_HEIGHT) * VC4_MICRO_TILE_WIDTH_BYTES; // destRow points to beginning of row y BYTE* const destRow = static_cast<BYTE*>(Dest) + y * DestPitch; for (UINT x = 0; x < DestPitch; x += VC4_MICRO_TILE_WIDTH_BYTES) { TileCoord tileCoord( x / VC4_MICRO_TILE_WIDTH_BYTES, y / VC4_MICRO_TILE_HEIGHT, SourceWidthTiles); // Compute the start of the line within the micro tile const BYTE* src = static_cast<const BYTE*>(Source) + tileCoord.ByteOffset() + offsetWithinMicrotile; NT_ASSERT((src + VC4_MICRO_TILE_WIDTH_BYTES) <= srcEnd); UNREFERENCED_PARAMETER(srcEnd); BYTE* dest = destRow + x; NT_ASSERT((dest + VC4_MICRO_TILE_WIDTH_BYTES) <= destEnd); UNREFERENCED_PARAMETER(destEnd); memcpy(dest, src, VC4_MICRO_TILE_WIDTH_BYTES); } } }
void RosUmdResource::CalculateMemoryLayout( void) { switch (m_resourceDimension) { case D3D10DDIRESOURCE_BUFFER: { m_hwLayout = RosHwLayout::Linear; // TODO(bhouse) Need mapping code from resource DXGI format to hw format m_hwWidthPixels = m_mip0Info.TexelWidth; m_hwHeightPixels = m_mip0Info.TexelHeight; m_hwSizeBytes = m_mip0Info.TexelWidth * CPixel::BytesPerPixel(m_format); NT_ASSERT(this->Pitch() == m_hwSizeBytes); } break; case D3D10DDIRESOURCE_TEXTURE2D: { // get layout and alignment requirement from binding and format const auto reqs = Get2dTextureLayoutRequirements(m_bindFlags, m_format); const UINT unalignedPitch = m_mip0Info.TexelWidth * CPixel::BytesPerPixel(m_format); const UINT alignedPitch = AlignValue(unalignedPitch, reqs.PitchAlign); const UINT unalignedHeight = m_mip0Info.TexelHeight; const UINT alignedHeight = AlignValue(unalignedHeight, reqs.HeightAlign); m_hwLayout = reqs.Layout; m_hwWidthPixels = alignedPitch / CPixel::BytesPerPixel(m_format); m_hwHeightPixels = alignedHeight; m_hwSizeBytes = alignedPitch * alignedHeight; } break; case D3D10DDIRESOURCE_TEXTURE1D: case D3D10DDIRESOURCE_TEXTURE3D: case D3D10DDIRESOURCE_TEXTURECUBE: default: throw RosUmdException(DXGI_DDI_ERR_UNSUPPORTED); } }
RosUmdResource::_LayoutRequirements RosUmdResource::Get2dTextureLayoutRequirements ( UINT BindFlags, DXGI_FORMAT Format ) { RosHwLayout hwLayout; UINT pitchAlign, heightAlign; switch (BindFlags) { case 0: // non-bindable resources (e.g. staging resources) must be pitch-aligned // to microtile width so that we can copy efficiently between T-format // and linear resources hwLayout = RosHwLayout::Linear; pitchAlign = VC4_MICRO_TILE_WIDTH_BYTES; heightAlign = 1; break; case D3D10_DDI_BIND_RENDER_TARGET: case D3D10_DDI_BIND_RENDER_TARGET | D3D10_DDI_BIND_SHADER_RESOURCE: // non-displayable render targets use T-Format, and must be aligned // to the binning tile size hwLayout = RosHwLayout::Tiled; pitchAlign = VC4_BINNING_TILE_PIXELS * CPixel::BytesPerPixel(Format); heightAlign = VC4_BINNING_TILE_PIXELS; break; //case D3D10_DDI_BIND_RENDER_TARGET: case D3D10_DDI_BIND_RENDER_TARGET | D3D10_DDI_BIND_PRESENT: case D3D10_DDI_BIND_RENDER_TARGET | D3D10_DDI_BIND_SHADER_RESOURCE | D3D10_DDI_BIND_PRESENT: // displayable render target uses linear (raster) format, and must be // aligned to binning tile size hwLayout = RosHwLayout::Linear; pitchAlign = VC4_BINNING_TILE_PIXELS * CPixel::BytesPerPixel(Format); heightAlign = VC4_BINNING_TILE_PIXELS; break; case D3D10_DDI_BIND_SHADER_RESOURCE: case D3D10_DDI_BIND_DEPTH_STENCIL: // bindable textures and depth stencils use T-Format and must be // aligned to the t-format tile size // XXX: Disable tiled format until issue #48 is fixed. hwLayout = RosHwLayout::Linear; // RosHwLayout::Tiled; pitchAlign = VC4_4KB_TILE_WIDTH_BYTES; heightAlign = VC4_4KB_TILE_HEIGHT; break; case D3D10_DDI_BIND_PRESENT: // display-only surfaces use linear format with no alignment requirement hwLayout = RosHwLayout::Linear; pitchAlign = CPixel::BytesPerPixel(Format); heightAlign = 1; break; case D3D10_DDI_BIND_VERTEX_BUFFER: case D3D10_DDI_BIND_INDEX_BUFFER: case D3D10_DDI_BIND_CONSTANT_BUFFER: ROS_LOG_ERROR( "Unsupported bind flag for 2D texture. (BindFlags = 0x%x)", BindFlags); throw RosUmdException(E_INVALIDARG); case D3D10_DDI_BIND_STREAM_OUTPUT: default: ROS_LOG_ERROR("Unsupported or invalid bind flags: 0x%x", BindFlags); throw RosUmdException(E_INVALIDARG); } return _LayoutRequirements{hwLayout, pitchAlign, heightAlign}; }
void RosUmdPipelineShader::Update() { // TODO: state dirtiness check. if (m_pCompiler) { return; } assert(m_pCode != NULL); const UINT *ShaderLinkage[2] = { NULL, NULL }; // Downstream, Upstream. switch (m_ProgramType) { case D3D10_SB_VERTEX_SHADER: assert(m_pDevice->m_pixelShader); ShaderLinkage[0] = m_pDevice->m_pixelShader->GetHLSLCode(); break; case D3D10_SB_PIXEL_SHADER: assert(m_pDevice->m_vertexShader); ShaderLinkage[1] = m_pDevice->m_vertexShader->GetHLSLCode(); break; default: assert(false); }; m_pCompiler = RosCompilerCreate(m_ProgramType, m_pCode, ShaderLinkage[0], // Downstream ShaderLinkage[1], // Upstream m_pDevice->m_blendState->GetDesc(), m_pDevice->m_depthStencilState->GetDesc(), m_pDevice->m_rasterizerState->GetDesc(), (const RosUmdRenderTargetView **)&m_pDevice->m_renderTargetViews[0], (const RosUmdShaderResourceView **)&m_pDevice->m_psResourceViews[0], m_numInputSignatureEntries, m_pInputSignatureEntries, m_numOutputSignatureEntries, m_pOutputSignatureEntries, 0, NULL); if (m_pCompiler == NULL) { throw RosUmdException(E_OUTOFMEMORY); } HRESULT hr; if (FAILED(hr = m_pCompiler->Compile())) { throw RosUmdException(hr); } { m_hwShaderCodeSize = m_pCompiler->GetShaderCodeSize(); assert(m_hwShaderCodeSize != 0); m_pDevice->CreateInternalBuffer( &m_hwShaderCode, ROUND_TO_PAGES(m_hwShaderCodeSize)); // TODO: for now, for easier debugging, round allocation size to PAGE size aligned. { D3D10DDI_MAPPED_SUBRESOURCE mappedSubRes = { 0 }; m_hwShaderCode.Map( m_pDevice, 0, D3D10_DDI_MAP_WRITE, 0, &mappedSubRes); if (mappedSubRes.pData) { m_pCompiler->GetShaderCode( mappedSubRes.pData, &m_vc4CoordinateShaderOffset); m_hwShaderCode.Unmap( m_pDevice, 0); return; } } } throw RosUmdException(E_FAIL); }
void RosUmdResource::CalculateMemoryLayout( void) { switch (m_resourceDimension) { case D3D10DDIRESOURCE_BUFFER: { m_hwLayout = RosHwLayout::Linear; // TODO(bhouse) Need mapping code from resource DXGI format to hw format m_hwFormat = RosHwFormat::X8; m_hwWidthPixels = m_mip0Info.TexelWidth; m_hwHeightPixels = m_mip0Info.TexelHeight; assert(m_hwFormat == RosHwFormat::X8); assert(m_hwHeightPixels == 1); m_hwSizeBytes = m_hwWidthPixels; } break; case D3D10DDIRESOURCE_TEXTURE2D: { if (m_usage == D3D10_DDI_USAGE_DEFAULT) { m_hwLayout = RosHwLayout::Tiled; } else { m_hwLayout = RosHwLayout::Linear; } // TODO(bhouse) Need mapping code from resource DXGI format to hw format m_hwFormat = RosHwFormat::X32; // Using system memory linear MipMap as example m_hwWidthPixels = m_mip0Info.TexelWidth; m_hwHeightPixels = m_mip0Info.TexelHeight; if (m_hwLayout == RosHwLayout::Linear) { m_hwSizeBytes = CPixel::ComputeMipMapSize( m_hwWidthPixels, m_hwHeightPixels, m_mipLevels, m_format); m_hwPitchBytes = CPixel::ComputeSurfaceStride( m_hwWidthPixels, CPixel::BytesPerPixel(m_format)); } else { assert(m_hwLayout == RosHwLayout::Tiled); assert(m_mipLevels == 1); m_hwWidthTilePixels = 64; m_hwHeightTilePixels = 64; m_hwWidthTiles = (m_hwWidthPixels + m_hwWidthTilePixels - 1) / m_hwWidthTilePixels; m_hwHeightTiles = (m_hwHeightPixels + m_hwHeightTilePixels - 1) / m_hwHeightTilePixels; assert(m_hwFormat == RosHwFormat::X32); UINT sizeTileBytes = 64 * 64 * 4; m_hwSizeBytes = m_hwWidthTiles * m_hwWidthTiles * sizeTileBytes; m_hwPitchBytes = 0; } } break; case D3D10DDIRESOURCE_TEXTURE1D: case D3D10DDIRESOURCE_TEXTURE3D: case D3D10DDIRESOURCE_TEXTURECUBE: { throw RosUmdException(DXGI_DDI_ERR_UNSUPPORTED); } break; } }
void RosUmdResource::CalculateMemoryLayout( void) { switch (m_resourceDimension) { case D3D10DDIRESOURCE_BUFFER: { m_hwLayout = RosHwLayout::Linear; // TODO(bhouse) Need mapping code from resource DXGI format to hw format m_hwFormat = RosHwFormat::X8; m_hwWidthPixels = m_mip0Info.TexelWidth; m_hwHeightPixels = m_mip0Info.TexelHeight; assert(m_hwFormat == RosHwFormat::X8); assert(m_hwHeightPixels == 1); m_hwSizeBytes = m_hwWidthPixels; } break; case D3D10DDIRESOURCE_TEXTURE2D: { if (m_usage == D3D10_DDI_USAGE_DEFAULT) { m_hwLayout = RosHwLayout::Tiled; } else { m_hwLayout = RosHwLayout::Linear; } #if VC4 // TODO[indyz]: Enable tiled render target if (m_bindFlags & D3D10_DDI_BIND_RENDER_TARGET) { m_hwLayout = RosHwLayout::Linear; } #endif // TODO(bhouse) Need mapping code from resource DXGI format to hw format if (m_bindFlags & D3D10_DDI_BIND_DEPTH_STENCIL) { m_hwFormat = RosHwFormat::D24S8; } else { m_hwFormat = RosHwFormat::X8888; } // Using system memory linear MipMap as example m_hwWidthPixels = m_mip0Info.TexelWidth; m_hwHeightPixels = m_mip0Info.TexelHeight; #if VC4 // Align width and height to VC4_BINNING_TILE_PIXELS for binning #endif m_hwWidthTilePixels = VC4_BINNING_TILE_PIXELS; m_hwHeightTilePixels = VC4_BINNING_TILE_PIXELS; m_hwWidthTiles = (m_hwWidthPixels + m_hwWidthTilePixels - 1) / m_hwWidthTilePixels; m_hwHeightTiles = (m_hwHeightPixels + m_hwHeightTilePixels - 1) / m_hwHeightTilePixels; m_hwWidthPixels = m_hwWidthTiles*m_hwWidthTilePixels; m_hwHeightPixels = m_hwHeightTiles*m_hwHeightTilePixels; if (m_hwLayout == RosHwLayout::Linear) { m_hwSizeBytes = CPixel::ComputeMipMapSize( m_hwWidthPixels, m_hwHeightPixels, m_mipLevels, m_format); m_hwPitchBytes = CPixel::ComputeSurfaceStride( m_hwWidthPixels, CPixel::BytesPerPixel(m_format)); } else { assert(m_hwLayout == RosHwLayout::Tiled); assert(m_mipLevels == 1); assert((m_hwFormat == RosHwFormat::X8888) || (m_hwFormat == RosHwFormat::D24S8)); UINT sizeTileBytes = 64 * 64 * 4; m_hwSizeBytes = m_hwWidthTiles * m_hwHeightTiles * sizeTileBytes; m_hwPitchBytes = 0; } } break; case D3D10DDIRESOURCE_TEXTURE1D: case D3D10DDIRESOURCE_TEXTURE3D: case D3D10DDIRESOURCE_TEXTURECUBE: { throw RosUmdException(DXGI_DDI_ERR_UNSUPPORTED); } break; } }