From ba75d3d9ff725dcafe4aee73deccb004d95034c6 Mon Sep 17 00:00:00 2001 From: Nikita Gubarkov Date: Wed, 6 Aug 2025 01:22:41 +0200 Subject: [PATCH] JBR-7256 Vulkan: Implement FILL_PARALLELOGRAM primitive for flat color rendering (cherry picked from commit 57dc1a9e23cfc4c9839cac2335db91bfbce2ae1e) --- src/java.desktop/share/glsl/vulkan/color.vert | 7 +- .../common/java2d/vulkan/VKRenderQueue.c | 114 ++++++++++-------- .../native/common/java2d/vulkan/VKRenderer.c | 28 ++++- .../native/common/java2d/vulkan/VKRenderer.h | 2 +- .../native/common/java2d/vulkan/VKVertex.c | 12 +- .../native/common/java2d/vulkan/VKVertex.h | 6 +- 6 files changed, 98 insertions(+), 71 deletions(-) diff --git a/src/java.desktop/share/glsl/vulkan/color.vert b/src/java.desktop/share/glsl/vulkan/color.vert index 866be5df4683..76b151f2d82f 100644 --- a/src/java.desktop/share/glsl/vulkan/color.vert +++ b/src/java.desktop/share/glsl/vulkan/color.vert @@ -1,10 +1,13 @@ #version 450 +layout(push_constant) uniform PushConstants { + vec4 fragColor; +} pushConstants; + layout(location = 0) in vec2 inPosition; -layout(location = 1) in vec4 inColor; layout(location = 0) out flat vec4 fragColor; void main() { gl_Position = vec4(inPosition, 0.0, 1.0); - fragColor = inColor; + fragColor = pushConstants.fragColor; } \ No newline at end of file diff --git a/src/java.desktop/share/native/common/java2d/vulkan/VKRenderQueue.c b/src/java.desktop/share/native/common/java2d/vulkan/VKRenderQueue.c index 5eeaf1a67b1a..11fabbc14f9f 100644 --- a/src/java.desktop/share/native/common/java2d/vulkan/VKRenderQueue.c +++ b/src/java.desktop/share/native/common/java2d/vulkan/VKRenderQueue.c @@ -207,6 +207,67 @@ JNIEXPORT void JNICALL Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer J2dRlsTraceLn(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; + J2dRlsTraceLn(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); + } } break; case sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM: @@ -220,59 +281,6 @@ JNIEXPORT void JNICALL Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: FILL_AAPARALLELOGRAM(%f, %f, %f, %f, %f, %f)", x11, y11, dx21, dy21, dx12, dy12); - - // TODO: For now rendering bounding box. Implement correct rendering using shaders - 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; - J2dRlsTraceLn(J2D_TRACE_VERBOSE, - "VKRenderQueue_flushBuffer: FILL_AAPARALLELOGRAM(W=%f, H=%f)", - width, height); - VKCVertex* cVertices = ARRAY_ALLOC(VKCVertex, 4); - float px11 = -1.0f + x11 / width; - float py11 = -1.0f + y11 / height; - float px21 = -1.0f + (x11 + dx21) / width; - float py21 = -1.0f + (y11 + dy21) / height; - - ARRAY_PUSH_BACK(&cVertices, ((VKCVertex){px11, - py11, - RGBA_TO_L4(color)})); - ARRAY_PUSH_BACK(&cVertices, ((VKCVertex){px21, - py11, - RGBA_TO_L4(color)})); - ARRAY_PUSH_BACK(&cVertices, ((VKCVertex){px11, - py21, - RGBA_TO_L4(color)})); - ARRAY_PUSH_BACK(&cVertices, ((VKCVertex){px21, - py21, - RGBA_TO_L4(color)})); - J2dRlsTraceLn(J2D_TRACE_VERBOSE, - "VKRenderQueue_flushBuffer: FILL_AAPARALLELOGRAM(color=%x, px11=%f, py11=%f, px21=%f, py21=%f)", - color, px11, py11, px21, py21); - VKBuffer* fillVertexBuffer = ARRAY_TO_VERTEX_BUF(cVertices); - if (!fillVertexBuffer) { - J2dRlsTrace(J2D_TRACE_ERROR, "Cannot create vertex buffer\n"); - break; - } - ARRAY_FREE(cVertices); - - 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, - fillVertexBuffer->buffer, 4 - ); - - VKRenderer_EndRendering(VK_FALSE, VK_FALSE); - } } break; diff --git a/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.c b/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.c index 474ecd8f7bb0..d7f90c3d5fb1 100644 --- a/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.c +++ b/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.c @@ -352,7 +352,7 @@ VKRenderer* VKRenderer_CreateFillColorPoly() { }; VkPipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo}; - VKVertexDescr vertexDescr = VKVertex_GetCVertexDescr(); + VKVertexDescr vertexDescr = VKVertex_GetVertexDescr(); VkPipelineVertexInputStateCreateInfo vertexInputInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, .vertexBindingDescriptionCount = vertexDescr.bindingDescriptionCount, @@ -423,10 +423,17 @@ VKRenderer* VKRenderer_CreateFillColorPoly() { .pDynamicStates = dynamicStates }; + VkPushConstantRange pushConstantRange = { + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + .offset = 0, + .size = sizeof(float) * 4 + }; + VkPipelineLayoutCreateInfo pipelineLayoutInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .setLayoutCount = 0, - .pushConstantRangeCount = 0 + .pushConstantRangeCount = 1, + .pPushConstantRanges = &pushConstantRange }; if (ge->vkCreatePipelineLayout(device, &pipelineLayoutInfo, NULL, @@ -727,7 +734,7 @@ void VKRenderer_TextureRender(VKImage *destImage, VKImage *srcImage, VkBuffer ve } -void VKRenderer_ColorRender(VKImage *destImage, VkBuffer vertexBuffer, uint32_t vertexNum) +void VKRenderer_ColorRender(VKImage *destImage, uint32_t rgba, VkBuffer vertexBuffer, uint32_t vertexNum) { VKGraphicsEnvironment* ge = VKGE_graphics_environment(); VKLogicalDevice* logicalDevice = &ge->devices[ge->enabledDeviceNum]; @@ -748,6 +755,21 @@ void VKRenderer_ColorRender(VKImage *destImage, VkBuffer vertexBuffer, uint32_t ge->vkCmdBindPipeline(logicalDevice->commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, logicalDevice->fillColorPoly->graphicsPipeline); + struct PushConstants { + float r, g, b, a; + } pushConstants; + + pushConstants = (struct PushConstants){RGBA_TO_L4(rgba)}; + + ge->vkCmdPushConstants( + logicalDevice->commandBuffer, + logicalDevice->fillColorPoly->pipelineLayout, + VK_SHADER_STAGE_VERTEX_BIT, + 0, + sizeof(struct PushConstants), + &pushConstants + ); + VkBuffer vertexBuffers[] = {vertexBuffer}; VkDeviceSize offsets[] = {0}; ge->vkCmdBindVertexBuffers(logicalDevice->commandBuffer, 0, 1, vertexBuffers, offsets); diff --git a/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.h b/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.h index 72ad69ef68d6..f78d5b42667a 100644 --- a/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.h +++ b/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.h @@ -40,7 +40,7 @@ VKRenderer* VKRenderer_CreateFillMaxColorPoly(); void VKRenderer_BeginRendering(); void VKRenderer_EndRendering(VkBool32 notifyRenderFinish, VkBool32 waitForDisplayImage); void VKRenderer_TextureRender(VKImage *destImage, VKImage *srcImage, VkBuffer vertexBuffer, uint32_t vertexNum); -void VKRenderer_ColorRender(VKImage *destImage, VkBuffer vertexBuffer, uint32_t vertexNum); +void VKRenderer_ColorRender(VKImage *destImage, uint32_t rgba, VkBuffer vertexBuffer, uint32_t vertexNum); void VKRenderer_ColorRenderMaxRect(VKImage *destImage, uint32_t rgba); // fill ops void VKRenderer_FillRect(jint x, jint y, jint w, jint h); diff --git a/src/java.desktop/share/native/common/java2d/vulkan/VKVertex.c b/src/java.desktop/share/native/common/java2d/vulkan/VKVertex.c index 1591edb29172..495300ffddd4 100644 --- a/src/java.desktop/share/native/common/java2d/vulkan/VKVertex.c +++ b/src/java.desktop/share/native/common/java2d/vulkan/VKVertex.c @@ -62,11 +62,11 @@ VKVertexDescr VKVertex_GetTxVertexDescr() { }; } -VKVertexDescr VKVertex_GetCVertexDescr() { +VKVertexDescr VKVertex_GetVertexDescr() { static VkVertexInputBindingDescription bindingDescriptions[] = { { .binding = 0, - .stride = sizeof(VKCVertex), + .stride = sizeof(VKVertex), .inputRate = VK_VERTEX_INPUT_RATE_VERTEX } }; @@ -76,13 +76,7 @@ VKVertexDescr VKVertex_GetCVertexDescr() { .binding = 0, .location = 0, .format = VK_FORMAT_R32G32_SFLOAT, - .offset = offsetof(VKCVertex, px) - }, - { - .binding = 0, - .location = 1, - .format = VK_FORMAT_R32G32B32A32_SFLOAT, - .offset = offsetof(VKCVertex, r) + .offset = offsetof(VKVertex, px) } }; diff --git a/src/java.desktop/share/native/common/java2d/vulkan/VKVertex.h b/src/java.desktop/share/native/common/java2d/vulkan/VKVertex.h index cc933676ab5a..8c0c33dff583 100644 --- a/src/java.desktop/share/native/common/java2d/vulkan/VKVertex.h +++ b/src/java.desktop/share/native/common/java2d/vulkan/VKVertex.h @@ -53,11 +53,11 @@ typedef struct { typedef struct { float px, py; - float r, g, b, a; -} VKCVertex; +} VKVertex; + VKVertexDescr VKVertex_GetTxVertexDescr(); -VKVertexDescr VKVertex_GetCVertexDescr(); +VKVertexDescr VKVertex_GetVertexDescr();