Skip to content

Commit 35a63c7

Browse files
committed
BasicRenderingEngine update
1 parent 794ff7c commit 35a63c7

File tree

7 files changed

+295
-67
lines changed

7 files changed

+295
-67
lines changed

src/main/java/com/sfengine/components/rendering/BasicFrameFactory.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,20 @@ public void update(SwapchainContext swapchainContext) {
8383
for (int i = 0; i < requiredImages; i++)
8484
frames.add(create(wrappers[i], jobContext.getJob(frameBuffers[i])));
8585
}
86+
else {
87+
long[] frameBuffers = swapchainContext.getFrameBuffers();
88+
RenderJobContext jobContext = ContextUtil.getRenderJob(dict);
89+
jobContext.recreateJobs(frameBuffers);
90+
91+
VkFenceWrapper[] wrappers = VkFenceWrapperFactory.createWrapper(dict, requiredImages);
92+
93+
for (int i = 0; i < frames.size(); i++) {
94+
forgetFrame(i);
95+
}
96+
97+
for (int i = 0; i < requiredImages; i++)
98+
frames.set(i, create(wrappers[i], jobContext.getJob(frameBuffers[i])));
99+
}
86100

87101

88102
}

src/main/java/com/sfengine/components/rendering/BasicRenderingEngine.java

Lines changed: 0 additions & 64 deletions
This file was deleted.
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
package com.sfengine.components.rendering;
2+
3+
import com.sfengine.components.contexts.DefaultContexts;
4+
import com.sfengine.components.contexts.framebufferfactory.BasicFrameBufferFactoryContextFactory;
5+
import com.sfengine.components.contexts.renderjob.BasicRenderJobContext;
6+
import com.sfengine.components.contexts.renderjob.BasicRenderJobContextFactory;
7+
import com.sfengine.components.contexts.swapchain.BasicSwapchainContextFactory;
8+
import com.sfengine.components.resources.MemoryBin;
9+
import com.sfengine.components.window.CFrame;
10+
import com.sfengine.core.context.ContextDictionary;
11+
import com.sfengine.core.context.ContextUtil;
12+
import com.sfengine.core.context.swapchain.SwapchainContext;
13+
import com.sfengine.core.engine.Engine;
14+
import com.sfengine.core.engine.EngineFactory;
15+
import com.sfengine.core.engine.EngineTask;
16+
import com.sfengine.core.rendering.*;
17+
import com.sfengine.core.rendering.frames.FrameFactory;
18+
import com.sfengine.core.result.VulkanException;
19+
import com.sfengine.core.synchronization.Dependency;
20+
import com.sfengine.core.synchronization.DependencyFence;
21+
import com.sfengine.core.synchronization.VkFence.VkFenceSupervisor;
22+
import com.sfengine.core.synchronization.VkFence.VkFenceSupervisorTask;
23+
import junit.framework.Assert;
24+
import org.lwjgl.vulkan.VkDevice;
25+
import org.lwjgl.vulkan.VkPhysicalDevice;
26+
import org.lwjgl.vulkan.VkQueue;
27+
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
28+
29+
import java.nio.IntBuffer;
30+
import java.util.*;
31+
32+
import static com.sfengine.core.result.VulkanResult.validate;
33+
import static org.lwjgl.system.MemoryUtil.memAllocInt;
34+
import static org.lwjgl.system.MemoryUtil.memFree;
35+
import static org.lwjgl.vulkan.KHRSurface.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
36+
import static org.lwjgl.vulkan.KHRSurface.vkGetPhysicalDeviceSurfaceSupportKHR;
37+
import static org.lwjgl.vulkan.VK10.*;
38+
39+
public class CBasicRenderingEngine implements RenderingEngine {
40+
41+
private final Engine engine = EngineFactory.getEngine();
42+
private CFrame frame;
43+
44+
private final Map<Long, PipelineContainer> pipelines = Collections.synchronizedMap(new HashMap<>());
45+
private final Set<Updatable> upds = Collections.synchronizedSet(new HashSet<>());
46+
47+
private RenderPass renderPass;
48+
49+
private final MemoryBin bin = new MemoryBin();
50+
private List<EngineTask> tickTasks = new ArrayList<EngineTask>();
51+
52+
private final DependencyFence created = new DependencyFence();
53+
54+
private volatile ContextDictionary dict;
55+
private volatile FrameFactory frameFactory;
56+
57+
public CBasicRenderingEngine(ContextDictionary dict, CFrame frame) {
58+
this.dict = dict;
59+
this.frame = frame;
60+
61+
List<Dependency> deps = DefaultContexts.getDependencies();
62+
deps.add(frame.getDependency());
63+
64+
Dependency[] depsArr = new Dependency[deps.size()];
65+
for (int i = 0; i < deps.size(); i++)
66+
depsArr[i] = deps.get(i);
67+
68+
engine.addConfig(() -> {
69+
initialize(dict);
70+
}, depsArr);
71+
}
72+
73+
private void record() {
74+
75+
}
76+
77+
private void initialize(ContextDictionary dict) {
78+
RenderingEngineFactory.setRenderingEngine(frame, this);
79+
80+
Window window = frame.getWindow();
81+
82+
// Creating required vulkan objects.
83+
VkPhysicalDevice physicalDevice = ContextUtil.getPhysicalDevice(dict).getPhysicalDevice();
84+
ColorFormatAndSpace colorFormat = getColorFormat(window, physicalDevice);
85+
int renderQueueFamilyIndex = ContextUtil.getQueueFamily(dict).getQueueFamilyIndex();
86+
87+
// Checking the window support
88+
checkSupport(window, physicalDevice, renderQueueFamilyIndex);
89+
90+
renderPass = RenderPassFactory.createRenderPass(dict, "RenderPass1");
91+
bin.add(renderPass);
92+
93+
CommandBufferFactory basicCMD =
94+
new CommandBufferFactory(dict, (cmd, framebuffer) -> {
95+
renderPass.record(cmd, framebuffer);
96+
97+
Set<Long> kpipelines = null;
98+
synchronized (pipelines) {
99+
kpipelines = pipelines.keySet();
100+
}
101+
for (long p : kpipelines) {
102+
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, p);
103+
104+
synchronized (pipelines.get(p)) {
105+
for (RenderObject obj : pipelines.get(p))
106+
obj.record(cmd, framebuffer);
107+
}
108+
}
109+
110+
vkCmdEndRenderPass(cmd);
111+
}, renderQueueFamilyIndex, 0);
112+
dict.put(BasicFrameBufferFactoryContextFactory.createFrameBufferFactoryContext("BasicFBFactory", dict, renderPass.handle()));
113+
dict.put(BasicSwapchainContextFactory.createSwapchainContext("BasicSwapchain", dict, frame, renderPass.getAttachmentBlueprints(), colorFormat));
114+
115+
BasicRenderJobContext renderJobContext =
116+
BasicRenderJobContextFactory.createContext("helloCube", basicCMD, dict, () -> {
117+
synchronized (upds) {
118+
for (Updatable u : upds)
119+
u.update();
120+
}
121+
});
122+
dict.put(renderJobContext);
123+
124+
VkFenceSupervisor vksupervisor = new VkFenceSupervisor();
125+
VkFenceSupervisorTask supTask = new VkFenceSupervisorTask(vksupervisor);
126+
engine.addTickTask(supTask);
127+
tickTasks.add(supTask);
128+
129+
frameFactory = new BasicFrameFactory(dict, vksupervisor);
130+
131+
engine.addTask(()-> {
132+
Presenter presenter = new Presenter(dict, frameFactory);
133+
engine.addTickTask(presenter);
134+
tickTasks.add(presenter);
135+
bin.add(presenter);
136+
137+
created.release();
138+
});
139+
}
140+
141+
142+
/**
143+
* Obtains suitable color format.
144+
*
145+
* @param window
146+
* @param physicalDevice
147+
* @return
148+
*/
149+
private static ColorFormatAndSpace getColorFormat(
150+
Window window, VkPhysicalDevice physicalDevice) {
151+
ColorFormatAndSpace colorFormat = new ColorFormatAndSpace(0, 0);
152+
try {
153+
colorFormat =
154+
RenderUtil.getNextColorFormatAndSpace(
155+
0,
156+
physicalDevice,
157+
window.getSurface(),
158+
VK_FORMAT_B8G8R8A8_UNORM,
159+
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR);
160+
} catch (VulkanException e) {
161+
e.printStackTrace();
162+
throw new AssertionError("Failed to choose color format and space.");
163+
}
164+
165+
return colorFormat;
166+
}
167+
168+
/**
169+
* Checks if the physical device supports KHR surface.
170+
*
171+
* @param window
172+
* @param physicalDevice
173+
* @param renderQueueFamilyIndex
174+
*/
175+
private static void checkSupport(
176+
Window window, VkPhysicalDevice physicalDevice, int renderQueueFamilyIndex) {
177+
IntBuffer pSupported = memAllocInt(1);
178+
int err =
179+
vkGetPhysicalDeviceSurfaceSupportKHR(
180+
physicalDevice, renderQueueFamilyIndex, window.getSurface(), pSupported);
181+
182+
try {
183+
validate(err, "Failed to check device KHR surface suport.");
184+
} catch (VulkanException e1) {
185+
e1.printStackTrace();
186+
}
187+
188+
if (pSupported.get(0) != VK_TRUE) {
189+
throw new AssertionError("Device does not support the khr swapchain.");
190+
}
191+
192+
memFree(pSupported);
193+
}
194+
195+
@Override
196+
public void add(RenderObject obj) {
197+
if (!pipelines.containsKey(obj.getPipeline()))
198+
pipelines.put(obj.getPipeline(), new PipelineContainer(obj.getPipeline()));
199+
200+
pipelines.get(obj.getPipeline()).add(obj);
201+
}
202+
203+
@Override
204+
public boolean remove(RenderObject obj) {
205+
if (!pipelines.containsKey(obj.getPipeline()))
206+
return false;
207+
208+
return pipelines.get(obj.getPipeline()).remove(obj);
209+
}
210+
211+
@Override
212+
public void requestUpdate() {
213+
throw new NotImplementedException();
214+
}
215+
216+
@Override
217+
public void forceUpdate() {
218+
SwapchainContext swc = ContextUtil.getSwapchain(dict);
219+
frameFactory.update(swc);
220+
}
221+
222+
@Override
223+
public void addUpdate(Updatable upd) {
224+
if (upd == null)
225+
throw new AssertionError("Updatable cannot be null.");
226+
upds.add(upd);
227+
}
228+
229+
@Override
230+
public void removeUpdate(Updatable upd) {
231+
upds.add(upd);
232+
}
233+
234+
@Override
235+
public RenderPass getRenderPass() {
236+
return renderPass;
237+
}
238+
239+
@Override
240+
public CFrame getCFrame() {
241+
return frame;
242+
}
243+
244+
@Override
245+
public void destroy() {
246+
247+
for (EngineTask task : tickTasks) {
248+
engine.removeTickTask(task);
249+
}
250+
251+
//TODO: free the rest of the resources
252+
253+
bin.destroy();
254+
}
255+
256+
@Override
257+
public Dependency getDependency() {
258+
return created;
259+
}
260+
}

src/main/java/com/sfengine/components/rendering/RenderPass.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,7 @@ public void record(VkCommandBuffer buffer, long frameBuffer) {
142142
}
143143
if (work != null) {
144144
work.record(buffer, frameBuffer);
145+
vkCmdEndRenderPass(buffer);
145146
}
146-
147-
vkCmdEndRenderPass(buffer);
148147
}
149148
}

src/main/java/com/sfengine/core/rendering/RenderingEngine.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.sfengine.core.rendering;
22

3+
import com.sfengine.components.rendering.RenderPass;
34
import com.sfengine.components.window.CFrame;
45
import com.sfengine.core.resources.Destroyable;
6+
import com.sfengine.core.synchronization.Dependable;
57

6-
public interface RenderingEngine extends Destroyable {
8+
public interface RenderingEngine extends Destroyable, Dependable {
79

810
void add(RenderObject obj);
911

@@ -13,5 +15,11 @@ public interface RenderingEngine extends Destroyable {
1315

1416
void forceUpdate();
1517

18+
void addUpdate(Updatable upd);
19+
20+
void removeUpdate(Updatable upd);
21+
22+
RenderPass getRenderPass();
23+
1624
CFrame getCFrame();
1725
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.sfengine.core.rendering;
2+
3+
public interface Updatable {
4+
5+
void update();
6+
7+
}

src/test/java/demos/hellowindow/GameLogic.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,9 @@ public void run() throws AssertionError {
2222
HardwareManager.init();
2323

2424
CFrame frame = new CFrame("MyFrame");
25+
26+
engine.addConfig(() -> {
27+
frame.getWindow().setVisible(true);
28+
}, frame.getDependency());
2529
}
2630
}

0 commit comments

Comments
 (0)