예제 #1
0
    IDXGISwapChain3Ptr createDxgiSwapChain(IDXGIFactory4* pFactory, const Window* pWindow, ID3D12CommandQueue* pCommandQueue, ResourceFormat colorFormat)
    {
        DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
        swapChainDesc.BufferCount = kSwapChainBuffers;
        swapChainDesc.Width = pWindow->getClientAreaWidth();
        swapChainDesc.Height = pWindow->getClientAreaHeight();
        // Flip mode doesn't support SRGB formats, so we strip them down when creating the resource. We will create the RTV as SRGB instead.
        // More details at the end of https://msdn.microsoft.com/en-us/library/windows/desktop/bb173064.aspx
        swapChainDesc.Format = getDxgiFormat(srgbToLinearFormat(colorFormat));
        swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
        swapChainDesc.SampleDesc.Count = 1;

        // CreateSwapChainForHwnd() doesn't accept IDXGISwapChain3 (Why MS? Why?)
        MAKE_SMART_COM_PTR(IDXGISwapChain1);
        IDXGISwapChain1Ptr pSwapChain;

        HRESULT hr = pFactory->CreateSwapChainForHwnd(pCommandQueue, pWindow->getApiHandle(), &swapChainDesc, nullptr, nullptr, &pSwapChain);
        if (FAILED(hr))
        {
            d3dTraceHR("Failed to create the swap-chain", hr);
            return false;
        }

        IDXGISwapChain3Ptr pSwapChain3;
        d3d_call(pSwapChain->QueryInterface(IID_PPV_ARGS(&pSwapChain3)));
        return pSwapChain3;
    }
예제 #2
0
	DXGI_FORMAT getDxgiDSVFormat(E_GI_FORMAT format)
	{
		if (format == EGF_D16)
			return DXGI_FORMAT_D16_UNORM;
		if (format == EGF_D24S8)
			return DXGI_FORMAT_D24_UNORM_S8_UINT;
		if (format == EGF_D32)
			return DXGI_FORMAT_D32_FLOAT;

		return getDxgiFormat(format);
	}
예제 #3
0
	DXGI_FORMAT getDxgiSRVFormat(E_GI_FORMAT format)
	{
		if (format == EGF_D16)
			return DXGI_FORMAT_R16_FLOAT;
		if (format == EGF_D24S8)
			return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
		if (format == EGF_D32)
			return DXGI_FORMAT_R32_FLOAT;

		return getDxgiFormat(format);
	}
예제 #4
0
	CD3D11InputLayout::CD3D11InputLayout(u32 sortCode,
		ID3D11Device* pd3dDevice,
		ID3D11DeviceContext* pd3dDeviceContext,
		ID3D10Blob* vertexShaderBuffer,
		const std::vector<SInputLayoutElement>& elements, u32 hashcode)
		:IInputLayout(sortCode, elements, hashcode)
		, md3dDeviceContext(pd3dDeviceContext)
		, m_pd3dInputLayout(nullptr)
	{
		HRESULT hr;
		u32 elementCount = elements.size();

		std::vector<D3D11_INPUT_ELEMENT_DESC> elementsDescs(elementCount);
		elementsDescs.resize(elementCount);

		for (u32 i = 0; i < elementCount; i++)
		{
			const SInputLayoutElement& element = elements[i];
			elementsDescs[i].SemanticName = element.SemanticName.c_str();
			elementsDescs[i].SemanticIndex = element.SemanticIndex;
			elementsDescs[i].Format = getDxgiFormat(element.Format);
			elementsDescs[i].InputSlot = element.Slot;
			elementsDescs[i].AlignedByteOffset = element.Offset;
			if (element.InstanceData)
			{
				elementsDescs[i].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
				elementsDescs[i].InstanceDataStepRate = element.InstanceDataStepRate;
			}
			else
			{
				elementsDescs[i].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
				elementsDescs[i].InstanceDataStepRate = 0;
			}
		}


		hr = pd3dDevice->CreateInputLayout(&elementsDescs[0], elementCount, vertexShaderBuffer->GetBufferPointer(),
				vertexShaderBuffer->GetBufferSize(), &m_pd3dInputLayout);

		if (FAILED(hr))
		{
			throw std::runtime_error("Create InputLayout Failed!");
		}
	}
예제 #5
0
	bool CD3D11Texture2D::create(u32 width, u32 height, u32 bindFlags,
		void* rawData, u32 miplevel, E_GI_FORMAT format, u32 pitch,
		E_MEMORY_USAGE memoryUsage)
	{
		HRESULT hr;
		ID3D11Texture2D* pd3dTexture = NULL;
		ID3D11ShaderResourceView* pd3dSRV = NULL;
		ID3D11UnorderedAccessView* pd3dUAV = NULL;
		CD3D11RenderTarget* pRenderTarget = nullptr;

		D3D11_TEXTURE2D_DESC texDesc;
		texDesc.Width = width;
		texDesc.Height = height;
		texDesc.MipLevels = miplevel;
		texDesc.ArraySize = 1;
		texDesc.Format = getDxgiFormat(format);
		texDesc.SampleDesc.Count = 1;
		texDesc.SampleDesc.Quality = 0;
		texDesc.BindFlags = getD3dx11BindFlags(bindFlags);
		texDesc.CPUAccessFlags = getD3dx11CpuAccessFlag(bindFlags);
		texDesc.MiscFlags = 0;
		texDesc.Usage = getD3d11Usage(memoryUsage);

		if (memoryUsage == EMU_UNKNOWN)
		{
			if ((bindFlags & ETBT_CPU_ACCESS_READ)) {
				texDesc.Usage = D3D11_USAGE_STAGING;
				memoryUsage = EMU_STAGING;
			}
			else if (bindFlags & ETBT_CPU_ACCESS_WRITE) {
				texDesc.Usage = D3D11_USAGE_DYNAMIC;
				memoryUsage = EMU_DEFAULT;
			}
			else if (rawData) {
				texDesc.Usage = D3D11_USAGE_IMMUTABLE;
				memoryUsage = EMU_STATIC;
			}
			else if (!rawData) {
				texDesc.Usage = D3D11_USAGE_DEFAULT;
				memoryUsage = EMU_DEFAULT;
			}
		}
		else
		{
			if (memoryUsage == EMU_DEFAULT || memoryUsage == EMU_STATIC)
			{
				if ((bindFlags & ETBT_CPU_ACCESS_READ) || (bindFlags & ETBT_CPU_ACCESS_WRITE))
				{
					GF_PRINT_CONSOLE_INFO("Static or Default Buffer cannot be accessed by CPU.\n");
					return false;
				}
			}
			else if (memoryUsage == EMU_DYNAMIC)
			{
				if (bindFlags & ETBT_CPU_ACCESS_READ)
				{
					GF_PRINT_CONSOLE_INFO("Dynamic Buffer cannot be read by CPU.\n");
					return false;
				}
			}
		}

		if (memoryUsage == D3D11_USAGE_STAGING)
		{
			if ((bindFlags & ETBT_SHADER_RESOURCE) || (bindFlags & ETBT_UNORDERED_ACCESS)){
				GF_PRINT_CONSOLE_INFO("Buffer with the memory usage 'STARING' cannot have SHADER_RESOURCE or UNORDERED_ACCESS.");
				return false;
			}
		}

		if (rawData)
		{
			D3D11_SUBRESOURCE_DATA texData;
			texData.pSysMem = rawData;
			if (pitch == 0)
				pitch = getFormatOffset(format) * width;

			texData.SysMemPitch = pitch;
			texData.SysMemSlicePitch = 0;
			hr = md3dDevice->CreateTexture2D(&texDesc, &texData, &pd3dTexture);
		}
		else
		{
			hr = md3dDevice->CreateTexture2D(&texDesc, NULL, &pd3dTexture);
		}
		

		if (FAILED(hr))
		{
			return false;
		}

		if (bindFlags & ETBT_SHADER_RESOURCE)
		{
			D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
			srvDesc.Format = texDesc.Format;
			srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
			srvDesc.Texture2D.MostDetailedMip = 0;
			srvDesc.Texture2D.MipLevels = -1;

			hr = md3dDevice->CreateShaderResourceView(pd3dTexture, &srvDesc, &pd3dSRV);
			if (FAILED(hr))
			{
				ReleaseCOM(pd3dTexture);
				return false;
			}
		}

		if (bindFlags & ETBT_UNORDERED_ACCESS)
		{
			D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
			uavDesc.Format = texDesc.Format;
			uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
			uavDesc.Texture2D.MipSlice = 0;

			hr = md3dDevice->CreateUnorderedAccessView(pd3dTexture, &uavDesc, &pd3dUAV);
			if (FAILED(hr))
			{
				ReleaseCOM(pd3dTexture);
				return false;
			}
		}


		if (bindFlags & ETBT_RENDER_TARGET)
		{
			pRenderTarget = new CD3D11RenderTarget(md3dDevice, md3dDeviceContext);
			if (!pRenderTarget->create(this, pd3dTexture, pd3dSRV, width, height, format))
			{
				ReleaseReferenceCounted(pRenderTarget);
				ReleaseCOM(pd3dSRV);
				ReleaseCOM(pd3dTexture);
				return false;
			}
		}

		ReleaseReferenceCounted(mRenderTarget);
		ReleaseReferenceCounted(mDepthStencilSurface);
		ReleaseCOM(md3dSRV);
		ReleaseCOM(md3dUAV);
		ReleaseCOM(md3dTexture);
		
		md3dTexture = pd3dTexture;
		md3dSRV = pd3dSRV;
		md3dUAV = pd3dUAV;
		mRenderTarget = pRenderTarget;

		mTextureWidth = width;
		mTextureHeight = height;
		mFormat = format;

		return true;
	}
예제 #6
0
	bool CD3D11Texture3D::create(u32 width, u32 height,
		u32 depth, u32 bindFlags, void* rawData,
		u32 miplevel, E_GI_FORMAT format, u32 pitch /*= 0*/, 
		u32 slicePitch /*= 0*/, E_MEMORY_USAGE memoryUsage)
	{
		HRESULT hr;
		ID3D11Texture3D* pd3dTexture3D = NULL;
		ID3D11ShaderResourceView* pd3dSRV = NULL;
		ID3D11UnorderedAccessView* pd3dUAV = NULL;

		D3D11_TEXTURE3D_DESC texDesc;
		texDesc.Width = width;
		texDesc.Height = height;
		texDesc.Depth = depth;
		texDesc.MipLevels = miplevel;
		texDesc.Format = getDxgiFormat(format);
		texDesc.Usage = D3D11_USAGE_IMMUTABLE;
		texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
		texDesc.CPUAccessFlags = 0;
		texDesc.MiscFlags = 0;
		texDesc.Usage = getD3d11Usage(memoryUsage);

		if (pitch == 0)
			pitch = getFormatOffset(format) * width;

		if (slicePitch == 0)
			slicePitch = getFormatOffset(format) * width * height;

		if (rawData)
		{
			if (memoryUsage == EMU_UNKNOWN)
				texDesc.Usage = D3D11_USAGE_IMMUTABLE;

			D3D11_SUBRESOURCE_DATA texData;
			texData.pSysMem = rawData;
			texData.SysMemPitch = pitch;
			texData.SysMemSlicePitch = slicePitch;

			hr = md3dDevice->CreateTexture3D(&texDesc, &texData, &pd3dTexture3D);
		}
		else
		{
			if (memoryUsage == EMU_UNKNOWN)
				texDesc.Usage = D3D11_USAGE_DEFAULT;

			md3dDevice->CreateTexture3D(&texDesc, NULL, &pd3dTexture3D);

		}

		if (FAILED(hr))
		{
			return false;
		}

		if (bindFlags & ETBT_SHADER_RESOURCE)
		{
			D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
			srvDesc.Format = texDesc.Format;
			srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
			srvDesc.Texture3D.MostDetailedMip = 0;
			srvDesc.Texture3D.MipLevels = texDesc.MipLevels;

			hr = md3dDevice->CreateShaderResourceView(pd3dTexture3D, &srvDesc, &pd3dSRV);
			if (FAILED(hr))
			{
				ReleaseCOM(pd3dTexture3D);
				return false;
			}
		}

		if (bindFlags & ETBT_UNORDERED_ACCESS)
		{
			D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
			uavDesc.Format = texDesc.Format;
			uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;

			uavDesc.Texture3D.MipSlice = 0;
			uavDesc.Texture3D.FirstWSlice = 0;
			uavDesc.Texture3D.WSize = texDesc.Depth;

			hr = md3dDevice->CreateUnorderedAccessView(pd3dTexture3D, &uavDesc, &pd3dUAV);
			if (FAILED(hr))
			{
				ReleaseCOM(pd3dTexture3D);
				return false;
			}
		}

		ReleaseCOM(md3dShaderResourceView);
		ReleaseCOM(md3dUAV);
		ReleaseCOM(md3dTexture);		

		md3dTexture = pd3dTexture3D;
		md3dShaderResourceView = pd3dSRV;
		md3dUAV = pd3dUAV;

		mTextureWidth = width;
		mTextureHeight = height;
		mTextureDepth = depth;
		mFormat = format;

		return true;
	}
예제 #7
0
	bool CD3D11Texture2DArray::create(u32 width, u32 height, u32 arraySize, u32 bindFlags, 
		void* rawData, u32 miplevel, E_GI_FORMAT format, u32 pitch /*= 0*/,
		E_MEMORY_USAGE memoryUsage)
	{
		HRESULT hr;
		ID3D11Texture2D* pd3dTexture = NULL;
		ID3D11ShaderResourceView* pd3dSRV = NULL;
		ID3D11UnorderedAccessView* pd3dUAV = NULL;
		CD3D11RenderTarget* pRenderTarget = nullptr;
		std::vector<CD3D11RenderTarget*> renderTargets;
		std::vector<CD3D11DepthStencilSurface*> depthStencilSurfaces;

		D3D11_TEXTURE2D_DESC texDesc;
		texDesc.Width = width;
		texDesc.Height = height;
		texDesc.MipLevels = miplevel;
		texDesc.ArraySize = arraySize;
		texDesc.Format = getDxgiFormat(format);
		texDesc.SampleDesc.Count = 1;
		texDesc.SampleDesc.Quality = 0;
		texDesc.BindFlags = getD3dx11BindFlags(bindFlags);
		texDesc.CPUAccessFlags = 0;
		texDesc.MiscFlags = 0;
		texDesc.Usage = getD3d11Usage(memoryUsage);

		if (rawData)
		{
			if (memoryUsage == EMU_UNKNOWN)
				texDesc.Usage = D3D11_USAGE_IMMUTABLE;

			D3D11_SUBRESOURCE_DATA texData;
			texData.pSysMem = rawData;
			if (pitch == 0)
				pitch = getFormatOffset(format) * width;

			texData.SysMemPitch = pitch;
			texData.SysMemSlicePitch = 0;
			hr = md3dDevice->CreateTexture2D(&texDesc, &texData, &pd3dTexture);
		}
		else
		{
			if (memoryUsage == EMU_UNKNOWN)
				texDesc.Usage = D3D11_USAGE_DEFAULT;
			hr = md3dDevice->CreateTexture2D(&texDesc, NULL, &pd3dTexture);
		}


		if (FAILED(hr))
			return false;

		if (bindFlags & ETBT_SHADER_RESOURCE)
		{
			D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
			srvDesc.Format = getDxgiSRVFormat(format);
			srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
			srvDesc.Texture2DArray.MostDetailedMip = 0;
			srvDesc.Texture2DArray.MipLevels = miplevel;
			srvDesc.Texture2DArray.FirstArraySlice = 0;
			srvDesc.Texture2DArray.ArraySize = arraySize;

			hr = md3dDevice->CreateShaderResourceView(pd3dTexture, &srvDesc, &pd3dSRV);
			if (FAILED(hr))
			{
				ReleaseCOM(pd3dTexture);
				return false;
			}
		}

		if (bindFlags & ETBT_UNORDERED_ACCESS)
		{
			D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
			uavDesc.Format = texDesc.Format;
			uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
			uavDesc.Texture2DArray.MipSlice = 0;
			uavDesc.Texture2DArray.ArraySize = arraySize;
			uavDesc.Texture2DArray.FirstArraySlice = 0;

			hr = md3dDevice->CreateUnorderedAccessView(pd3dTexture, &uavDesc, &pd3dUAV);
			if (FAILED(hr))
			{
				ReleaseCOM(pd3dTexture);
				return false;
			}
		}

		
		if (bindFlags & ETBT_RENDER_TARGET)
		{
			for (u32 i = 0; i < arraySize; i++)
			{
				CD3D11RenderTarget* pRenderTarget = new CD3D11RenderTarget(md3dDevice, md3dDeviceContext);
				renderTargets.push_back(pRenderTarget);
				if (!pRenderTarget->createOneInArray(this, pd3dTexture, pd3dSRV, i, width, height, format))
				{
					clearRenderTargets(renderTargets);
					ReleaseCOM(pd3dSRV);
					ReleaseCOM(pd3dTexture);
					return false;
				}
			}
		}

		if (bindFlags & ETBT_DEPTH_STENCIL)
		{
			for (u32 i = 0; i < arraySize; i++)
			{
				CD3D11DepthStencilSurface* pDS = new CD3D11DepthStencilSurface(md3dDevice, md3dDeviceContext);
				depthStencilSurfaces.push_back(pDS);
				if (!pDS->createOneInArray(this, pd3dTexture, pd3dSRV, i, width, height, format))
				{
					clearDepthStencilSurfaces(depthStencilSurfaces);
					clearRenderTargets(renderTargets);
					ReleaseCOM(pd3dSRV);
					ReleaseCOM(pd3dTexture);
					return false;
				}
			}
		}

		clearRenderTargets(mRenderTargets);
		clearDepthStencilSurfaces(mDepthStencilSurfaces);
		ReleaseCOM(md3dSRV);
		ReleaseCOM(md3dUAV);
		ReleaseCOM(md3dTexture);

		md3dTexture = pd3dTexture;
		md3dSRV = pd3dSRV;
		md3dUAV = pd3dUAV;
		mRenderTargets = renderTargets;
		mDepthStencilSurfaces = depthStencilSurfaces;

		mTextureWidth = width;
		mTextureHeight = height;
		mFormat = format;

		return true;
	}