Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JBR-7305 Vulkan: Implement FILL_SPANS primitive for flat color rendering #406

Merged
merged 1 commit into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 2 additions & 61 deletions src/java.desktop/share/native/common/java2d/vulkan/VKRenderQueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint count = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FILL_SPANS");
VKRenderer_FillSpans(color, dstOps, count, (jint *)b);
SKIP_BYTES(b, count * BYTES_PER_SPAN);
}
break;
Expand All @@ -207,67 +208,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn6(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FILL_PARALLELOGRAM(%f, %f, %f, %f, %f, %f)",
x11, y11, dx21, dy21, dx12, dy12);

if (dstOps != NULL) {
VKSDOps *vksdOps = (VKSDOps *)dstOps;
VKGraphicsEnvironment* ge = VKGE_graphics_environment();
VKLogicalDevice* logicalDevice = &ge->devices[ge->enabledDeviceNum];
float width = vksdOps->width;
float height = vksdOps->height;
J2dRlsTraceLn2(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FILL_PARALLELOGRAM(W=%f, H=%f)",
width, height);
VKVertex* vertices = ARRAY_ALLOC(VKVertex, 4);
/* dx21
* (p1)---------(p2) | (p1)------
* |\ \ | | \ dy21
* | \ \ | dy12 | \
* | \ \| | (p2)-
* | (p4)---------(p3) (p4) |
* dx12 \ | dy12
* dy21 \ |
* -----(p3)
*/
float p1x = -1.0f + x11 / width;
float p1y = -1.0f + y11 / height;
float p2x = -1.0f + (x11 + dx21) / width;
float p2y = -1.0f + (y11 + dy21) / height;
float p3x = -1.0f + (x11 + dx21 + dx12) / width;
float p3y = -1.0f + (y11 + dy21 + dy12) / height;
float p4x = -1.0f + (x11 + dx12) / width;
float p4y = -1.0f + (y11 + dy12) / height;


ARRAY_PUSH_BACK(&vertices, ((VKVertex){p1x,p1y}));

ARRAY_PUSH_BACK(&vertices, ((VKVertex){p2x,p2y}));

ARRAY_PUSH_BACK(&vertices, ((VKVertex){p4x,p4y}));

ARRAY_PUSH_BACK(&vertices, ((VKVertex){p3x,p3y}));

VKBuffer* fillVertexBuffer = ARRAY_TO_VERTEX_BUF(vertices);
if (!fillVertexBuffer) {
J2dRlsTrace(J2D_TRACE_ERROR, "Cannot create vertex buffer\n")
break;
}
ARRAY_FREE(vertices);

ge->vkWaitForFences(logicalDevice->device, 1, &logicalDevice->inFlightFence, VK_TRUE, UINT64_MAX);
ge->vkResetFences(logicalDevice->device, 1, &logicalDevice->inFlightFence);

ge->vkResetCommandBuffer(logicalDevice->commandBuffer, 0);

VKRenderer_BeginRendering();

VKRenderer_ColorRender(
vksdOps->image,
color,
fillVertexBuffer->buffer, 4
);

VKRenderer_EndRendering(VK_FALSE, VK_FALSE);
}
VKRenderer_FillParallelogram(color, dstOps, x11, y11, dx21, dy21, dx12, dy12);
}
break;
case sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM:
Expand Down
148 changes: 147 additions & 1 deletion src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ VKRenderer* VKRenderer_CreateFillColorPoly() {

VkPipelineInputAssemblyStateCreateInfo inputAssembly = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
.primitiveRestartEnable = VK_FALSE
};

Expand Down Expand Up @@ -863,6 +863,152 @@ VKRenderer_FillRect(jint x, jint y, jint w, jint h)
}
}

void VKRenderer_FillParallelogram(jint color, VKSDOps *dstOps,
jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12)
{
if (dstOps == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "VKRenderer_FillParallelogram: current dest is null");
return;
}

VKSDOps *vksdOps = (VKSDOps *)dstOps;
VKGraphicsEnvironment* ge = VKGE_graphics_environment();
VKLogicalDevice* logicalDevice = &ge->devices[ge->enabledDeviceNum];
float width = vksdOps->width;
float height = vksdOps->height;
J2dRlsTraceLn2(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FILL_PARALLELOGRAM(W=%f, H=%f)",
width, height);
VKVertex* vertices = ARRAY_ALLOC(VKVertex, 6);
/* dx21
* (p1)---------(p2) | (p1)------
* |\ \ | | \ dy21
* | \ \ | dy12 | \
* | \ \| | (p2)-
* | (p4)---------(p3) (p4) |
* dx12 \ | dy12
* dy21 \ |
* -----(p3)
*/
float p1x = -1.0f + x11 / width;
float p1y = -1.0f + y11 / height;
float p2x = -1.0f + (x11 + dx21) / width;
float p2y = -1.0f + (y11 + dy21) / height;
float p3x = -1.0f + (x11 + dx21 + dx12) / width;
float p3y = -1.0f + (y11 + dy21 + dy12) / height;
float p4x = -1.0f + (x11 + dx12) / width;
float p4y = -1.0f + (y11 + dy12) / height;


ARRAY_PUSH_BACK(&vertices, ((VKVertex){p1x,p1y}));

ARRAY_PUSH_BACK(&vertices, ((VKVertex){p2x,p2y}));

ARRAY_PUSH_BACK(&vertices, ((VKVertex){p3x,p3y}));

ARRAY_PUSH_BACK(&vertices, ((VKVertex){p3x,p3y}));

ARRAY_PUSH_BACK(&vertices, ((VKVertex){p4x,p4y}));

ARRAY_PUSH_BACK(&vertices, ((VKVertex){p1x,p1y}));

VKBuffer* fillVertexBuffer = ARRAY_TO_VERTEX_BUF(vertices);
if (!fillVertexBuffer) {
J2dRlsTrace(J2D_TRACE_ERROR, "Cannot create vertex buffer\n")
return;
}
ARRAY_FREE(vertices);

ge->vkWaitForFences(logicalDevice->device, 1, &logicalDevice->inFlightFence, VK_TRUE, UINT64_MAX);
ge->vkResetFences(logicalDevice->device, 1, &logicalDevice->inFlightFence);

ge->vkResetCommandBuffer(logicalDevice->commandBuffer, 0);

VKRenderer_BeginRendering();

VKRenderer_ColorRender(
vksdOps->image,
color,
fillVertexBuffer->buffer, 6
);

VKRenderer_EndRendering(VK_FALSE, VK_FALSE);
}

void VKRenderer_FillSpans(jint color, VKSDOps *dstOps, jint spanCount, jint *spans)
{
if (dstOps == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "VKRenderer_FillSpans: current dest is null");
return;
}

if (spanCount == 0) {
return;
}

VKSDOps *vksdOps = (VKSDOps *)dstOps;
VKGraphicsEnvironment* ge = VKGE_graphics_environment();
VKLogicalDevice* logicalDevice = &ge->devices[ge->enabledDeviceNum];
float width = vksdOps->width;
float height = vksdOps->height;
J2dRlsTraceLn3(J2D_TRACE_VERBOSE, "VKRenderer_FillSpans(W=%f, H=%f, COUNT=%d)",
width, height, spanCount)

const int VERT_COUNT = spanCount * 6;
VKVertex* vertices = ARRAY_ALLOC(VKVertex, VERT_COUNT);
for (int i = 0; i < spanCount; i++) {
jfloat x1 = *(spans++);
jfloat y1 = *(spans++);
jfloat x2 = *(spans++);
jfloat y2 = *(spans++);

float p1x = -1.0f + x1 / width;
float p1y = -1.0f + y1 / height;
float p2x = -1.0f + x2 / width;
float p2y = p1y;
float p3x = p2x;
float p3y = -1.0f + y2 / height;
float p4x = p1x;
float p4y = p3y;

ARRAY_PUSH_BACK(&vertices, ((VKVertex){p1x,p1y}));

ARRAY_PUSH_BACK(&vertices, ((VKVertex){p2x,p2y}));

ARRAY_PUSH_BACK(&vertices, ((VKVertex){p3x,p3y}));

ARRAY_PUSH_BACK(&vertices, ((VKVertex){p3x,p3y}));

ARRAY_PUSH_BACK(&vertices, ((VKVertex){p4x,p4y}));

ARRAY_PUSH_BACK(&vertices, ((VKVertex){p1x,p1y}));
}

VKBuffer *fillVertexBuffer = ARRAY_TO_VERTEX_BUF(vertices);
if (!fillVertexBuffer) {
J2dRlsTrace(J2D_TRACE_ERROR, "Cannot create vertex buffer\n")
return;
}
ARRAY_FREE(vertices);

ge->vkWaitForFences(logicalDevice->device, 1, &logicalDevice->inFlightFence, VK_TRUE, UINT64_MAX);
ge->vkResetFences(logicalDevice->device, 1, &logicalDevice->inFlightFence);

ge->vkResetCommandBuffer(logicalDevice->commandBuffer, 0);

VKRenderer_BeginRendering();

VKRenderer_ColorRender(
vksdOps->image,
color,
fillVertexBuffer->buffer, VERT_COUNT
);

VKRenderer_EndRendering(VK_FALSE, VK_FALSE);
}

jboolean VK_CreateLogicalDeviceRenderers() {
VKGraphicsEnvironment* ge = VKGE_graphics_environment();
VKLogicalDevice* logicalDevice = &ge->devices[ge->enabledDeviceNum];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,10 @@ void VKRenderer_ColorRender(VKImage *destImage, uint32_t rgba, VkBuffer vertexBu
void VKRenderer_ColorRenderMaxRect(VKImage *destImage, uint32_t rgba);
// fill ops
void VKRenderer_FillRect(jint x, jint y, jint w, jint h);
void VKRenderer_FillParallelogram(jint color, VKSDOps *dstOps,
jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12);
void VKRenderer_FillSpans(jint color, VKSDOps *dstOps, jint spanCount, jint *spans);

#endif //VKRenderer_h_Included