Result GraphicsInterfaceD3D11::createTexture2D(void **dst_tex, int width, int height, TextureFormat format, const void *data, ResourceFlags flags)
{
    size_t texel_size = GetTexelSize(format);
    DXGI_FORMAT internal_format = GetDXGIFormat(format);

    D3D11_TEXTURE2D_DESC desc = {
        (UINT)width, (UINT)height, 1, 1, internal_format, { 1, 0 },
        D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0
    };
    if (flags & ResourceFlags::CPU_Write) {
        desc.Usage = D3D11_USAGE_DYNAMIC;
        desc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE;
    }
    if (flags & ResourceFlags::CPU_Read) {
        desc.Usage = D3D11_USAGE_STAGING;
        desc.CPUAccessFlags |= D3D11_CPU_ACCESS_READ;
        desc.BindFlags = 0;
    }

    D3D11_SUBRESOURCE_DATA subr = {
        data,
        width * (UINT)texel_size,
        width * height * (UINT)texel_size,
    };

    ID3D11Texture2D *ret = nullptr;
    HRESULT hr = m_device->CreateTexture2D(&desc, data ? &subr : nullptr, &ret);
    if (FAILED(hr))
    {
        return TranslateReturnCode(hr);
    }
    *dst_tex = ret;
    return Result::OK;
}
예제 #2
0
파일: dds.c 프로젝트: snake5/sgs-sdl
DDSRESULT dds_load_info( dds_info* out, size_t size, DDS_HEADER* hdr, DDS_HEADER_DXT10* hdr10 )
{
	static const dds_u32 sideflags[6] = { DDS_CUBEMAP_PX, DDS_CUBEMAP_NX, DDS_CUBEMAP_PY, DDS_CUBEMAP_NY, DDS_CUBEMAP_PZ, DDS_CUBEMAP_NZ };
	
	int i;
	dds_u32 sum, sum2;
	dds_image_info plane;
	
	out->image.width = hdr->width;
	out->image.height = hdr->height;
	out->image.depth = hdr->flags & DDSD_DEPTH ? hdr->depth : 1;
	out->image.format = dds_supported_format( GetDXGIFormat( hdr->ddspf ) );
	
	out->mipcount = hdr->flags & DDSD_MIPMAPCOUNT ? hdr->mipMapCount : 1;
	out->flags = 0;
	if( hdr->caps2 & DDSCAPS2_VOLUME ) out->flags |= DDS_VOLUME;
	if( hdr->caps2 & DDSCAPS2_CUBEMAP ) out->flags |= DDS_CUBEMAP;
	if( hdr->caps2 & DDSCAPS2_CUBEMAP_POSITIVEX ) out->flags |= DDS_CUBEMAP_PX;
	if( hdr->caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX ) out->flags |= DDS_CUBEMAP_NX;
	if( hdr->caps2 & DDSCAPS2_CUBEMAP_POSITIVEY ) out->flags |= DDS_CUBEMAP_PY;
	if( hdr->caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) out->flags |= DDS_CUBEMAP_NY;
	if( hdr->caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) out->flags |= DDS_CUBEMAP_PZ;
	if( hdr->caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ ) out->flags |= DDS_CUBEMAP_NZ;
	
	if( out->mipcount > 16 )
		return DDS_ENOTSUP;
	
	sum = 0;
	for( i = 0; i < out->mipcount; ++i )
	{
		out->mipoffsets[ i ] = sum;
		out->mip = i;
		dds_getinfo( out, &plane );
		sum += plane.size;
	}
	sum2 = 0;
	for( i = 0; i < 6; ++i )
	{
		out->sideoffsets[ i ] = sum2;
		if( out->flags & DDS_CUBEMAP && out->flags & sideflags[ i ] )
			sum2 += sum;
	}
	
	out->image.size = out->flags & DDS_CUBEMAP ? sum2 : sum;
	
	out->data = NULL;
	out->side = 0;
	out->mip = 0;
	
	printf( "loaded dds: w=%d h=%d d=%d fmt=%d mips=%d cube=%s size=%d\n", (int) out->image.width, (int) out->image.height,
		(int) out->image.depth, (int) out->image.format, (int) out->mipcount, out->flags & DDS_CUBEMAP ? "true" : "false", (int) out->image.size );
	
	return DDS_SUCCESS;
}
예제 #3
0
	void ProceduralTexture::Create(const void* data, uint32_t width, uint32_t height, Format format, uint32_t bpp)
	{
		Assert(!resource_ && data);
		width_ = width;
		height_ = height;
		depth_ = 1;
		format_ = format;

		DXGI_FORMAT dxgiFormat = GetDXGIFormat(format);

		// テクスチャ生成
		D3D11_TEXTURE2D_DESC objdesc;
		ZeroMemory(&objdesc, sizeof(objdesc));
		objdesc.Width = width;
		objdesc.Height = height;
		objdesc.MipLevels = 1;
		objdesc.ArraySize = 1;
		objdesc.SampleDesc.Count = 1;
		objdesc.SampleDesc.Quality = 0;
		objdesc.MiscFlags = 0;
		objdesc.Format = dxgiFormat;
		objdesc.Usage = D3D11_USAGE_DEFAULT;
		objdesc.CPUAccessFlags = 0;
		objdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;

		D3D11_SUBRESOURCE_DATA dataBin;
		dataBin.pSysMem = data;
		dataBin.SysMemPitch = bpp * width;
		dataBin.SysMemSlicePitch = 0;

		//	テクスチャ生成
		auto* device = GraphicsCore::GetDevice();
		ID3D11Texture2D* texture;
		THROW_IF_FAILED(device->CreateTexture2D(&objdesc, &dataBin, &texture));
		resource_ = texture;

		//	シェーダリソースビュー
		D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
		memset(&srvDesc, 0, sizeof(srvDesc));
		srvDesc.Format = dxgiFormat;
		srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		srvDesc.Texture2D.MipLevels = 1;
		THROW_IF_FAILED(device->CreateShaderResourceView(texture, &srvDesc, &srv_));
	}
예제 #4
0
/**
	If different input slot classes are needed, the caller of this function is responsible
	for that.
**/
void ShaderInfo::CreateInputLayout(D3D11_INPUT_ELEMENT_DESC* layout, UINT elementCount,
                                   bool perVertex /*= true */, UINT instanceDataStepRate /* = 0 */)
{
    for(UINT i = 0; i < elementCount; i++)
    {
        layout[i].SemanticName		= m_inputParams[i].SemanticName;
        layout[i].SemanticIndex		= m_inputParams[i].SemanticIndex;
        layout[i].Format			= GetDXGIFormat(m_inputParams[i]);
        layout[i].InputSlot			= 0;
        layout[i].InstanceDataStepRate = instanceDataStepRate;
        if(perVertex)
            layout[i].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
        else
            layout[i].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;;
        if(i == 0)
            layout[i].AlignedByteOffset = 0;
        else
            layout[i].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
    }
}
ComPtr<ID3D11Texture2D> GraphicsInterfaceD3D11::createStagingTexture(int width, int height, TextureFormat format, StagingFlag flag)
{
    D3D11_TEXTURE2D_DESC desc = {};
    desc.Width = (UINT)width;
    desc.Height = (UINT)height;
    desc.MipLevels = 1;
    desc.ArraySize = 1;
    desc.Format = GetDXGIFormat(format);
    desc.SampleDesc = { 1, 0 };
    desc.Usage = D3D11_USAGE_STAGING;
    if (flag == StagingFlag::Upload) {
        desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    }
    if (flag == StagingFlag::Readback) {
        desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
    }

    auto ret = ComPtr<ID3D11Texture2D>();
    auto hr = m_device->CreateTexture2D(&desc, nullptr, &ret);
    return ret;
}
예제 #6
0
//--------------------------------------------------------------------------
VeBlobPtr ParseDDS(VeTexture::FileInfo& kOut,
	VeMemoryIStream& kIn) noexcept
{
	if (kIn.RemainingLength() < sizeof(DDS_HEADER)) return nullptr;
	DDS_HEADER* pkHeader = kIn.To<DDS_HEADER>();
	if (pkHeader->m_u32Size != sizeof(DDS_HEADER) ||
		pkHeader->m_kFormat.m_u32Size != sizeof(DDS_PIXELFORMAT)) return nullptr;

	DDS_HEADER_DXT10* pkHeader10 = nullptr;
	if ((pkHeader->m_kFormat.m_u32Flags & DDS_FOURCC)
		&& (VE_FOURCC('D', 'X', '1', '0') == pkHeader->m_kFormat.m_u32FourCC))
	{
		if (kIn.RemainingLength() < sizeof(DDS_HEADER_DXT10)) return nullptr;
		pkHeader10 = kIn.To<DDS_HEADER_DXT10>();
	}

	VeUInt32 u32Width = pkHeader->m_u32Width;
	VeUInt32 u32Height = pkHeader->m_u32Height;
	VeUInt32 u32Depth = pkHeader->m_u32Depth;
	
	VeRenderResource::Dimension eResDim = VeRenderResource::DIMENSION_UNKNOWN;
	VeUInt32 u32ArraySize = 1;
	VeRenderResource::Format eFormat = VeRenderResource::FORMAT_UNKNOWN;
	bool bIsCubeMap = false;

	VeUInt32 u32MipCount = pkHeader->m_u32MipMapCount ? pkHeader->m_u32MipMapCount : 1;
	
	if (pkHeader10)
	{
		u32ArraySize = pkHeader10->m_u32ArraySize;
		if (u32ArraySize == 0) return nullptr;
		switch (pkHeader10->m_eFormat)
		{
		case VeRenderResource::FORMAT_AI44:
		case VeRenderResource::FORMAT_IA44:
		case VeRenderResource::FORMAT_P8:
		case VeRenderResource::FORMAT_A8P8:
			return nullptr;
		default:
			if (VeRenderResource::BitsPerPixel(pkHeader10->m_eFormat) == 0)
			{
				return nullptr;
			}
		}
		eFormat = pkHeader10->m_eFormat;

		switch (pkHeader10->m_eResourceDimension)
		{
		case VeRenderResource::DIMENSION_TEXTURE1D:
			if ((pkHeader->m_u32Flags & DDS_HEIGHT) && u32Height != 1)
			{
				return nullptr;
			}
			u32Height = u32Depth = 1;
			break;

		case VeRenderResource::DIMENSION_TEXTURE2D:
			if (pkHeader10->m_u32MiscFlag & RESOURCE_MISC_TEXTURECUBE)
			{
				u32ArraySize *= 6;
				bIsCubeMap = true;
			}
			u32Depth = 1;
			break;

		case VeRenderResource::DIMENSION_TEXTURE3D:
			if (!(pkHeader->m_u32Flags & DDS_HEADER_FLAGS_VOLUME))
			{
				return nullptr;
			}

			if (u32ArraySize > 1)
			{
				return nullptr;
			}
			break;

		default:
			return nullptr;
		}

		eResDim = pkHeader10->m_eResourceDimension;
	}
	else
	{
		eFormat = GetDXGIFormat(pkHeader->m_kFormat);
		if (eFormat == VeRenderResource::FORMAT_UNKNOWN)
		{
			return nullptr;
		}
		if (pkHeader->m_u32Flags & DDS_HEADER_FLAGS_VOLUME)
		{
			eResDim = VeRenderResource::DIMENSION_TEXTURE3D;
		}
		else
		{
			if (pkHeader->m_u32Caps2 & DDS_CUBEMAP)
			{
				if ((pkHeader->m_u32Caps2 & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES)
				{
					return nullptr;
				}
				u32ArraySize = 6;
				bIsCubeMap = true;
			}
			u32Depth = 1;
			eResDim = VeRenderResource::DIMENSION_TEXTURE2D;
		}
		VE_ASSERT(VeRenderResource::BitsPerPixel(eFormat) != 0);
	}
	
	if (u32MipCount > REQ_MIP_LEVELS)
	{
		return nullptr;
	}

	switch (eResDim)
	{
	case VeRenderResource::DIMENSION_TEXTURE1D:
		if ((u32ArraySize > REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION) ||
			(u32Width > REQ_TEXTURE1D_U_DIMENSION))
		{
			return nullptr;
		}
		break;
	case VeRenderResource::DIMENSION_TEXTURE2D:
		if (bIsCubeMap)
		{
			if ((u32ArraySize > REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION) ||
				(u32Width > REQ_TEXTURECUBE_DIMENSION) ||
				(u32Height > REQ_TEXTURECUBE_DIMENSION))
			{
				return nullptr;
			}
		}
		else if ((u32ArraySize > REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION) ||
			(u32Width > REQ_TEXTURE2D_U_OR_V_DIMENSION) ||
			(u32Height > REQ_TEXTURE2D_U_OR_V_DIMENSION))
		{
			return nullptr;
		}
		break;
	case VeRenderResource::DIMENSION_TEXTURE3D:
		if ((u32ArraySize > 1) ||
			(u32Width > REQ_TEXTURE3D_U_V_OR_W_DIMENSION) ||
			(u32Height > REQ_TEXTURE3D_U_V_OR_W_DIMENSION) ||
			(u32Depth > REQ_TEXTURE3D_U_V_OR_W_DIMENSION))
		{
			return nullptr;
		}
		break;
	default:
		return nullptr;
	}

	if (u32Depth != 1 && u32ArraySize != 1) return nullptr;

	kOut.m_eDimension = eResDim;
	kOut.m_eFormat = eFormat;
	kOut.m_u32Width = u32Width;
	kOut.m_u32Height = u32Height;
	kOut.m_u16Depth = (VeUInt16)(u32Depth * u32ArraySize);
	kOut.m_u16MipLevels = (VeUInt16)u32MipCount;
	kOut.m_bIsCube = bIsCubeMap;
	VeSizeT stDataSize = kIn.RemainingLength();
	void* pvData = kIn.Skip(stDataSize);
	return VE_NEW VeBlob(pvData, stDataSize);
}
//--------------------------------------------------------------------------------------
static HRESULT CreateTextureFromDDS( ID3D10Device* pDev, DDS_HEADER* pHeader, BYTE* pBitData,
                                     UINT BitSize, ID3D10ShaderResourceView** ppSRV, bool bSRGB )
{
    HRESULT hr = S_OK;

    UINT iWidth = pHeader->dwWidth;
    UINT iHeight = pHeader->dwHeight;
    UINT iMipCount = pHeader->dwMipMapCount;
    if( 0 == iMipCount )
        iMipCount = 1;

    D3D10_TEXTURE2D_DESC desc;
    if ((  pHeader->ddspf.dwFlags & DDS_FOURCC )
        && (MAKEFOURCC( 'D', 'X', '1', '0' ) == pHeader->ddspf.dwFourCC ) )
    {
        DDS_HEADER_DXT10* d3d10ext = (DDS_HEADER_DXT10*)( (char*)pHeader + sizeof(DDS_HEADER) );
        desc.ArraySize = d3d10ext->arraySize;
        desc.Format = d3d10ext->dxgiFormat;

        // For now, we only support 2D textures
        if ( d3d10ext->resourceDimension != D3D10_RESOURCE_DIMENSION_TEXTURE2D )
            return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }
    else
    {
        desc.ArraySize = 1;
        desc.Format = GetDXGIFormat( pHeader->ddspf );

        if (pHeader->dwCubemapFlags != 0
            || (pHeader->dwHeaderFlags & DDS_HEADER_FLAGS_VOLUME) )
        {
            // For now only support 2D textures, not cubemaps or volumes
            return E_FAIL;
        }

        if( desc.Format == DXGI_FORMAT_UNKNOWN )
        {
            D3DFORMAT fmt = GetD3D9Format( pHeader->ddspf );

            // Swizzle some RGB to BGR common formats to be DXGI (1.0) supported
            switch( fmt )
            {
            case D3DFMT_X8R8G8B8:
            case D3DFMT_A8R8G8B8:
                {
                    desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    
                    for( UINT i = 0; i < BitSize; i += 4 )
                    {
                        BYTE a = pBitData[i];
                        pBitData[i] = pBitData[i + 2];
                        pBitData[i + 2] = a;
                    }
                }
                break;

            // Need more room to try to swizzle 24bpp or 4bpp formats

            default:
                return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
            }
        }
    }
    
    if ( bSRGB )
        desc.Format = MAKE_SRGB( desc.Format );

    // Create the texture
    desc.Width = iWidth;
    desc.Height = iHeight;
    desc.MipLevels = iMipCount;
    desc.SampleDesc.Count = 1;
    desc.SampleDesc.Quality = 0;
    desc.Usage = D3D10_USAGE_DEFAULT;
    desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
    desc.CPUAccessFlags = 0;
    desc.MiscFlags = 0;

    ID3D10Texture2D* pTex2D;
    D3D10_SUBRESOURCE_DATA* pInitData = new D3D10_SUBRESOURCE_DATA[iMipCount];
    if( !pInitData )
        return E_OUTOFMEMORY;

    UINT NumBytes = 0;
    UINT RowBytes = 0;
    UINT NumRows = 0;
    BYTE* pSrcBits = pBitData;
    for( UINT j = 0; j < desc.ArraySize; j++ )
    {
        for( UINT i = 0; i < iMipCount; i++ )
        {
            GetSurfaceInfo( iWidth, iHeight, desc.Format, &NumBytes, &RowBytes, &NumRows );
            pInitData[i].pSysMem = ( void* )pSrcBits;
            pInitData[i].SysMemPitch = RowBytes;
    
            pSrcBits += NumBytes;
            iWidth = iWidth >> 1;
            iHeight = iHeight >> 1;
            if( iWidth == 0 )
                iWidth = 1;
            if( iHeight == 0 )
                iHeight = 1;
        }
    }

    hr = pDev->CreateTexture2D( &desc, pInitData, &pTex2D );
    if( SUCCEEDED( hr ) && pTex2D )
    {
        D3D10_SHADER_RESOURCE_VIEW_DESC SRVDesc;
        ZeroMemory( &SRVDesc, sizeof( SRVDesc ) );
        SRVDesc.Format = desc.Format;
        SRVDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
        SRVDesc.Texture2D.MipLevels = desc.MipLevels;
        hr = pDev->CreateShaderResourceView( pTex2D, &SRVDesc, ppSRV );
        SAFE_RELEASE( pTex2D );
    }

    SAFE_DELETE( pInitData );

    return hr;
}
예제 #8
0
	void ColorBuffer::Create2D(Format format, uint32_t width, uint32_t height, uint32_t arraySize, uint32_t mips, bool unorderedAccess)
	{
		Assert(!resource_);
		mips = se::Max<uint32_t>(1, mips);
		width_ = width;
		height_ = height;
		depth_ = arraySize;
		format_ = format;

		DXGI_FORMAT dxgiFormat = GetDXGIFormat(format);

		// テクスチャ生成
		D3D11_TEXTURE2D_DESC objdesc;
		ZeroMemory(&objdesc, sizeof(objdesc));
		objdesc.Width = width;
		objdesc.Height = height;
		objdesc.MipLevels = mips;
		objdesc.ArraySize = arraySize;
		objdesc.SampleDesc.Count = 1;
		objdesc.SampleDesc.Quality = 0;
		objdesc.MiscFlags = 0;
		objdesc.Format = dxgiFormat;
		objdesc.Usage = D3D11_USAGE_DEFAULT;
		objdesc.CPUAccessFlags = 0;
		objdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
		if(unorderedAccess)
			objdesc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;

		//	テクスチャ生成
		auto* device = GraphicsCore::GetDevice();
		ID3D11Texture2D* texture;
		THROW_IF_FAILED(device->CreateTexture2D(&objdesc, nullptr, &texture));
		resource_ = texture;

		//	シェーダリソースビュー
		bool isArray = (arraySize > 1);
		D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
		memset(&srvDesc, 0, sizeof(srvDesc));
		srvDesc.Format = dxgiFormat;
		if (isArray) {
			srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
			srvDesc.Texture2DArray.ArraySize = arraySize;
			srvDesc.Texture2DArray.MipLevels = mips;
		}
		else {
			srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
			srvDesc.Texture2D.MipLevels = mips;
		}
		THROW_IF_FAILED(device->CreateShaderResourceView(texture, &srvDesc, &srv_));

		// レンダーターゲットビュー
		D3D11_RENDER_TARGET_VIEW_DESC rdesc;
		rdesc.Format = dxgiFormat;
		rdesc.ViewDimension = (arraySize > 1 || mips > 1) ? D3D11_RTV_DIMENSION_TEXTURE2DARRAY : D3D11_RTV_DIMENSION_TEXTURE2D;
		rdesc.Texture2DArray.ArraySize = 1;
		rdesc.Texture2DArray.MipSlice = 0;
		rdesc.Texture2DArray.FirstArraySlice = 0;
		THROW_IF_FAILED(device->CreateRenderTargetView(texture, &rdesc, &rtv_));

		// アンオーダードアクセスビューを生成
		if (unorderedAccess) {
			D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
			if (isArray) {
				uavDesc.Texture2DArray.ArraySize = arraySize;
				uavDesc.Texture2DArray.FirstArraySlice = 0;
				uavDesc.Texture2DArray.MipSlice = 0;
				uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
			} else {
				uavDesc.Texture2D.MipSlice = 0;
				uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
			}
			uavDesc.Format = dxgiFormat;
			THROW_IF_FAILED(GraphicsCore::GetDevice()->CreateUnorderedAccessView(resource_, &uavDesc, &uav_));
		}
	}