diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp
index a93346cf08d17e96cfd32fef5e3f8cddabf19b61..27b255c3a3413d747ea8e351d26eb1671bf9ebef 100644
--- a/projects/first_mesh/src/main.cpp
+++ b/projects/first_mesh/src/main.cpp
@@ -63,18 +63,12 @@ int main(int argc, const char** argv) {
 
 	// an example attachment for passes that output to the window
 	const vkcv::AttachmentDescription present_color_attachment(
-		vkcv::AttachmentLayout::UNDEFINED,
-		vkcv::AttachmentLayout::COLOR_ATTACHMENT,
-		vkcv::AttachmentLayout::PRESENTATION,
 		vkcv::AttachmentOperation::STORE,
 		vkcv::AttachmentOperation::CLEAR,
 		core.getSwapchainImageFormat()
 	);
 	
 	const vkcv::AttachmentDescription depth_attachment(
-			vkcv::AttachmentLayout::UNDEFINED,
-			vkcv::AttachmentLayout::DEPTH_STENCIL_ATTACHMENT,
-			vkcv::AttachmentLayout::DEPTH_STENCIL_ATTACHMENT,
 			vkcv::AttachmentOperation::STORE,
 			vkcv::AttachmentOperation::CLEAR,
 			vk::Format::eD32Sfloat
@@ -100,17 +94,10 @@ int main(int argc, const char** argv) {
 		return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type);
 	});
 
-	vkcv::DescriptorSetConfig setConfig({
+	std::vector<vkcv::DescriptorBinding> descriptorBindings = {
 		vkcv::DescriptorBinding(vkcv::DescriptorType::IMAGE_SAMPLED,	1, vkcv::ShaderStage::FRAGMENT),
-		vkcv::DescriptorBinding(vkcv::DescriptorType::SAMPLER,			1, vkcv::ShaderStage::FRAGMENT)
-	});
-	vkcv::DescriptorSetHandle set = core.createDescriptorSet({ setConfig });
-
-	//only exemplary code for testing
-	for (int i = 0; i < 1001; i++) {
-		vkcv::DescriptorSetHandle furtherSets = core.createDescriptorSet({ setConfig });
-	}
-	//end of exemplary code
+		vkcv::DescriptorBinding(vkcv::DescriptorType::SAMPLER,			1, vkcv::ShaderStage::FRAGMENT) };
+	vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorBindings);
 
 	const vkcv::PipelineConfig trianglePipelineDefinition(
 		triangleShaderProgram,
@@ -118,7 +105,7 @@ int main(int argc, const char** argv) {
         UINT32_MAX,
 		trianglePass,
 		mesh.vertexGroups[0].vertexBuffer.attributes,
-		{ core.getDescriptorSet(set, 0) },
+		{ core.getDescriptorSet(descriptorSet).layout },
 		true);
 	vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition);
 	
@@ -137,16 +124,16 @@ int main(int argc, const char** argv) {
 		vkcv::SamplerAddressMode::REPEAT
 	);
 
-	std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = {
-		{ mesh.vertexGroups[0].vertexBuffer.attributes[0].offset, vertexBuffer.getHandle() },
-		{ mesh.vertexGroups[0].vertexBuffer.attributes[1].offset, vertexBuffer.getHandle() },
-		{ mesh.vertexGroups[0].vertexBuffer.attributes[2].offset, vertexBuffer.getHandle() }
+	const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = {
+		vkcv::VertexBufferBinding( mesh.vertexGroups[0].vertexBuffer.attributes[0].offset, vertexBuffer.getVulkanHandle() ),
+		vkcv::VertexBufferBinding( mesh.vertexGroups[0].vertexBuffer.attributes[1].offset, vertexBuffer.getVulkanHandle() ),
+		vkcv::VertexBufferBinding( mesh.vertexGroups[0].vertexBuffer.attributes[2].offset, vertexBuffer.getVulkanHandle() )
 	};
 
 	vkcv::DescriptorWrites setWrites;
 	setWrites.sampledImageWrites	= { vkcv::SampledImageDescriptorWrite(0, texture.getHandle()) };
 	setWrites.samplerWrites			= { vkcv::SamplerDescriptorWrite(1, sampler) };
-	core.writeResourceDescription(set, 0, setWrites);
+	core.writeResourceDescription(descriptorSet, 0, setWrites);
 
 	vkcv::ImageHandle depthBuffer = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight).getHandle();
 
@@ -156,6 +143,11 @@ int main(int argc, const char** argv) {
 
 	const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle();
 
+	const vkcv::Mesh renderMesh(vertexBufferBindings, indexBuffer.getVulkanHandle(), mesh.vertexGroups[0].numIndices);
+
+	vkcv::DescriptorSetUsage    descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle);
+	vkcv::DrawcallInfo          drawcall(renderMesh, { descriptorUsage });
+
 	auto start = std::chrono::system_clock::now();
 	while (window.isWindowOpen()) {
         vkcv::Window::pollEvents();
@@ -170,17 +162,20 @@ int main(int argc, const char** argv) {
 		cameraManager.getCamera().updateView(std::chrono::duration<double>(deltatime).count());
 		const glm::mat4 mvp = cameraManager.getCamera().getProjection() * cameraManager.getCamera().getView();
 
+		vkcv::PushConstantData pushConstantData((void*)&mvp, sizeof(glm::mat4));
+
+		const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer };
+		auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics);
+
 		core.recordDrawcallsToCmdStream(
+			cmdStream,
 			trianglePass,
 			trianglePipeline,
-			sizeof(mvp),
-			&mvp,
-			vertexBufferBindings,
-			indexBuffer.getHandle(),
-			mesh.vertexGroups[0].numIndices,
-			set,
-			0,
-			{ swapchainInput, depthBuffer });
+			pushConstantData,
+			{ drawcall },
+			renderTargets);
+		core.prepareSwapchainImageForPresent(cmdStream);
+		core.submitCommandStream(cmdStream);
 
 		core.endFrame();
 	}
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index 40e8a3e222419cd2ba823d6d7ef6f619e3cd20b8..b4a08659a94b2de63e7b47efc07b1cc8ba601b8d 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -79,9 +79,6 @@ int main(int argc, const char** argv) {
 
 	// an example attachment for passes that output to the window
 	const vkcv::AttachmentDescription present_color_attachment(
-		vkcv::AttachmentLayout::UNDEFINED,
-		vkcv::AttachmentLayout::COLOR_ATTACHMENT,
-		vkcv::AttachmentLayout::PRESENTATION,
 		vkcv::AttachmentOperation::STORE,
 		vkcv::AttachmentOperation::CLEAR,
 		core.getSwapchainImageFormat());
@@ -103,21 +100,21 @@ int main(int argc, const char** argv) {
 
 	const vkcv::PipelineConfig trianglePipelineDefinition(
 		triangleShaderProgram,
-		windowWidth,
-		windowHeight,
+		(uint32_t)windowWidth,
+		(uint32_t)windowHeight,
 		trianglePass,
 		{},
-		{});
+		{},
+		false);
+
 	vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition);
-	
+
 	if (!trianglePipeline)
 	{
 		std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl;
 		return EXIT_FAILURE;
 	}
 
-	std::vector<vkcv::VertexBufferBinding> vertexBufferBindings;
-
 	/*
 	 * BufferHandle triangleVertices = core.createBuffer(vertices);
 	 * BufferHandle triangleIndices = core.createBuffer(indices);
@@ -133,10 +130,15 @@ int main(int argc, const char** argv) {
 	 *
 	 * PipelineHandle trianglePipeline = core.CreatePipeline(trianglePipeline);
 	 */
-    auto start = std::chrono::system_clock::now();
+	auto start = std::chrono::system_clock::now();
 
 	vkcv::ImageHandle swapchainImageHandle = vkcv::ImageHandle::createSwapchainImageHandle();
 
+	const vkcv::Mesh renderMesh({}, triangleIndexBuffer.getVulkanHandle(), 3);
+	vkcv::DrawcallInfo drawcall(renderMesh, {});
+
+	const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle();
+
 	while (window.isWindowOpen())
 	{
         window.pollEvents();
@@ -147,17 +149,18 @@ int main(int argc, const char** argv) {
         cameraManager.getCamera().updateView(std::chrono::duration<double>(deltatime).count());
 		const glm::mat4 mvp = cameraManager.getCamera().getProjection() * cameraManager.getCamera().getView();
 
-	    core.recordDrawcallsToCmdStream(
+		vkcv::PushConstantData pushConstantData((void*)&mvp, sizeof(glm::mat4));
+		auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics);
+
+		core.recordDrawcallsToCmdStream(
+			cmdStream,
 			trianglePass,
 			trianglePipeline,
-			sizeof(mvp),
-			&mvp,
-			vertexBufferBindings,
-			triangleIndexBuffer.getHandle(),
-			3,
-			vkcv::DescriptorSetHandle(),
-			0,
-			{swapchainImageHandle});
+			pushConstantData,
+			{ drawcall },
+			{ swapchainInput });
+		core.prepareSwapchainImageForPresent(cmdStream);
+		core.submitCommandStream(cmdStream);
 	    
 	    core.endFrame();
 	}