Ejemplo n.º 1
0
bool D3D12GSRender::LoadProgram()
{
	if (!m_cur_fragment_prog)
	{
		LOG_WARNING(RSX, "LoadProgram: m_cur_shader_prog == NULL");
		return false;
	}

	m_cur_fragment_prog->ctrl = m_shader_ctrl;

	if (!m_cur_vertex_prog)
	{
		LOG_WARNING(RSX, "LoadProgram: m_cur_vertex_prog == NULL");
		return false;
	}

	D3D12PipelineProperties prop = {};
	switch (m_draw_mode - 1)
	{
	case GL_POINTS:
		prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
		break;
	case GL_LINES:
	case GL_LINE_LOOP:
	case GL_LINE_STRIP:
		prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
		break;
	case GL_TRIANGLES:
	case GL_TRIANGLE_STRIP:
	case GL_TRIANGLE_FAN:
		prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
		break;
	case GL_QUADS:
	case GL_QUAD_STRIP:
	case GL_POLYGON:
	default:
		//		LOG_ERROR(RSX, "Unsupported primitive type");
		prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
		break;
	}

	static D3D12_BLEND_DESC CD3D12_BLEND_DESC =
	{
		FALSE,
		FALSE,
		{
			FALSE,FALSE,
			D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
		D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
		D3D12_LOGIC_OP_NOOP,
		D3D12_COLOR_WRITE_ENABLE_ALL,
		}
	};
	prop.Blend = CD3D12_BLEND_DESC;

	if (m_set_blend)
	{
		prop.Blend.RenderTarget[0].BlendEnable = true;

		if (m_set_blend_mrt1)
			prop.Blend.RenderTarget[1].BlendEnable = true;
		if (m_set_blend_mrt2)
			prop.Blend.RenderTarget[2].BlendEnable = true;
		if (m_set_blend_mrt3)
			prop.Blend.RenderTarget[3].BlendEnable = true;
	}

	if (m_set_blend_equation)
	{
		prop.Blend.RenderTarget[0].BlendOp = getBlendOp(m_blend_equation_rgb);
		prop.Blend.RenderTarget[0].BlendOpAlpha = getBlendOp(m_blend_equation_alpha);

		if (m_set_blend_mrt1)
		{
			prop.Blend.RenderTarget[1].BlendOp = getBlendOp(m_blend_equation_rgb);
			prop.Blend.RenderTarget[1].BlendOpAlpha = getBlendOp(m_blend_equation_alpha);
		}

		if (m_set_blend_mrt2)
		{
			prop.Blend.RenderTarget[2].BlendOp = getBlendOp(m_blend_equation_rgb);
			prop.Blend.RenderTarget[2].BlendOpAlpha = getBlendOp(m_blend_equation_alpha);
		}

		if (m_set_blend_mrt3)
		{
			prop.Blend.RenderTarget[3].BlendOp = getBlendOp(m_blend_equation_rgb);
			prop.Blend.RenderTarget[3].BlendOpAlpha = getBlendOp(m_blend_equation_alpha);
		}
	}

	if (m_set_blend_sfactor && m_set_blend_dfactor)
	{
		prop.Blend.RenderTarget[0].SrcBlend = getBlendFactor(m_blend_sfactor_rgb);
		prop.Blend.RenderTarget[0].DestBlend = getBlendFactor(m_blend_dfactor_rgb);
		prop.Blend.RenderTarget[0].SrcBlendAlpha = getBlendFactor(m_blend_sfactor_alpha);
		prop.Blend.RenderTarget[0].DestBlendAlpha = getBlendFactor(m_blend_dfactor_alpha);

		if (m_set_blend_mrt1)
		{
			prop.Blend.RenderTarget[1].SrcBlend = getBlendFactor(m_blend_sfactor_rgb);
			prop.Blend.RenderTarget[1].DestBlend = getBlendFactor(m_blend_dfactor_rgb);
			prop.Blend.RenderTarget[1].SrcBlendAlpha = getBlendFactor(m_blend_sfactor_alpha);
			prop.Blend.RenderTarget[1].DestBlendAlpha = getBlendFactor(m_blend_dfactor_alpha);
		}

		if (m_set_blend_mrt2)
		{
			prop.Blend.RenderTarget[2].SrcBlend = getBlendFactor(m_blend_sfactor_rgb);
			prop.Blend.RenderTarget[2].DestBlend = getBlendFactor(m_blend_dfactor_rgb);
			prop.Blend.RenderTarget[2].SrcBlendAlpha = getBlendFactor(m_blend_sfactor_alpha);
			prop.Blend.RenderTarget[2].DestBlendAlpha = getBlendFactor(m_blend_dfactor_alpha);
		}

		if (m_set_blend_mrt3)
		{
			prop.Blend.RenderTarget[3].SrcBlend = getBlendFactor(m_blend_sfactor_rgb);
			prop.Blend.RenderTarget[3].DestBlend = getBlendFactor(m_blend_dfactor_rgb);
			prop.Blend.RenderTarget[3].SrcBlendAlpha = getBlendFactor(m_blend_sfactor_alpha);
			prop.Blend.RenderTarget[3].DestBlendAlpha = getBlendFactor(m_blend_dfactor_alpha);
		}
	}

	if (m_set_logic_op)
	{
		prop.Blend.RenderTarget[0].LogicOpEnable = true;
		prop.Blend.RenderTarget[0].LogicOp = getLogicOp(m_logic_op);
	}

	if (m_set_blend_color)
	{
		//		glBlendColor(m_blend_color_r, m_blend_color_g, m_blend_color_b, m_blend_color_a);
		//		checkForGlError("glBlendColor");
	}

	switch (m_surface_depth_format)
	{
	case 0:
		break;
	case CELL_GCM_SURFACE_Z16:
		prop.DepthStencilFormat = DXGI_FORMAT_D16_UNORM;
		break;
	case CELL_GCM_SURFACE_Z24S8:
		prop.DepthStencilFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
		break;
	default:
		LOG_ERROR(RSX, "Bad depth format! (%d)", m_surface_depth_format);
		assert(0);
	}

	switch (m_surface_color_format)
	{
	case CELL_GCM_SURFACE_A8R8G8B8:
		prop.RenderTargetsFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
		break;
	case CELL_GCM_SURFACE_F_W16Z16Y16X16:
		prop.RenderTargetsFormat = DXGI_FORMAT_R16G16B16A16_FLOAT;
		break;
	}

	switch (m_surface_color_target)
	{
	case CELL_GCM_SURFACE_TARGET_0:
	case CELL_GCM_SURFACE_TARGET_1:
		prop.numMRT = 1;
		break;
	case CELL_GCM_SURFACE_TARGET_MRT1:
		prop.numMRT = 2;
		break;
	case CELL_GCM_SURFACE_TARGET_MRT2:
		prop.numMRT = 3;
		break;
	case CELL_GCM_SURFACE_TARGET_MRT3:
		prop.numMRT = 4;
		break;
	default:
		LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target);
	}

	prop.DepthStencil.DepthEnable = m_set_depth_test;
	prop.DepthStencil.DepthWriteMask = m_depth_mask ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
	prop.DepthStencil.DepthFunc = getCompareFunc(m_depth_func);
	prop.DepthStencil.StencilEnable = m_set_stencil_test;
	prop.DepthStencil.StencilReadMask = m_stencil_func_mask;
	prop.DepthStencil.StencilWriteMask = m_stencil_mask;
	prop.DepthStencil.FrontFace.StencilPassOp = getStencilOp(m_stencil_zpass);
	prop.DepthStencil.FrontFace.StencilDepthFailOp = getStencilOp(m_stencil_zfail);
	prop.DepthStencil.FrontFace.StencilFailOp = getStencilOp(m_stencil_fail);
	prop.DepthStencil.FrontFace.StencilFunc = getCompareFunc(m_stencil_func);

	if (m_set_two_sided_stencil_test_enable)
	{
		prop.DepthStencil.BackFace.StencilFailOp = getStencilOp(m_back_stencil_fail);
		prop.DepthStencil.BackFace.StencilFunc = getCompareFunc(m_back_stencil_func);
		prop.DepthStencil.BackFace.StencilPassOp = getStencilOp(m_back_stencil_zpass);
		prop.DepthStencil.BackFace.StencilDepthFailOp = getStencilOp(m_back_stencil_zfail);
	}
	else
	{
		prop.DepthStencil.BackFace.StencilPassOp = getStencilOp(m_stencil_zpass);
		prop.DepthStencil.BackFace.StencilDepthFailOp = getStencilOp(m_stencil_zfail);
		prop.DepthStencil.BackFace.StencilFailOp = getStencilOp(m_stencil_fail);
		prop.DepthStencil.BackFace.StencilFunc = getCompareFunc(m_stencil_func);
	}

	// Sensible default value
	static D3D12_RASTERIZER_DESC CD3D12_RASTERIZER_DESC =
	{
		D3D12_FILL_MODE_SOLID,
		D3D12_CULL_MODE_NONE,
		FALSE,
		D3D12_DEFAULT_DEPTH_BIAS,
		D3D12_DEFAULT_DEPTH_BIAS_CLAMP,
		D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,
		TRUE,
		FALSE,
		FALSE,
		0,
		D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF,
	};
	prop.Rasterization = CD3D12_RASTERIZER_DESC;
	switch (m_set_cull_face)
	{
	case CELL_GCM_FRONT:
		prop.Rasterization.CullMode = D3D12_CULL_MODE_FRONT;
		break;
	case CELL_GCM_BACK:
		prop.Rasterization.CullMode = D3D12_CULL_MODE_BACK;
		break;
	default:
		prop.Rasterization.CullMode = D3D12_CULL_MODE_NONE;
		break;
	}

	switch (m_front_face)
	{
	case CELL_GCM_CW:
		prop.Rasterization.FrontCounterClockwise = FALSE;
		break;
	case CELL_GCM_CCW:
		prop.Rasterization.FrontCounterClockwise = TRUE;
		break;
	}

	if (m_set_color_mask)
	{
		UINT8 mask = 0;
		mask |= m_color_mask_r ? D3D12_COLOR_WRITE_ENABLE_RED : 0;
		mask |= m_color_mask_g ? D3D12_COLOR_WRITE_ENABLE_GREEN : 0;
		mask |= m_color_mask_b ? D3D12_COLOR_WRITE_ENABLE_BLUE : 0;
		mask |= m_color_mask_a ? D3D12_COLOR_WRITE_ENABLE_ALPHA : 0;
		for (unsigned i = 0; i < prop.numMRT; i++)
			prop.Blend.RenderTarget[i].RenderTargetWriteMask = mask;
	}

	prop.IASet = m_IASet;

	m_PSO = m_cachePSO.getGraphicPipelineState(m_cur_vertex_prog, m_cur_fragment_prog, prop, std::make_pair(m_device.Get(), m_rootSignatures));
	return m_PSO != nullptr;
}
Ejemplo n.º 2
0
bool D3D12GSRender::LoadProgram()
{
	RSXVertexProgram vertex_program;
	u32 transform_program_start = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START];
	vertex_program.data.reserve((512 - transform_program_start) * 4);

	for (int i = transform_program_start; i < 512; ++i)
	{
		vertex_program.data.resize((i - transform_program_start) * 4 + 4);
		memcpy(vertex_program.data.data() + (i - transform_program_start) * 4, transform_program + i * 4, 4 * sizeof(u32));

		D3 d3;
		d3.HEX = transform_program[i * 4 + 3];

		if (d3.end)
			break;
	}

	u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM];
	fragment_program.offset = shader_program & ~0x3;
	fragment_program.addr = rsx::get_address(fragment_program.offset, (shader_program & 0x3) - 1);
	fragment_program.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL];

	D3D12PipelineProperties prop = {};
	switch (draw_mode - 1)
	{
	case GL_POINTS:
		prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
		break;
	case GL_LINES:
	case GL_LINE_LOOP:
	case GL_LINE_STRIP:
		prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
		break;
	case GL_TRIANGLES:
	case GL_TRIANGLE_STRIP:
	case GL_TRIANGLE_FAN:
		prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
		break;
	case GL_QUADS:
	case GL_QUAD_STRIP:
	case GL_POLYGON:
	default:
		//		LOG_ERROR(RSX, "Unsupported primitive type");
		prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
		break;
	}

	static D3D12_BLEND_DESC CD3D12_BLEND_DESC =
	{
		FALSE,
		FALSE,
		{
			FALSE,FALSE,
			D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
		D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
		D3D12_LOGIC_OP_NOOP,
		D3D12_COLOR_WRITE_ENABLE_ALL,
		}
	};
	prop.Blend = CD3D12_BLEND_DESC;

	if (rsx::method_registers[NV4097_SET_BLEND_ENABLE])
	{
		prop.Blend.RenderTarget[0].BlendEnable = true;

		if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x2)
			prop.Blend.RenderTarget[1].BlendEnable = true;
		if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x4)
			prop.Blend.RenderTarget[2].BlendEnable = true;
		if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x8)
			prop.Blend.RenderTarget[3].BlendEnable = true;

		prop.Blend.RenderTarget[0].BlendOp = getBlendOp(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF);
		prop.Blend.RenderTarget[0].BlendOpAlpha = getBlendOp(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16);

		if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x2)
		{
			prop.Blend.RenderTarget[1].BlendOp = getBlendOp(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF);
			prop.Blend.RenderTarget[1].BlendOpAlpha = getBlendOp(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16);
		}

		if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x4)
		{
			prop.Blend.RenderTarget[2].BlendOp = getBlendOp(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF);
			prop.Blend.RenderTarget[2].BlendOpAlpha = getBlendOp(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16);
		}