Beispiel #1
0
bool WrappedOpenGL::Serialise_glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ,
												                         GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ,
												                         GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)
{
	SERIALISE_ELEMENT(ResourceId, srcid, GetResourceManager()->GetID(BufferRes(srcName)));
	SERIALISE_ELEMENT(ResourceId, dstid, GetResourceManager()->GetID(BufferRes(dstName)));
	SERIALISE_ELEMENT(GLenum, SourceTarget, srcTarget);
	SERIALISE_ELEMENT(GLenum, DestTarget, dstTarget);
	SERIALISE_ELEMENT(uint32_t, SourceLevel, srcLevel);
	SERIALISE_ELEMENT(uint32_t, SourceX, srcX);
	SERIALISE_ELEMENT(uint32_t, SourceY, srcY);
	SERIALISE_ELEMENT(uint32_t, SourceZ, srcZ);
	SERIALISE_ELEMENT(uint32_t, SourceWidth, srcWidth);
	SERIALISE_ELEMENT(uint32_t, SourceHeight, srcHeight);
	SERIALISE_ELEMENT(uint32_t, SourceDepth, srcDepth);
	SERIALISE_ELEMENT(uint32_t, DestLevel, dstLevel);
	SERIALISE_ELEMENT(uint32_t, DestX, dstX);
	SERIALISE_ELEMENT(uint32_t, DestY, dstY);
	SERIALISE_ELEMENT(uint32_t, DestZ, dstZ);
	
	if(m_State < WRITING)
	{
		GLResource srcres = GetResourceManager()->GetLiveResource(srcid);
		GLResource dstres = GetResourceManager()->GetLiveResource(dstid);
		m_Real.glCopyImageSubData(srcres.name, SourceTarget, SourceLevel, SourceX, SourceY, SourceZ,
															dstres.name, DestTarget, DestLevel, DestX, DestY, DestZ,
															SourceWidth, SourceHeight, SourceDepth);
	}
	return true;
}
Beispiel #2
0
void WrappedOpenGL::glGetNamedBufferPointervEXT(GLuint buffer, GLenum pname, void **params)
{
	CoherentMapImplicitBarrier();
	
	// intercept GL_BUFFER_MAP_POINTER queries
	if(pname == eGL_BUFFER_MAP_POINTER)
	{
		GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer));
		RDCASSERT(record);

		if(record)
		{
			if(record->Map.status == GLResourceRecord::Unmapped)
				*params = NULL;
			else
				*params = (void *)record->Map.ptr;
		}
		else
		{
			*params = NULL;
		}
	}
	else
	{
	m_Real.glGetNamedBufferPointervEXT(buffer, pname, params);
	}
}
Beispiel #3
0
void GLRenderState::Serialise(LogState state, void *ctx, WrappedOpenGL *gl)
{
	GLResourceManager *rm = gl->GetResourceManager();
	// TODO check GL_MAX_*

	m_pSerialiser->Serialise<eEnabled_Count>("GL_ENABLED", Enabled);
	
	for(size_t i=0; i < ARRAY_COUNT(Tex2D); i++)
	{
		ResourceId ID = ResourceId();
		if(state >= WRITING) ID = rm->GetID(TextureRes(ctx, Tex2D[i]));
		m_pSerialiser->Serialise("GL_TEXTURE_BINDING_2D", ID);
		if(state < WRITING && ID != ResourceId()) Tex2D[i] = rm->GetLiveResource(ID).name;
	}
	
	for(size_t i=0; i < ARRAY_COUNT(Samplers); i++)
	{
		ResourceId ID = ResourceId();
		if(state >= WRITING) ID = rm->GetID(SamplerRes(ctx, Samplers[i]));
		m_pSerialiser->Serialise("GL_SAMPLER_BINDING", ID);
		if(state < WRITING && ID != ResourceId()) Samplers[i] = rm->GetLiveResource(ID).name;
	}

	m_pSerialiser->Serialise("GL_ACTIVE_TEXTURE", ActiveTexture);
	
	{
		ResourceId ID = ResourceId();
		if(state >= WRITING) ID = rm->GetID(VertexArrayRes(ctx, VAO));
		m_pSerialiser->Serialise("GL_VERTEX_ARRAY_BINDING", ID);
		if(state < WRITING && ID != ResourceId()) VAO = rm->GetLiveResource(ID).name;

		if(VAO == 0) VAO = gl->GetFakeVAO();
	}
	
	{
		ResourceId ID = ResourceId();
		if(state >= WRITING) ID = rm->GetID(FeedbackRes(ctx, FeedbackObj));
		m_pSerialiser->Serialise("GL_TRANSFORM_FEEDBACK_BINDING", ID);
		if(state < WRITING && ID != ResourceId()) FeedbackObj = rm->GetLiveResource(ID).name;
	}
	
	for(size_t i=0; i < ARRAY_COUNT(GenericVertexAttribs); i++)
	{
		m_pSerialiser->Serialise<4>("GL_CURRENT_VERTEX_ATTRIB", &GenericVertexAttribs[i].x);
	}
	
	m_pSerialiser->Serialise("GL_POINT_FADE_THRESHOLD_SIZE", PointFadeThresholdSize);
	m_pSerialiser->Serialise("GL_POINT_SPRITE_COORD_ORIGIN", PointSpriteOrigin);
	m_pSerialiser->Serialise("GL_LINE_WIDTH", LineWidth);
	m_pSerialiser->Serialise("GL_POINT_SIZE", PointSize);
	
	m_pSerialiser->Serialise("GL_PRIMITIVE_RESTART_INDEX", PrimitiveRestartIndex);
	m_pSerialiser->Serialise("GL_CLIP_ORIGIN", ClipOrigin);
	m_pSerialiser->Serialise("GL_CLIP_DEPTH_MODE", ClipDepth);
	m_pSerialiser->Serialise("GL_PROVOKING_VERTEX", ProvokingVertex);

	for(size_t i=0; i < ARRAY_COUNT(BufferBindings); i++)
	{
		ResourceId ID = ResourceId();
		if(state >= WRITING) ID = rm->GetID(BufferRes(ctx, BufferBindings[i]));
		m_pSerialiser->Serialise("GL_BUFFER_BINDING", ID);
		if(state < WRITING && ID != ResourceId()) BufferBindings[i] = rm->GetLiveResource(ID).name;
	}
	
	{
		ResourceId ID = ResourceId();
		if(state >= WRITING) ID = rm->GetID(ProgramRes(ctx, Program));
		m_pSerialiser->Serialise("GL_CURRENT_PROGRAM", ID);
		if(state < WRITING && ID != ResourceId()) Program = rm->GetLiveResource(ID).name;
	}
	{
		ResourceId ID = ResourceId();
		if(state >= WRITING) ID = rm->GetID(ProgramPipeRes(ctx, Pipeline));
		m_pSerialiser->Serialise("GL_PROGRAM_PIPELINE_BINDING", ID);
		if(state < WRITING && ID != ResourceId()) Pipeline = rm->GetLiveResource(ID).name;
	}
	
	for(size_t s=0; s < ARRAY_COUNT(Subroutines); s++)
	{
		m_pSerialiser->Serialise("GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS", Subroutines[s].numSubroutines);
		m_pSerialiser->Serialise<128>("GL_SUBROUTINE_UNIFORMS", Subroutines[s].Values);
	}

	{
		ResourceId ID = ResourceId();
		if(state >= WRITING) ID = rm->GetID(FramebufferRes(ctx, DrawFBO));
		m_pSerialiser->Serialise("GL_DRAW_FRAMEBUFFER_BINDING", ID);
		if(state < WRITING && ID != ResourceId()) DrawFBO = rm->GetLiveResource(ID).name;

		if(DrawFBO == 0) DrawFBO = gl->GetFakeBBFBO();
	}
	{
		ResourceId ID = ResourceId();
		if(state >= WRITING) ID = rm->GetID(FramebufferRes(ctx, ReadFBO));
		m_pSerialiser->Serialise("GL_READ_FRAMEBUFFER_BINDING", ID);
		if(state < WRITING && ID != ResourceId()) ReadFBO = rm->GetLiveResource(ID).name;

		if(ReadFBO == 0) ReadFBO = gl->GetFakeBBFBO();
	}
	
	struct { IdxRangeBuffer *bufs; int count; } idxBufs[] =
	{
		{ AtomicCounter, ARRAY_COUNT(AtomicCounter), },
		{ ShaderStorage, ARRAY_COUNT(ShaderStorage), },
		{ TransformFeedback, ARRAY_COUNT(TransformFeedback), },
		{ UniformBinding, ARRAY_COUNT(UniformBinding), },
	};

	for(size_t b=0; b < ARRAY_COUNT(idxBufs); b++)
	{
		for(int i=0; i < idxBufs[b].count; i++)
		{
			ResourceId ID = ResourceId();
			if(state >= WRITING) ID = rm->GetID(BufferRes(ctx, idxBufs[b].bufs[i].name));
			m_pSerialiser->Serialise("BUFFER_BINDING", ID);
			if(state < WRITING && ID != ResourceId()) idxBufs[b].bufs[i].name = rm->GetLiveResource(ID).name;

			m_pSerialiser->Serialise("BUFFER_START", idxBufs[b].bufs[i].start);
			m_pSerialiser->Serialise("BUFFER_SIZE", idxBufs[b].bufs[i].size);
		}
	}
	
	for(size_t i=0; i < ARRAY_COUNT(Blends); i++)
	{
		m_pSerialiser->Serialise("GL_BLEND_EQUATION_RGB", Blends[i].EquationRGB);
		m_pSerialiser->Serialise("GL_BLEND_EQUATION_ALPHA", Blends[i].EquationAlpha);

		m_pSerialiser->Serialise("GL_BLEND_SRC_RGB", Blends[i].SourceRGB);
		m_pSerialiser->Serialise("GL_BLEND_SRC_ALPHA", Blends[i].SourceAlpha);

		m_pSerialiser->Serialise("GL_BLEND_DST_RGB", Blends[i].DestinationRGB);
		m_pSerialiser->Serialise("GL_BLEND_DST_ALPHA", Blends[i].DestinationAlpha);
		
		m_pSerialiser->Serialise("GL_BLEND", Blends[i].Enabled);
	}
	
	m_pSerialiser->Serialise<4>("GL_BLEND_COLOR", BlendColor);
		
	for(size_t i=0; i < ARRAY_COUNT(Viewports); i++)
	{
		m_pSerialiser->Serialise("GL_VIEWPORT.x", Viewports[i].x);
		m_pSerialiser->Serialise("GL_VIEWPORT.y", Viewports[i].y);
		m_pSerialiser->Serialise("GL_VIEWPORT.w", Viewports[i].width);
		m_pSerialiser->Serialise("GL_VIEWPORT.h", Viewports[i].height);
	}

	for(size_t i=0; i < ARRAY_COUNT(Scissors); i++)
	{
		m_pSerialiser->Serialise("GL_SCISSOR.x", Scissors[i].x);
		m_pSerialiser->Serialise("GL_SCISSOR.y", Scissors[i].y);
		m_pSerialiser->Serialise("GL_SCISSOR.w", Scissors[i].width);
		m_pSerialiser->Serialise("GL_SCISSOR.h", Scissors[i].height);
		m_pSerialiser->Serialise("GL_SCISSOR.enabled", Scissors[i].enabled);
	}
	
	m_pSerialiser->Serialise<8>("GL_DRAW_BUFFERS", DrawBuffers);
	m_pSerialiser->Serialise("GL_READ_BUFFER", ReadBuffer);

	m_pSerialiser->Serialise("GL_FRAGMENT_SHADER_DERIVATIVE_HINT", Hints.Derivatives);
	m_pSerialiser->Serialise("GL_LINE_SMOOTH_HINT", Hints.LineSmooth);
	m_pSerialiser->Serialise("GL_POLYGON_SMOOTH_HINT", Hints.PolySmooth);
	m_pSerialiser->Serialise("GL_TEXTURE_COMPRESSION_HINT", Hints.TexCompression);
	
	m_pSerialiser->Serialise("GL_DEPTH_WRITEMASK", DepthWriteMask);
	m_pSerialiser->Serialise("GL_DEPTH_CLEAR_VALUE", DepthClearValue);
	m_pSerialiser->Serialise("GL_DEPTH_FUNC", DepthFunc);
	
	for(size_t i=0; i < ARRAY_COUNT(DepthRanges); i++)
	{
		m_pSerialiser->Serialise("GL_DEPTH_RANGE.near", DepthRanges[i].nearZ);
		m_pSerialiser->Serialise("GL_DEPTH_RANGE.far", DepthRanges[i].farZ);
	}
	
	{
		m_pSerialiser->Serialise("GL_DEPTH_BOUNDS_EXT.near", DepthBounds.nearZ);
		m_pSerialiser->Serialise("GL_DEPTH_BOUNDS_EXT.far", DepthBounds.farZ);
	}
	
	{
		m_pSerialiser->Serialise("GL_STENCIL_FUNC", StencilFront.func);
		m_pSerialiser->Serialise("GL_STENCIL_BACK_FUNC", StencilBack.func);

		m_pSerialiser->Serialise("GL_STENCIL_REF", StencilFront.ref);
		m_pSerialiser->Serialise("GL_STENCIL_BACK_REF", StencilBack.ref);

		m_pSerialiser->Serialise("GL_STENCIL_VALUE_MASK", StencilFront.valuemask);
		m_pSerialiser->Serialise("GL_STENCIL_BACK_VALUE_MASK", StencilBack.valuemask);
		
		m_pSerialiser->Serialise("GL_STENCIL_WRITEMASK", StencilFront.writemask);
		m_pSerialiser->Serialise("GL_STENCIL_BACK_WRITEMASK", StencilBack.writemask);

		m_pSerialiser->Serialise("GL_STENCIL_FAIL", StencilFront.stencilFail);
		m_pSerialiser->Serialise("GL_STENCIL_BACK_FAIL", StencilBack.stencilFail);

		m_pSerialiser->Serialise("GL_STENCIL_PASS_DEPTH_FAIL", StencilFront.depthFail);
		m_pSerialiser->Serialise("GL_STENCIL_BACK_PASS_DEPTH_FAIL", StencilBack.depthFail);

		m_pSerialiser->Serialise("GL_STENCIL_PASS_DEPTH_PASS", StencilFront.pass);
		m_pSerialiser->Serialise("GL_STENCIL_BACK_PASS_DEPTH_PASS", StencilBack.pass);
	}

	m_pSerialiser->Serialise("GL_STENCIL_CLEAR_VALUE", StencilClearValue);

	for(size_t i=0; i < ARRAY_COUNT(ColorMasks); i++)
		m_pSerialiser->Serialise<4>("GL_COLOR_WRITEMASK", &ColorMasks[i].red);
	
	m_pSerialiser->Serialise<2>("GL_SAMPLE_MASK_VALUE", &SampleMask[0]);
	m_pSerialiser->Serialise("GL_SAMPLE_COVERAGE_VALUE", SampleCoverage);
	m_pSerialiser->Serialise("GL_SAMPLE_COVERAGE_INVERT", SampleCoverageInvert);
	m_pSerialiser->Serialise("GL_MIN_SAMPLE_SHADING", MinSampleShading);

	m_pSerialiser->Serialise("GL_RASTER_SAMPLES_EXT", RasterSamples);
	m_pSerialiser->Serialise("GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT", RasterFixed);

	m_pSerialiser->Serialise("GL_LOGIC_OP_MODE", LogicOp);

	m_pSerialiser->Serialise<4>("GL_COLOR_CLEAR_VALUE", &ColorClearValue.red);

	{
		m_pSerialiser->Serialise("GL_PATCH_VERTICES", PatchParams.numVerts);
		m_pSerialiser->Serialise<2>("GL_PATCH_DEFAULT_INNER_LEVEL", &PatchParams.defaultInnerLevel[0]);
		m_pSerialiser->Serialise<4>("GL_PATCH_DEFAULT_OUTER_LEVEL", &PatchParams.defaultOuterLevel[0]);
	}

	m_pSerialiser->Serialise("GL_POLYGON_MODE", PolygonMode);
	m_pSerialiser->Serialise("GL_POLYGON_OFFSET_FACTOR", PolygonOffset[0]);
	m_pSerialiser->Serialise("GL_POLYGON_OFFSET_UNITS", PolygonOffset[1]);
	m_pSerialiser->Serialise("GL_POLYGON_OFFSET_CLAMP_EXT", PolygonOffset[2]);
		
	m_pSerialiser->Serialise("GL_FRONT_FACE", FrontFace);
	m_pSerialiser->Serialise("GL_CULL_FACE_MODE", CullFace);
}
Beispiel #4
0
void GLReplay::SavePipelineState()
{
	GLPipelineState &pipe = m_CurPipelineState;
	WrappedOpenGL &gl = *m_pDriver;
	GLResourceManager *rm = m_pDriver->GetResourceManager();

	MakeCurrentReplayContext(&m_ReplayCtx);

	// Index buffer

	pipe.m_VtxIn.ibuffer.Offset = m_pDriver->m_LastIndexOffset;
	
	pipe.m_VtxIn.ibuffer.Format = ResourceFormat();
	pipe.m_VtxIn.ibuffer.Format.special = false;
	pipe.m_VtxIn.ibuffer.Format.compCount = 1;
	pipe.m_VtxIn.ibuffer.Format.compType = eCompType_UInt;
	switch(m_pDriver->m_LastIndexSize)
	{
		default:
			break;
		case eGL_UNSIGNED_BYTE:
			pipe.m_VtxIn.ibuffer.Format.compByteWidth = 1;
			pipe.m_VtxIn.ibuffer.Format.strname = L"GL_UNSIGNED_BYTE";
			break;
		case eGL_UNSIGNED_SHORT:
			pipe.m_VtxIn.ibuffer.Format.compByteWidth = 2;
			pipe.m_VtxIn.ibuffer.Format.strname = L"GL_UNSIGNED_SHORT";
			break;
		case eGL_UNSIGNED_INT:
			pipe.m_VtxIn.ibuffer.Format.compByteWidth = 4;
			pipe.m_VtxIn.ibuffer.Format.strname = L"GL_UNSIGNED_INT";
			break;
	}

	GLint curIdxBuf = 0;
	gl.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, &curIdxBuf);

	pipe.m_VtxIn.ibuffer.Buffer = rm->GetOriginalID(rm->GetID(BufferRes(curIdxBuf)));

	// Vertex buffers and attributes
	GLint numVBufferBindings = 16;
	gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIB_BINDINGS, &numVBufferBindings);
	
	GLint numVAttribBindings = 16;
	gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIBS, &numVAttribBindings);

	create_array_uninit(pipe.m_VtxIn.vbuffers, numVBufferBindings);
	create_array_uninit(pipe.m_VtxIn.attributes, numVAttribBindings);

	for(GLuint i=0; i < (GLuint)numVBufferBindings; i++)
	{
		GLint vb = 0;
		gl.glGetIntegeri_v(eGL_VERTEX_BINDING_BUFFER, i, &vb);
		pipe.m_VtxIn.vbuffers[i].Buffer = rm->GetOriginalID(rm->GetID(BufferRes(vb)));

		gl.glGetIntegeri_v(eGL_VERTEX_BINDING_STRIDE, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Stride);
		gl.glGetIntegeri_v(eGL_VERTEX_BINDING_OFFSET, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Offset);
		gl.glGetIntegeri_v(eGL_VERTEX_BINDING_DIVISOR, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Divisor);
		pipe.m_VtxIn.vbuffers[i].PerInstance = (pipe.m_VtxIn.vbuffers[i].Divisor != 0);
	}
	
	for(GLuint i=0; i < (GLuint)numVAttribBindings; i++)
	{
		gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_ENABLED, (GLint *)&pipe.m_VtxIn.attributes[i].Enabled);
		gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_BINDING, (GLint *)&pipe.m_VtxIn.attributes[i].BufferSlot);
		gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_RELATIVE_OFFSET, (GLint*)&pipe.m_VtxIn.attributes[i].RelativeOffset);

		GLenum type = eGL_FLOAT;
		GLint normalized = 0;
		
		gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_TYPE, (GLint *)&type);
		gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized);

		ResourceFormat fmt;

		fmt.special = false;
		fmt.compCount = 4;
		gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_SIZE, (GLint *)&fmt.compCount);
		
		switch(type)
		{
			default:
			case eGL_BYTE:
				fmt.compByteWidth = 1;
				fmt.compType = normalized ? eCompType_SInt : eCompType_SNorm;
				fmt.strname = StringFormat::WFmt(L"GL_BYTE%d", fmt.compCount) + (normalized ? L"" : L"_SNORM");
				break;
			case eGL_UNSIGNED_BYTE:
				fmt.compByteWidth = 1;
				fmt.compType = normalized ? eCompType_UInt : eCompType_UNorm;
				fmt.strname = StringFormat::WFmt(L"GL_UNSIGNED_BYTE%d", fmt.compCount) + (normalized ? L"" : L"_UNORM");
				break;
			case eGL_SHORT:
				fmt.compByteWidth = 2;
				fmt.compType = normalized ? eCompType_SInt : eCompType_SNorm;
				fmt.strname = StringFormat::WFmt(L"GL_SHORT%d", fmt.compCount) + (normalized ? L"" : L"_SNORM");
				break;
			case eGL_UNSIGNED_SHORT:
				fmt.compByteWidth = 2;
				fmt.compType = normalized ? eCompType_UInt : eCompType_UNorm;
				fmt.strname = StringFormat::WFmt(L"GL_UNSIGNED_SHORT%d", fmt.compCount) + (normalized ? L"" : L"_UNORM");
				break;
			case eGL_INT:
				fmt.compByteWidth = 4;
				fmt.compType = normalized ? eCompType_SInt : eCompType_SNorm;
				fmt.strname = StringFormat::WFmt(L"GL_INT%d", fmt.compCount) + (normalized ? L"" : L"_SNORM");
				break;
			case eGL_UNSIGNED_INT:
				fmt.compByteWidth = 4;
				fmt.compType = normalized ? eCompType_UInt : eCompType_UNorm;
				fmt.strname = StringFormat::WFmt(L"GL_UNSIGNED_INT%d", fmt.compCount) + (normalized ? L"" : L"_UNORM");
				break;
			case eGL_FLOAT:
				fmt.compByteWidth = 4;
				fmt.compType = eCompType_Float;
				fmt.strname = StringFormat::WFmt(L"GL_FLOAT%d", fmt.compCount);
				break;
			case eGL_DOUBLE:
				fmt.compByteWidth = 8;
				fmt.compType = eCompType_Double;
				fmt.strname = StringFormat::WFmt(L"GL_DOUBLE%d", fmt.compCount);
				break;
			case eGL_HALF_FLOAT:
				fmt.compByteWidth = 2;
				fmt.compType = eCompType_Float;
				fmt.strname = StringFormat::WFmt(L"GL_HALF_FLOAT%d", fmt.compCount);
				break;
			case eGL_INT_2_10_10_10_REV:
				fmt.special = true;
				fmt.specialFormat = eSpecial_R10G10B10A2;
				fmt.compCount = 4;
				fmt.compType = eCompType_UInt;
				fmt.strname = L"GL_INT_2_10_10_10_REV";
				break;
			case eGL_UNSIGNED_INT_2_10_10_10_REV:
				fmt.special = true;
				fmt.specialFormat = eSpecial_R10G10B10A2;
				fmt.compCount = 4;
				fmt.compType = eCompType_SInt;
				fmt.strname = L"eGL_UNSIGNED_INT_2_10_10_10_REV";
				break;
			case eGL_UNSIGNED_INT_10F_11F_11F_REV:
				fmt.special = true;
				fmt.specialFormat = eSpecial_R11G11B10;
				fmt.compCount = 3;
				fmt.compType = eCompType_SInt;
				fmt.strname = L"eGL_UNSIGNED_INT_10F_11F_11F_REV";
				break;
		}

		pipe.m_VtxIn.attributes[i].Format = fmt;
	}

	switch(m_pDriver->m_LastDrawMode)
	{
		default:
			pipe.m_VtxIn.Topology = eTopology_Unknown;
			break;
		case GL_POINTS:
			pipe.m_VtxIn.Topology = eTopology_PointList;
			break;
		case GL_LINE_STRIP:
			pipe.m_VtxIn.Topology = eTopology_LineStrip;
			break;
		case GL_LINE_LOOP:
			pipe.m_VtxIn.Topology = eTopology_LineLoop;
			break;
		case GL_LINES:
			pipe.m_VtxIn.Topology = eTopology_LineList;
			break;
		case GL_LINE_STRIP_ADJACENCY:
			pipe.m_VtxIn.Topology = eTopology_LineStrip_Adj;
			break;
		case GL_LINES_ADJACENCY:
			pipe.m_VtxIn.Topology = eTopology_LineList_Adj;
			break;
		case GL_TRIANGLE_STRIP:
			pipe.m_VtxIn.Topology = eTopology_TriangleStrip;
			break;
		case GL_TRIANGLE_FAN:
			pipe.m_VtxIn.Topology = eTopology_TriangleFan;
			break;
		case GL_TRIANGLES:
			pipe.m_VtxIn.Topology = eTopology_TriangleList;
			break;
		case GL_TRIANGLE_STRIP_ADJACENCY:
			pipe.m_VtxIn.Topology = eTopology_TriangleStrip_Adj;
			break;
		case GL_TRIANGLES_ADJACENCY:
			pipe.m_VtxIn.Topology = eTopology_TriangleList_Adj;
			break;
		case GL_PATCHES:
		{
			GLint patchCount = 3;
			gl.glGetIntegerv(eGL_PATCH_VERTICES, &patchCount);
			pipe.m_VtxIn.Topology = PrimitiveTopology(eTopology_PatchList_1CPs+patchCount);
			break;
		}
	}

	// Shader stages
	
	GLuint curProg = 0;
	gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint*)&curProg);
	
	auto &progDetails = m_pDriver->m_Programs[rm->GetID(ProgramRes(curProg))];

	RDCASSERT(progDetails.shaders.size());

	for(size_t i=0; i < progDetails.shaders.size(); i++)
	{
		if(m_pDriver->m_Shaders[ progDetails.shaders[i] ].type == eGL_VERTEX_SHADER)
			pipe.m_VS.Shader = rm->GetOriginalID(progDetails.shaders[i]);
		else if(m_pDriver->m_Shaders[ progDetails.shaders[i] ].type == eGL_FRAGMENT_SHADER)
			pipe.m_FS.Shader = rm->GetOriginalID(progDetails.shaders[i]);
	}
	
	pipe.m_VS.stage = eShaderStage_Vertex;
	pipe.m_TCS.stage = eShaderStage_Tess_Control;
	pipe.m_TES.stage = eShaderStage_Tess_Eval;
	pipe.m_GS.stage = eShaderStage_Geometry;
	pipe.m_FS.stage = eShaderStage_Fragment;
	pipe.m_CS.stage = eShaderStage_Compute;

	// Textures
	
	GLint numTexUnits = 8;
	gl.glGetIntegerv(eGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numTexUnits);
	create_array_uninit(pipe.Textures, numTexUnits);

	GLenum activeTexture = eGL_TEXTURE0;
	gl.glGetIntegerv(eGL_ACTIVE_TEXTURE, (GLint*)&activeTexture);

	// GL is ass-backwards in its handling of texture units. When a shader is active
	// the types in the glsl samplers inform which targets are used from which texture units
	//
	// So texture unit 5 can have a 2D bound (texture 52) and a Cube bound (texture 77).
	// * if a uniform sampler2D has value 5 then the 2D texture is used, and we sample from 52
	// * if a uniform samplerCube has value 5 then the Cube texture is used, and we sample from 77
	// It's illegal for both a sampler2D and samplerCube to both have the same value (or any two
	// different types). It makes it all rather pointless and needlessly complex.
	//
	// What we have to do then, is consider the program, look at the values of the uniforms, and
	// then get the appropriate current binding based on the uniform type. We can warn/alert the
	// user if we hit the illegal case of two uniforms with different types but the same value
	//
	// Handling is different if no shaders are active, but we don't consider that case.


	// prefetch uniform values in GetShader()
	ShaderReflection *refls[6];
	for(size_t s=0; s < progDetails.shaders.size(); s++)
		refls[s] = GetShader(progDetails.shaders[s]);

	for(GLint unit=0; unit < numTexUnits; unit++)
	{
		GLenum binding = eGL_UNKNOWN_ENUM;
		GLenum target = eGL_UNKNOWN_ENUM;
		
		for(size_t s=0; s < progDetails.shaders.size(); s++)
		{
			if(refls[s] == NULL) continue;

			for(int32_t r=0; r < refls[s]->Resources.count; r++)
			{
				// bindPoint is the uniform value for this sampler
				if(refls[s]->Resources[r].bindPoint == (uint32_t)unit)
				{
					GLenum t = eGL_UNKNOWN_ENUM;

					switch(refls[s]->Resources[r].resType)
					{
						case eResType_None:
							t = eGL_UNKNOWN_ENUM;
							break;
						case eResType_Buffer:
							t = eGL_TEXTURE_BINDING_BUFFER;
							break;
						case eResType_Texture1D:
							t = eGL_TEXTURE_BINDING_1D;
							target = eGL_TEXTURE_1D;
							break;
						case eResType_Texture1DArray:
							t = eGL_TEXTURE_BINDING_1D_ARRAY;
							target = eGL_TEXTURE_1D_ARRAY;
							break;
						case eResType_Texture2D:
							t = eGL_TEXTURE_BINDING_2D;
							target = eGL_TEXTURE_2D;
							break;
						case eResType_Texture2DArray:
							t = eGL_TEXTURE_BINDING_2D_ARRAY;
							target = eGL_TEXTURE_2D_ARRAY;
							break;
						case eResType_Texture2DMS:
							t = eGL_TEXTURE_BINDING_2D_MULTISAMPLE;
							target = eGL_TEXTURE_2D_MULTISAMPLE;
							break;
						case eResType_Texture2DMSArray:
							t = eGL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY;
							target = eGL_TEXTURE_2D_MULTISAMPLE_ARRAY;
							break;
						case eResType_Texture3D:
							t = eGL_TEXTURE_BINDING_3D;
							target = eGL_TEXTURE_3D;
							break;
						case eResType_TextureCube:
							t = eGL_TEXTURE_BINDING_CUBE_MAP;
							target = eGL_TEXTURE_CUBE_MAP;
							break;
						case eResType_TextureCubeArray:
							t = eGL_TEXTURE_BINDING_CUBE_MAP_ARRAY;
							target = eGL_TEXTURE_CUBE_MAP_ARRAY;
							break;
					}

					if(binding == eGL_UNKNOWN_ENUM)
					{
						binding = t;
					}
					else if(binding == t)
					{
						// two uniforms with the same type pointing to the same slot is fine
						binding = t;
					}
					else if(binding != t)
					{
						RDCWARN("Two uniforms pointing to texture unit %d with types %s and %s", unit, ToStr::Get(binding).c_str(), ToStr::Get(t).c_str());
					}
				}
			}
		}

		if(binding != eGL_UNKNOWN_ENUM)
		{
			gl.glActiveTexture(GLenum(eGL_TEXTURE0+unit));

			GLuint tex;
			gl.glGetIntegerv(binding, (GLint *)&tex);

			// very bespoke/specific
			GLint firstSlice = 0;
			gl.glGetTexParameteriv(target, eGL_TEXTURE_VIEW_MIN_LEVEL, &firstSlice);

			pipe.Textures[unit].Resource = rm->GetOriginalID(rm->GetID(TextureRes(tex)));
			pipe.Textures[unit].FirstSlice = (uint32_t)firstSlice;
		}
		else
		{
			// what should we do in this case? there could be something bound just not used,
			// it'd be nice to return that
		}
	}

	gl.glActiveTexture(activeTexture);

	GLuint curFBO = 0;
	gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&curFBO);
	
	GLint numCols = 8;
	gl.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols);

	GLuint curCol[32] = { 0 };
	GLuint curDepth = 0;
	GLuint curStencil = 0;

	RDCASSERT(numCols <= 32);

	// we should never bind the true default framebuffer - if the app did, we will have our fake bound
	RDCASSERT(curFBO != 0);

	{
		for(GLint i=0; i < numCols; i++)
			gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curCol[i]);
		gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curDepth);
		gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curStencil);
	}

	pipe.m_FB.FBO = rm->GetOriginalID(rm->GetID(FramebufferRes(curFBO)));
	create_array_uninit(pipe.m_FB.Color, numCols);
	for(GLint i=0; i < numCols; i++)
		pipe.m_FB.Color[i] = rm->GetOriginalID(rm->GetID(TextureRes(curCol[i])));

	pipe.m_FB.Depth = rm->GetOriginalID(rm->GetID(TextureRes(curDepth)));
	pipe.m_FB.Stencil = rm->GetOriginalID(rm->GetID(TextureRes(curStencil)));
}
Beispiel #5
0
HANDLE WrappedOpenGL::wglDXRegisterObjectNV(HANDLE hDevice, void *dxObject, GLuint name,
                                            GLenum type, GLenum access)
{
  RDCASSERT(IsCaptureMode(m_State));

  ID3D11Resource *real = UnwrapDXResource(dxObject);

  if(real == NULL)
  {
    SetLastError(ERROR_OPEN_FAILED);
    return 0;
  }

  WrappedHANDLE *wrapped = new WrappedHANDLE();

  if(type == eGL_RENDERBUFFER)
    wrapped->res = RenderbufferRes(GetCtx(), name);
  else if(type == eGL_NONE)
    wrapped->res = BufferRes(GetCtx(), name);
  else
    wrapped->res = TextureRes(GetCtx(), name);

  GLResourceRecord *record = GetResourceManager()->GetResourceRecord(wrapped->res);

  if(!record)
  {
    RDCERR("Unrecognised object with type %x and name %u", type, name);
    delete wrapped;
    return NULL;
  }

  SERIALISE_TIME_CALL(wrapped->real =
                          m_Real.wglDXRegisterObjectNV(hDevice, real, name, type, access));

  {
    RDCASSERT(record);

    USE_SCRATCH_SERIALISER();
    SCOPED_SERIALISE_CHUNK(gl_CurChunk);
    Serialise_wglDXRegisterObjectNV(ser, wrapped->res, type, dxObject);

    record->AddChunk(scope.Get());
  }

  if(type != eGL_NONE)
  {
    ResourceFormat fmt;
    uint32_t width = 0, height = 0, depth = 0, mips = 0, layers = 0, samples = 0;
    GetDXTextureProperties(dxObject, fmt, width, height, depth, mips, layers, samples);

    // defined as arrays mostly for Coverity code analysis to stay calm about passing
    // them to the *TexParameter* functions
    GLint maxlevel[4] = {GLint(mips - 1), 0, 0, 0};

    m_Real.glTextureParameteriEXT(wrapped->res.name, type, eGL_TEXTURE_MAX_LEVEL, GLint(mips - 1));

    ResourceId texId = record->GetResourceID();
    m_Textures[texId].resource = wrapped->res;
    m_Textures[texId].curType = type;
    m_Textures[texId].width = width;
    m_Textures[texId].height = height;
    m_Textures[texId].depth = RDCMAX(depth, samples);
    m_Textures[texId].samples = samples;
    m_Textures[texId].dimension = 2;
    if(type == eGL_TEXTURE_1D || type == eGL_TEXTURE_1D_ARRAY)
      m_Textures[texId].dimension = 1;
    else if(type == eGL_TEXTURE_3D)
      m_Textures[texId].dimension = 3;

    m_Textures[texId].internalFormat = MakeGLFormat(fmt);
  }

  return wrapped;
}
Beispiel #6
0
bool WrappedOpenGL::Serialise_glObjectLabel(GLenum identifier, GLuint name, GLsizei length,
                                            const GLchar *label)
{
  ResourceId liveid;

  bool extvariant = false;

  string Label;
  if(m_State >= WRITING)
  {
    if(length == 0)
      Label = "";
    else
      Label = string(label, label + (length > 0 ? length : strlen(label)));

    switch(identifier)
    {
      case eGL_TEXTURE: liveid = GetResourceManager()->GetID(TextureRes(GetCtx(), name)); break;
      case eGL_BUFFER_OBJECT_EXT: extvariant = true;
      case eGL_BUFFER: liveid = GetResourceManager()->GetID(BufferRes(GetCtx(), name)); break;
      case eGL_PROGRAM_OBJECT_EXT: extvariant = true;
      case eGL_PROGRAM: liveid = GetResourceManager()->GetID(ProgramRes(GetCtx(), name)); break;
      case eGL_PROGRAM_PIPELINE_OBJECT_EXT: extvariant = true;
      case eGL_PROGRAM_PIPELINE:
        liveid = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), name));
        break;
      case eGL_VERTEX_ARRAY_OBJECT_EXT: extvariant = true;
      case eGL_VERTEX_ARRAY:
        liveid = GetResourceManager()->GetID(VertexArrayRes(GetCtx(), name));
        break;
      case eGL_SHADER_OBJECT_EXT: extvariant = true;
      case eGL_SHADER: liveid = GetResourceManager()->GetID(ShaderRes(GetCtx(), name)); break;
      case eGL_QUERY_OBJECT_EXT: extvariant = true;
      case eGL_QUERY: liveid = GetResourceManager()->GetID(QueryRes(GetCtx(), name)); break;
      case eGL_TRANSFORM_FEEDBACK:
        liveid = GetResourceManager()->GetID(FeedbackRes(GetCtx(), name));
        break;
      case eGL_SAMPLER: liveid = GetResourceManager()->GetID(SamplerRes(GetCtx(), name)); break;
      case eGL_RENDERBUFFER:
        liveid = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), name));
        break;
      case eGL_FRAMEBUFFER:
        liveid = GetResourceManager()->GetID(FramebufferRes(GetCtx(), name));
        break;
      default: RDCERR("Unhandled namespace in glObjectLabel");
    }
  }

  SERIALISE_ELEMENT(GLenum, Identifier, identifier);
  SERIALISE_ELEMENT(ResourceId, id, liveid);
  SERIALISE_ELEMENT(uint32_t, Length, length);
  SERIALISE_ELEMENT(bool, HasLabel, label != NULL);

  m_pSerialiser->SerialiseString("label", Label);

  if(m_State == READING && GetResourceManager()->HasLiveResource(id))
  {
    GLResource res = GetResourceManager()->GetLiveResource(id);

    if(extvariant && m_Real.glLabelObjectEXT)
      m_Real.glLabelObjectEXT(Identifier, res.name, Length, HasLabel ? Label.c_str() : NULL);
    else
      m_Real.glObjectLabel(Identifier, res.name, Length, HasLabel ? Label.c_str() : NULL);
  }

  return true;
}
Beispiel #7
0
bool WrappedOpenGL::Serialise_glObjectLabel(SerialiserType &ser, GLenum identifier, GLuint name,
                                            GLsizei length, const GLchar *label)
{
  GLResource Resource;
  std::string Label;

  if(ser.IsWriting())
  {
    // we share implementations between KHR_debug and EXT_debug_label, however KHR_debug follows the
    // pattern elsewhere (e.g. in glShaderSource) of a length of -1 meaning indeterminate
    // NULL-terminated length, but EXT_debug_label takes length of 0 to mean that.
    GLsizei realLength = length;
    if(gl_CurChunk == GLChunk::glLabelObjectEXT && length == 0)
      realLength = -1;

    // if length is negative (after above twiddling), it's taken from strlen and the label must be
    // NULL-terminated
    if(realLength < 0)
      realLength = label ? (GLsizei)strlen(label) : 0;

    if(realLength == 0 || label == NULL)
      Label = "";
    else
      Label = std::string(label, label + realLength);

    switch(identifier)
    {
      case eGL_TEXTURE: Resource = TextureRes(GetCtx(), name); break;
      case eGL_BUFFER_OBJECT_EXT:
      case eGL_BUFFER: Resource = BufferRes(GetCtx(), name); break;
      case eGL_PROGRAM_OBJECT_EXT:
      case eGL_PROGRAM: Resource = ProgramRes(GetCtx(), name); break;
      case eGL_PROGRAM_PIPELINE_OBJECT_EXT:
      case eGL_PROGRAM_PIPELINE: Resource = ProgramPipeRes(GetCtx(), name); break;
      case eGL_VERTEX_ARRAY_OBJECT_EXT:
      case eGL_VERTEX_ARRAY: Resource = VertexArrayRes(GetCtx(), name); break;
      case eGL_SHADER_OBJECT_EXT:
      case eGL_SHADER: Resource = ShaderRes(GetCtx(), name); break;
      case eGL_QUERY_OBJECT_EXT:
      case eGL_QUERY: Resource = QueryRes(GetCtx(), name); break;
      case eGL_TRANSFORM_FEEDBACK: Resource = FeedbackRes(GetCtx(), name); break;
      case eGL_SAMPLER: Resource = SamplerRes(GetCtx(), name); break;
      case eGL_RENDERBUFFER: Resource = RenderbufferRes(GetCtx(), name); break;
      case eGL_FRAMEBUFFER: Resource = FramebufferRes(GetCtx(), name); break;
      default: RDCERR("Unhandled namespace in glObjectLabel");
    }
  }

  SERIALISE_ELEMENT(Resource);
  SERIALISE_ELEMENT(length);
  SERIALISE_ELEMENT(Label);

  SERIALISE_CHECK_READ_ERRORS();

  if(IsReplayingAndReading() && Resource.name)
  {
    ResourceId origId = GetResourceManager()->GetOriginalID(GetResourceManager()->GetID(Resource));

    GetResourceManager()->SetName(origId, Label);

    ResourceDescription &descr = GetReplay()->GetResourceDesc(origId);
    descr.SetCustomName(Label);
    AddResourceCurChunk(descr);
  }

  return true;
}