예제 #1
0
void InitUtils()
{
	util_vbuf = new UtilVertexBuffer(0x4000);

	float border[4] = { 0.f, 0.f, 0.f, 0.f };
	D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
	HRESULT hr = D3D::device->CreateSamplerState(&samDesc, &point_copy_sampler);
	if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
	else SetDebugObjectName((ID3D11DeviceChild*)point_copy_sampler, "point copy sampler state");

	samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
	hr = D3D::device->CreateSamplerState(&samDesc, &linear_copy_sampler);
	if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
	else SetDebugObjectName((ID3D11DeviceChild*)linear_copy_sampler, "linear copy sampler state");

	// cached data used to avoid unnecessarily reloading the vertex buffers
	memset(&tex_quad_data, 0, sizeof(tex_quad_data));
	memset(&tex_sub_quad_data, 0, sizeof(tex_sub_quad_data));
	memset(&draw_quad_data, 0, sizeof(draw_quad_data));
	memset(&clear_quad_data, 0, sizeof(clear_quad_data));

	// make sure to properly load the vertex data whenever the corresponding functions get called the first time
	stq_observer = stsq_observer = cq_observer = clearq_observer = true;
	util_vbuf->AddWrapObserver(&stq_observer);
	util_vbuf->AddWrapObserver(&stsq_observer);
	util_vbuf->AddWrapObserver(&cq_observer);
	util_vbuf->AddWrapObserver(&clearq_observer);

	font.Init();
}
예제 #2
0
void InitUtils()
{
	util_vbuf = new UtilVertexBuffer(0x4000);

	float border[4] = { 0.f, 0.f, 0.f, 0.f };
	D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
	HRESULT hr = D3D::device->CreateSamplerState(&samDesc, &point_copy_sampler);
	if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
	else SetDebugObjectName((ID3D11DeviceChild*)point_copy_sampler, "point copy sampler state");

	samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
	hr = D3D::device->CreateSamplerState(&samDesc, &linear_copy_sampler);
	if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
	else SetDebugObjectName((ID3D11DeviceChild*)linear_copy_sampler, "linear copy sampler state");

	// cached data used to avoid unnecessarily reloading the vertex buffers
	memset(&tex_quad_data, 0, sizeof(tex_quad_data));
	memset(&tex_sub_quad_data, 0, sizeof(tex_sub_quad_data));
	memset(&draw_quad_data, 0, sizeof(draw_quad_data));
	memset(&clear_quad_data, 0, sizeof(clear_quad_data));

	// make sure to properly load the vertex data whenever the corresponding functions get called the first time
	stq_observer = stsq_observer = cq_observer = clearq_observer = true;
	util_vbuf->AddWrapObserver(&stq_observer);
	util_vbuf->AddWrapObserver(&stsq_observer);
	util_vbuf->AddWrapObserver(&cq_observer);
	util_vbuf->AddWrapObserver(&clearq_observer);

	font.Init();
	
	// Create resources for encoder quads

	// Create vertex quad
	D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(ENCODER_QUAD_VERTS),
		D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_IMMUTABLE);
	D3D11_SUBRESOURCE_DATA srd = { ENCODER_QUAD_VERTS, 0, 0 };
	hr = D3D::device->CreateBuffer(&bd, &srd, &s_encoderQuad);
	CHECK(SUCCEEDED(hr), "create encoder quad buffer");

	// Create vertex shader
	D3DBlob* blob;
	D3D::CompileVertexShader(ENCODER_VS, sizeof(ENCODER_VS), &blob);
	s_encoderVShader = D3D::CreateVertexShaderFromByteCode(blob);
	CHECK(SUCCEEDED(hr), "create encoder vertex shader");

	// Create input layout
	hr = D3D::device->CreateInputLayout(ENCODER_QUAD_LAYOUT_DESC,
		sizeof(ENCODER_QUAD_LAYOUT_DESC) / sizeof(D3D11_INPUT_ELEMENT_DESC),
		blob->Data(), blob->Size(), &s_encoderQuadLayout);
	CHECK(SUCCEEDED(hr), "create encoder input layout");

	blob->Release();

	// Create vertex shader for encoder quads with texture coords
	s_encoderTexVShader = D3D::CompileAndCreateVertexShader(ENCODER_TEX_VS, sizeof(ENCODER_TEX_VS));
}
예제 #3
0
void Television::Init()
{
#ifdef USE_D3D11
	HRESULT hr;

	// Create YUYV texture for real XFB mode


	// Initialize the texture with YCbCr black
	//
	// Some games use narrower XFB widths (Nintendo titles are fond of 608),
	// so the sampler's BorderColor won't cover the right side
	// (see sampler state below)
	const unsigned int MAX_XFB_SIZE = 2 * (MAX_XFB_WIDTH)* MAX_XFB_HEIGHT;
	std::vector<u8> fill(MAX_XFB_SIZE);
	for (size_t i = 0; i < MAX_XFB_SIZE / sizeof(u32); ++i)
		reinterpret_cast<u32*>(fill.data())[i] = 0x80108010;
	D3D11_SUBRESOURCE_DATA srd = { fill.data(), 2 * (MAX_XFB_WIDTH), 0 };

	// This texture format is designed for YUYV data.
	D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC(
		DXGI_FORMAT_G8R8_G8B8_UNORM, MAX_XFB_WIDTH, MAX_XFB_HEIGHT, 1, 1);
	hr = D3D::device->CreateTexture2D(&t2dd, &srd, &m_yuyvTexture);
	CHECK(SUCCEEDED(hr), "create tv yuyv texture");
	D3D::SetDebugObjectName(m_yuyvTexture, "tv yuyv texture");

	// Create shader resource view for YUYV texture

	D3D11_SHADER_RESOURCE_VIEW_DESC srvd = CD3D11_SHADER_RESOURCE_VIEW_DESC(
		m_yuyvTexture, D3D11_SRV_DIMENSION_TEXTURE2D,
		DXGI_FORMAT_G8R8_G8B8_UNORM);
	hr = D3D::device->CreateShaderResourceView(m_yuyvTexture, &srvd, &m_yuyvTextureSRV);
	CHECK(SUCCEEDED(hr), "create tv yuyv texture srv");
	D3D::SetDebugObjectName(m_yuyvTextureSRV, "tv yuyv texture srv");

	// Create YUYV-decoding pixel shader

	m_pShader = D3D::CompileAndCreatePixelShader(YUYV_DECODER_PS);
	CHECK(m_pShader != nullptr, "compile and create yuyv decoder pixel shader");
	D3D::SetDebugObjectName(m_pShader, "yuyv decoder pixel shader");

	// Create sampler state and set border color
	//
	// The default sampler border color of { 0.f, 0.f, 0.f, 0.f }
	// creates a green border around the image - see issue 6483
	// (remember, the XFB is being interpreted as YUYV, and 0,0,0,0
	// is actually two green pixels in YUYV - black should be 16,128,16,128,
	// but we reverse the order to match DXGI_FORMAT_G8R8_G8B8_UNORM's ordering)
	float border[4] = { 128.0f / 255.0f, 16.0f / 255.0f, 128.0f / 255.0f, 16.0f / 255.0f };
	D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR,
		D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER,
		0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
	hr = D3D::device->CreateSamplerState(&samDesc, &m_sampler_state);
	CHECK(SUCCEEDED(hr), "create yuyv decoder sampler state");
	D3D::SetDebugObjectName(m_sampler_state, "yuyv decoder sampler state");

#endif
}
예제 #4
0
ID3D11SamplerState* StateCache::Get(SamplerState state)
{
  std::lock_guard<std::mutex> guard(m_lock);
  auto it = m_sampler.find(state.hex);
  if (it != m_sampler.end())
    return it->second;

  D3D11_SAMPLER_DESC sampdc = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT());
  if (state.mipmap_filter == SamplerState::Filter::Linear)
  {
    if (state.min_filter == SamplerState::Filter::Linear)
      sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
                          D3D11_FILTER_MIN_MAG_MIP_LINEAR :
                          D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
    else
      sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
                          D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR :
                          D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
  }
  else
  {
    if (state.min_filter == SamplerState::Filter::Linear)
      sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
                          D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT :
                          D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
    else
      sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
                          D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT :
                          D3D11_FILTER_MIN_MAG_MIP_POINT;
  }

  static constexpr std::array<D3D11_TEXTURE_ADDRESS_MODE, 3> address_modes = {
      {D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_WRAP, D3D11_TEXTURE_ADDRESS_MIRROR}};
  sampdc.AddressU = address_modes[static_cast<u32>(state.wrap_u.Value())];
  sampdc.AddressV = address_modes[static_cast<u32>(state.wrap_v.Value())];
  sampdc.MaxLOD = state.max_lod / 16.f;
  sampdc.MinLOD = state.min_lod / 16.f;
  sampdc.MipLODBias = (s32)state.lod_bias / 256.f;

  if (state.anisotropic_filtering)
  {
    sampdc.Filter = D3D11_FILTER_ANISOTROPIC;
    sampdc.MaxAnisotropy = 1u << g_ActiveConfig.iMaxAnisotropy;
  }

  ID3D11SamplerState* res = nullptr;
  HRESULT hr = D3D::device->CreateSamplerState(&sampdc, &res);
  if (FAILED(hr))
    PanicAlert("Fail %s %d\n", __FILE__, __LINE__);

  D3D::SetDebugObjectName(res, "sampler state used to emulate the GX pipeline");
  m_sampler.emplace(state.hex, res);
  return res;
}
예제 #5
0
void XFBEncoder::Init()
{
    HRESULT hr;

    // Create output texture

    // The pixel shader can generate one YUYV entry per pixel. One YUYV entry
    // is created for every two EFB pixels.
    D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC(
                                    DXGI_FORMAT_R8G8B8A8_UNORM, MAX_XFB_WIDTH/2, MAX_XFB_HEIGHT, 1, 1,
                                    D3D11_BIND_RENDER_TARGET);
    hr = D3D::device->CreateTexture2D(&t2dd, nullptr, &m_out);
    CHECK(SUCCEEDED(hr), "create xfb encoder output texture");
    D3D::SetDebugObjectName(m_out, "xfb encoder output texture");

    // Create output render target view

    D3D11_RENDER_TARGET_VIEW_DESC rtvd = CD3D11_RENDER_TARGET_VIEW_DESC(m_out,
                                         D3D11_RTV_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM);
    hr = D3D::device->CreateRenderTargetView(m_out, &rtvd, &m_outRTV);
    CHECK(SUCCEEDED(hr), "create xfb encoder output texture rtv");
    D3D::SetDebugObjectName(m_outRTV, "xfb encoder output rtv");

    // Create output staging buffer

    t2dd.Usage = D3D11_USAGE_STAGING;
    t2dd.BindFlags = 0;
    t2dd.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
    hr = D3D::device->CreateTexture2D(&t2dd, nullptr, &m_outStage);
    CHECK(SUCCEEDED(hr), "create xfb encoder output staging buffer");
    D3D::SetDebugObjectName(m_outStage, "xfb encoder output staging buffer");

    // Create constant buffer for uploading params to shaders

    D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(XFBEncodeParams),
                           D3D11_BIND_CONSTANT_BUFFER);
    hr = D3D::device->CreateBuffer(&bd, nullptr, &m_encodeParams);
    CHECK(SUCCEEDED(hr), "create xfb encode params buffer");
    D3D::SetDebugObjectName(m_encodeParams, "xfb encoder params buffer");

    // Create vertex quad

    bd = CD3D11_BUFFER_DESC(sizeof(QUAD_VERTS), D3D11_BIND_VERTEX_BUFFER,
                            D3D11_USAGE_IMMUTABLE);
    D3D11_SUBRESOURCE_DATA srd = { QUAD_VERTS, 0, 0 };

    hr = D3D::device->CreateBuffer(&bd, &srd, &m_quad);
    CHECK(SUCCEEDED(hr), "create xfb encode quad vertex buffer");
    D3D::SetDebugObjectName(m_quad, "xfb encoder quad vertex buffer");

    // Create vertex shader

    D3DBlob* bytecode = nullptr;
    if (!D3D::CompileVertexShader(XFB_ENCODE_VS, &bytecode))
    {
        ERROR_LOG(VIDEO, "XFB encode vertex shader failed to compile");
        return;
    }

    hr = D3D::device->CreateVertexShader(bytecode->Data(), bytecode->Size(), nullptr, &m_vShader);
    CHECK(SUCCEEDED(hr), "create xfb encode vertex shader");
    D3D::SetDebugObjectName(m_vShader, "xfb encoder vertex shader");

    // Create input layout for vertex quad using bytecode from vertex shader

    hr = D3D::device->CreateInputLayout(QUAD_LAYOUT_DESC,
                                        sizeof(QUAD_LAYOUT_DESC)/sizeof(D3D11_INPUT_ELEMENT_DESC),
                                        bytecode->Data(), bytecode->Size(), &m_quadLayout);
    CHECK(SUCCEEDED(hr), "create xfb encode quad vertex layout");
    D3D::SetDebugObjectName(m_quadLayout, "xfb encoder quad layout");

    bytecode->Release();

    // Create pixel shader

    m_pShader = D3D::CompileAndCreatePixelShader(XFB_ENCODE_PS);
    if (!m_pShader)
    {
        ERROR_LOG(VIDEO, "XFB encode pixel shader failed to compile");
        return;
    }
    D3D::SetDebugObjectName(m_pShader, "xfb encoder pixel shader");

    // Create blend state

    D3D11_BLEND_DESC bld = CD3D11_BLEND_DESC(CD3D11_DEFAULT());
    hr = D3D::device->CreateBlendState(&bld, &m_xfbEncodeBlendState);
    CHECK(SUCCEEDED(hr), "create xfb encode blend state");
    D3D::SetDebugObjectName(m_xfbEncodeBlendState, "xfb encoder blend state");

    // Create depth state

    D3D11_DEPTH_STENCIL_DESC dsd = CD3D11_DEPTH_STENCIL_DESC(CD3D11_DEFAULT());
    dsd.DepthEnable = FALSE;
    hr = D3D::device->CreateDepthStencilState(&dsd, &m_xfbEncodeDepthState);
    CHECK(SUCCEEDED(hr), "create xfb encode depth state");
    D3D::SetDebugObjectName(m_xfbEncodeDepthState, "xfb encoder depth state");

    // Create rasterizer state

    D3D11_RASTERIZER_DESC rd = CD3D11_RASTERIZER_DESC(CD3D11_DEFAULT());
    rd.CullMode = D3D11_CULL_NONE;
    rd.DepthClipEnable = FALSE;
    hr = D3D::device->CreateRasterizerState(&rd, &m_xfbEncodeRastState);
    CHECK(SUCCEEDED(hr), "create xfb encode rasterizer state");
    D3D::SetDebugObjectName(m_xfbEncodeRastState, "xfb encoder rast state");

    // Create EFB texture sampler

    D3D11_SAMPLER_DESC sd = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT());
    // FIXME: Should we really use point sampling here?
    sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
    hr = D3D::device->CreateSamplerState(&sd, &m_efbSampler);
    CHECK(SUCCEEDED(hr), "create xfb encode texture sampler");
    D3D::SetDebugObjectName(m_efbSampler, "xfb encoder texture sampler");
}
예제 #6
0
  bool InitD3D11QuadRendering( RENDERER_SETTINGS * settings )
  {
    ID3DBlob * pCode = NULL;
    ID3DBlob * pErrors = NULL;
    if (D3DCompile( defaultVertexShader, strlen(defaultVertexShader), NULL, NULL, NULL, "main", "vs_4_0", NULL, NULL, &pCode, &pErrors ) != S_OK)
    {
      printf("[Renderer] D3DCompile failed\n");
      return false;
    }

    if (pDevice->CreateVertexShader( pCode->GetBufferPointer(), pCode->GetBufferSize(), NULL, &pVertexShader ) != S_OK)
    {
      printf("[Renderer] CreateVertexShader failed\n");
      return false;
    }

    //////////////////////////////////////////////////////////////////////////

    static float pQuad[] = {
      -1.0, -1.0,  0.5, 0.0, 0.0,
      -1.0,  1.0,  0.5, 0.0, 1.0,
       1.0, -1.0,  0.5, 1.0, 0.0,
       1.0,  1.0,  0.5, 1.0, 1.0,
    };

    D3D11_BUFFER_DESC desc;
    ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));

    desc.ByteWidth = sizeof(float) * 5 * 4;
    desc.Usage = D3D11_USAGE_DEFAULT;
    desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;

    D3D11_SUBRESOURCE_DATA subData;
    ZeroMemory(&subData, sizeof(D3D11_SUBRESOURCE_DATA));
    subData.pSysMem = pQuad;

    if (pDevice->CreateBuffer(&desc, &subData, &pFullscreenQuadVB) != S_OK)
    {
      printf("[Renderer] CreateBuffer failed\n");
      return false;
    }

    static D3D11_INPUT_ELEMENT_DESC pQuadDesc[] =
    {
      {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0 * sizeof(float), D3D11_INPUT_PER_VERTEX_DATA, 0},
      {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT   , 0, 3 * sizeof(float), D3D11_INPUT_PER_VERTEX_DATA, 0},
    };

    if (pDevice->CreateInputLayout( pQuadDesc, 2, pCode->GetBufferPointer(), pCode->GetBufferSize(), &pFullscreenQuadLayout) != S_OK)
    {
      printf("[Renderer] CreateInputLayout failed\n");
      return false;
    }

    //////////////////////////////////////////////////////////////////////////

    D3D11_VIEWPORT viewport;
    ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));

    viewport.TopLeftX = 0;
    viewport.TopLeftY = 0;
    viewport.Width  = settings->nWidth;
    viewport.Height = settings->nHeight;

    pContext->RSSetViewports(1, &viewport);

    //////////////////////////////////////////////////////////////////////////

    D3D11_SAMPLER_DESC sampDesc = CD3D11_SAMPLER_DESC( CD3D11_DEFAULT() );
    sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
    if (pDevice->CreateSamplerState( &sampDesc, &pFullscreenQuadSamplerState ) != S_OK)
      return false;

    //////////////////////////////////////////////////////////////////////////

    D3D11_BUFFER_DESC cbDesc;
    ZeroMemory( &cbDesc, sizeof(D3D11_BUFFER_DESC) );
    cbDesc.ByteWidth = sizeof( pFullscreenQuadConstants );
    cbDesc.Usage = D3D11_USAGE_DYNAMIC;
    cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

    ZeroMemory( &subData, sizeof(D3D11_SUBRESOURCE_DATA) );
    subData.pSysMem = &pFullscreenQuadConstants;

    if (pDevice->CreateBuffer( &cbDesc, &subData, &pFullscreenQuadConstantBuffer ) != S_OK)
      return false;

    //////////////////////////////////////////////////////////////////////////

    D3D11_BLEND_DESC blendDesc = CD3D11_BLEND_DESC( CD3D11_DEFAULT() );
    if (pDevice->CreateBlendState( &blendDesc, &pFullscreenQuadBlendState ) != S_OK)
      return false;

    D3D11_RASTERIZER_DESC rastDesc = CD3D11_RASTERIZER_DESC( CD3D11_DEFAULT() );
    if (pDevice->CreateRasterizerState( &rastDesc, &pFullscreenQuadRasterizerState ) != S_OK)
      return false;

    return true;
  }
예제 #7
0
ID3D11SamplerState* StateCache::Get(SamplerState state)
{
	auto it = m_sampler.find(state.packed);

	if (it != m_sampler.end())
	{
		return it->second;
	}

	const unsigned int d3dMipFilters[4] =
	{
		TexMode0::TEXF_NONE,
		TexMode0::TEXF_POINT,
		TexMode0::TEXF_LINEAR,
		TexMode0::TEXF_NONE, //reserved
	};
	const D3D11_TEXTURE_ADDRESS_MODE d3dClamps[4] =
	{
		D3D11_TEXTURE_ADDRESS_CLAMP,
		D3D11_TEXTURE_ADDRESS_WRAP,
		D3D11_TEXTURE_ADDRESS_MIRROR,
		D3D11_TEXTURE_ADDRESS_WRAP //reserved
	};

	D3D11_SAMPLER_DESC sampdc = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT());

	unsigned int mip = d3dMipFilters[state.min_filter & 3];

	if (state.max_anisotropy)
	{
		sampdc.Filter = D3D11_FILTER_ANISOTROPIC;
		sampdc.MaxAnisotropy = (u32)state.max_anisotropy;
	}
	else if (state.min_filter & 4) // linear min filter
	{
		if (state.mag_filter) // linear mag filter
		{
			if (mip == TexMode0::TEXF_NONE)
				sampdc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
			else if (mip == TexMode0::TEXF_POINT)
				sampdc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
			else if (mip == TexMode0::TEXF_LINEAR)
				sampdc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
		}
		else // point mag filter
		{
			if (mip == TexMode0::TEXF_NONE)
				sampdc.Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
			else if (mip == TexMode0::TEXF_POINT)
				sampdc.Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
			else if (mip == TexMode0::TEXF_LINEAR)
				sampdc.Filter = D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
		}
	}
	else // point min filter
	{
		if (state.mag_filter) // linear mag filter
		{
			if (mip == TexMode0::TEXF_NONE)
				sampdc.Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
			else if (mip == TexMode0::TEXF_POINT)
				sampdc.Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
			else if (mip == TexMode0::TEXF_LINEAR)
				sampdc.Filter = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
		}
		else // point mag filter
		{
			if (mip == TexMode0::TEXF_NONE)
				sampdc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
			else if (mip == TexMode0::TEXF_POINT)
				sampdc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
			else if (mip == TexMode0::TEXF_LINEAR)
				sampdc.Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
		}
	}

	sampdc.AddressU = d3dClamps[state.wrap_s];
	sampdc.AddressV = d3dClamps[state.wrap_t];

	sampdc.MaxLOD = (mip == TexMode0::TEXF_NONE) ? 0.0f : (float)state.max_lod / 16.f;
	sampdc.MinLOD = (float)state.min_lod / 16.f;
	sampdc.MipLODBias = (s32)state.lod_bias / 32.0f;

	ID3D11SamplerState* res = nullptr;

	HRESULT hr = D3D::device->CreateSamplerState(&sampdc, &res);
	if (FAILED(hr)) PanicAlert("Fail %s %d\n", __FILE__, __LINE__);
	D3D::SetDebugObjectName((ID3D11DeviceChild*)res, "sampler state used to emulate the GX pipeline");
	m_sampler.insert(std::make_pair(state.packed, res));

	return res;
}
예제 #8
0
	void Texture::loadFromFile(const std::string &filename)
	{
		ID3DBlob* vsBuffer, *psBuffer = 0;
		D3D11_INPUT_ELEMENT_DESC solidColorLayout[] =
		{
			{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
			{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
			{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		};

		CompileD3DShader("Shaders/TextureMap.fx", "VS_Main", "vs_4_0", &vsBuffer);
		CompileD3DShader("Shaders/TextureMap.fx", "PS_Main", "ps_4_0", &psBuffer);

		DirectX::ThrowIfFailed(
			_dev->CreateVertexShader(vsBuffer->GetBufferPointer(),
				vsBuffer->GetBufferSize(),
				0,
				&solidColorVS)
			);

		DirectX::ThrowIfFailed(
			_dev->CreatePixelShader(psBuffer->GetBufferPointer(),
				psBuffer->GetBufferSize(),
				0,
				&solidColorPS)
			);

		unsigned int totalLayoutElements = ARRAYSIZE(solidColorLayout);

		DirectX::ThrowIfFailed(
			_dev->CreateInputLayout(solidColorLayout,
				totalLayoutElements,
				vsBuffer->GetBufferPointer(),
				vsBuffer->GetBufferSize(),
				&inputLayout)
			);

		D3DX11CreateShaderResourceViewFromFile(_dev.Get(),
			filename.c_str(), 0, 0, &colorMap, 0);

		ID3D11Resource *resource;
		ID3D11Texture2D *texture2D;
		D3D11_TEXTURE2D_DESC textureDesc;
		colorMap->GetResource(&resource);
		resource->QueryInterface<ID3D11Texture2D>(&texture2D);
		texture2D->GetDesc(&textureDesc);
		_textureWidth = static_cast<float>(textureDesc.Width);
		_textureHeight = static_cast<float>(textureDesc.Height);

		ID3D11Resource* colorTex;

		colorMap->GetResource(&colorTex);

		D3D11_TEXTURE2D_DESC colorTexDesc;
		((ID3D11Texture2D*)colorTex)->GetDesc(&colorTexDesc);
		colorTex->Release();

		ID3D11RasterizerState *rasterize;

		D3D11_RASTERIZER_DESC rasterizerDesc;
		ZeroMemory(&rasterizerDesc, sizeof(D3D11_RASTERIZER_DESC));

		rasterizerDesc.AntialiasedLineEnable = false;
		rasterizerDesc.CullMode = D3D11_CULL_NONE;
		rasterizerDesc.DepthBias = 0;
		rasterizerDesc.DepthBiasClamp = 0.0f;
		rasterizerDesc.DepthClipEnable = true;
		rasterizerDesc.FillMode = D3D11_FILL_SOLID;
		rasterizerDesc.FrontCounterClockwise = false;
		rasterizerDesc.MultisampleEnable = false;
		rasterizerDesc.ScissorEnable = false;
		rasterizerDesc.SlopeScaledDepthBias = 0.0f;

		_dev->CreateRasterizerState(&rasterizerDesc, &rasterize);
		_devcon->RSSetState(rasterize);

		// transparence
		D3D11_BLEND_DESC blendDesc;
		ZeroMemory(&blendDesc, sizeof(blendDesc));
		blendDesc.RenderTarget[0].BlendEnable = TRUE;
		blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
		blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
		blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
		blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
		blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
		blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
		blendDesc.RenderTarget[0].RenderTargetWriteMask = 0x0f;

		float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };

		_dev->CreateBlendState(&blendDesc, alphaBlendState.GetAddressOf());
		_devcon->OMSetBlendState(alphaBlendState.Get(), blendFactor, 0xFFFFFFFF);

		D3D11_SAMPLER_DESC desc = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT());
		_dev->CreateSamplerState(&desc, &colorMapSampler);
	}
예제 #9
0
bool D3D11Context::startup (void* hwnd)
{
    UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;

#ifdef _DEBUG
    flags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0,
    };

    if (m_failed (::D3D11CreateDevice (nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, flags, featureLevels, numElementsInArray (featureLevels), D3D11_SDK_VERSION, device, &featureLevel, contextIM)))
    {
        if (m_failed (::D3D11CreateDevice (nullptr, D3D_DRIVER_TYPE_WARP, nullptr, flags, featureLevels, numElementsInArray (featureLevels), D3D11_SDK_VERSION, device, &featureLevel, contextIM)))
            return false;
    }

    Hold<IDXGIDevice2> dxgiDevice;
    if (m_failed (device.as (dxgiDevice)))
        return false;

    Hold<IDXGIAdapter> dxgiAdapter;
    if (m_failed (dxgiDevice->GetAdapter (dxgiAdapter)))
        return false;

    Hold<IDXGIFactory2> dxgiFactory;
    if (m_failed (dxgiAdapter->GetParent (__uuidof (IDXGIFactory2), dxgiFactory)))
        return false;

    DXGI_SWAP_CHAIN_DESC1 desc;

    desc.Width = 0;
    desc.Height = 0;
    desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    desc.Stereo = false;
    desc.SampleDesc.Count = 1;
    desc.SampleDesc.Quality = 0;
    desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    desc.BufferCount = 2;
    desc.Scaling = DXGI_SCALING_STRETCH; // DXGI_SCALING_NONE is not supported on Windows7
    desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
    desc.Flags = 0;

    if (m_failed (dxgiFactory->CreateSwapChainForHwnd (device, (HWND)hwnd, &desc, nullptr, nullptr, swapchain)))
        return false;

    Hold<ID3D11Texture2D> backBuf;
    if (m_failed (swapchain->GetBuffer (0, __uuidof (ID3D11Texture2D), backBuf)))
        return false;

    if (m_failed (device->CreateRenderTargetView (backBuf, nullptr, backBufRTView)))
        return false;

    RECT rect;
    ::GetClientRect ((HWND)hwnd, &rect);
    if (m_isnull (depthBuf.set (createTexture2DRT (rect.right - rect.left, rect.bottom - rect.top, 1, DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_D32_FLOAT))))
        return false;

    if (m_isnull (depthBufDSView.set (createDepthStencilView (depthBuf, 0, DXGI_FORMAT_D32_FLOAT))))
        return false;

    if (m_isnull (depthBufSRView.set (createShaderResourceView (depthBuf, DXGI_FORMAT_R32_FLOAT))))
        return false;

    // common sampler states
    {
        D3D11_SAMPLER_DESC _ = CD3D11_SAMPLER_DESC (D3D11_DEFAULT);
        _.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
        _.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
        _.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
        _.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
        if (m_isnull (sampWrapLinear.set (createSamplerState (_))))
            return false;
    }
    {
        D3D11_SAMPLER_DESC _ = CD3D11_SAMPLER_DESC (D3D11_DEFAULT);
        _.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
        _.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
        _.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
        _.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
        if (m_isnull (sampWrapPoint.set (createSamplerState (_))))
            return false;
    }
    {
        D3D11_SAMPLER_DESC _ = CD3D11_SAMPLER_DESC (D3D11_DEFAULT);
        _.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
        _.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
        _.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
        _.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
        if (m_isnull (sampClampLinear.set (createSamplerState (_))))
            return false;
    }
    {
        D3D11_SAMPLER_DESC _ = CD3D11_SAMPLER_DESC (D3D11_DEFAULT);
        _.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
        _.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
        _.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
        _.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
        if (m_isnull (sampClampPoint.set (createSamplerState (_))))
            return false;
    }

    // common rasterizer state
    {
        D3D11_RASTERIZER_DESC _ = CD3D11_RASTERIZER_DESC (D3D11_DEFAULT);
        _.CullMode = D3D11_CULL_NONE;
        _.FrontCounterClockwise = FALSE;
        if (m_isnull (rastCullNone.set (createRasterizerState (_))))
            return false;
    }

    {
        D3D11_RASTERIZER_DESC _ = CD3D11_RASTERIZER_DESC (D3D11_DEFAULT);
        _.CullMode = D3D11_CULL_FRONT;
        _.FrontCounterClockwise = FALSE;
        if (m_isnull (rastCWCullFront.set (createRasterizerState (_))))
            return false;
    }

    {
        D3D11_RASTERIZER_DESC _ = CD3D11_RASTERIZER_DESC (D3D11_DEFAULT);
        _.CullMode = D3D11_CULL_BACK;
        _.FrontCounterClockwise = FALSE;
        if (m_isnull (rastCWCullBack.set (createRasterizerState (_))))
            return false;
    }

    {
        D3D11_RASTERIZER_DESC _ = CD3D11_RASTERIZER_DESC (D3D11_DEFAULT);
        _.CullMode = D3D11_CULL_FRONT;
        _.FrontCounterClockwise = TRUE;
        if (m_isnull (rastCCWCullFront.set (createRasterizerState (_))))
            return false;
    }

    {
        D3D11_RASTERIZER_DESC _ = CD3D11_RASTERIZER_DESC (D3D11_DEFAULT);
        _.CullMode = D3D11_CULL_BACK;
        _.FrontCounterClockwise = TRUE;
        if (m_isnull (rastCCWCullBack.set (createRasterizerState (_))))
            return false;
    }

    // common depth stencil state
    {
        D3D11_DEPTH_STENCIL_DESC _ = CD3D11_DEPTH_STENCIL_DESC (D3D11_DEFAULT);
        _.DepthEnable = TRUE;
        _.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
        if (m_isnull (depthTestOnWriteOn.set (createDepthStencilState (_))))
            return false;
    }

    {
        D3D11_DEPTH_STENCIL_DESC _ = CD3D11_DEPTH_STENCIL_DESC (D3D11_DEFAULT);
        _.DepthEnable = TRUE;
        _.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
        if (m_isnull (depthTestOnWriteOff.set (createDepthStencilState (_))))
            return false;
    }

    {
        D3D11_DEPTH_STENCIL_DESC _ = CD3D11_DEPTH_STENCIL_DESC (D3D11_DEFAULT);
        _.DepthEnable = FALSE;
        _.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
        if (m_isnull (depthTestOffWriteOn.set (createDepthStencilState (_))))
            return false;
    }

    {
        D3D11_DEPTH_STENCIL_DESC _ = CD3D11_DEPTH_STENCIL_DESC (D3D11_DEFAULT);
        _.DepthEnable = FALSE;
        _.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
        if (m_isnull (depthTestOffWriteOff.set (createDepthStencilState (_))))
            return false;
    }

    return true;
}