Compare commits

...

6 Commits

Author SHA1 Message Date
bjorn e652ae67af Pass:plane; 2022-06-04 01:34:13 -07:00
bjorn ebc6d9d3a3 Pass:line; 2022-06-04 01:33:50 -07:00
bjorn a2668a1632 Fix canvas always trying to add depth buffer; 2022-06-04 01:33:11 -07:00
bjorn 2c2eada1f0 Fix pipeline creating the wrong render pass; 2022-06-04 01:31:16 -07:00
bjorn d9bf19da33 Fix texture memory allocation; 2022-06-04 01:30:51 -07:00
bjorn b2a3c59c42 Fix projection matrix; 2022-06-04 01:04:23 -07:00
5 changed files with 128 additions and 26 deletions

View File

@ -400,17 +400,29 @@ static void luax_readvertices(lua_State* L, int index, float* vertices, uint32_t
static int l_lovrPassPoints(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
Buffer* buffer = luax_totype(L, 2, Buffer);
float* vertices;
uint32_t count = luax_getvertexcount(L, 2);
lovrPassPoints(pass, count, &vertices);
luax_readvertices(L, 2, vertices, count);
return 0;
}
if (buffer || !lua_toboolean(L, 2)) {
//
} else {
float* vertices;
uint32_t count = luax_getvertexcount(L, 2);
lovrPassPoints(pass, count, &vertices);
luax_readvertices(L, 2, vertices, count);
}
static int l_lovrPassLine(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
float* vertices;
uint32_t count = luax_getvertexcount(L, 2);
lovrPassLine(pass, count, &vertices);
luax_readvertices(L, 2, vertices, count);
return 0;
}
static int l_lovrPassPlane(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
float transform[16];
int index = luax_readmat4(L, 2, transform, 2);
uint32_t hsegments = luax_optu32(L, index++, 1);
uint32_t vsegments = luax_optu32(L, index, hsegments);
lovrPassPlane(pass, transform, hsegments, vsegments);
return 0;
}
@ -590,6 +602,8 @@ const luaL_Reg lovrPass[] = {
{ "send", l_lovrPassSend },
{ "points", l_lovrPassPoints },
{ "line", l_lovrPassLine },
{ "plane", l_lovrPassPlane },
{ "clear", l_lovrPassClear },
{ "copy", l_lovrPassCopy },

View File

@ -477,19 +477,19 @@ bool gpu_texture_init(gpu_texture* texture, gpu_texture_info* info) {
switch (info->format) {
case GPU_FORMAT_D16:
texture->aspect = VK_IMAGE_ASPECT_DEPTH_BIT;
memoryType = GPU_MEMORY_TEXTURE_D16;
memoryType = (info->usage & GPU_TEXTURE_TRANSIENT) ? GPU_MEMORY_TEXTURE_LAZY_D16 : GPU_MEMORY_TEXTURE_D16;
break;
case GPU_FORMAT_D24S8:
texture->aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
memoryType = GPU_MEMORY_TEXTURE_D24S8;
memoryType = (info->usage & GPU_TEXTURE_TRANSIENT) ? GPU_MEMORY_TEXTURE_LAZY_D24S8 : GPU_MEMORY_TEXTURE_D24S8;
break;
case GPU_FORMAT_D32F:
texture->aspect = VK_IMAGE_ASPECT_DEPTH_BIT;
memoryType = GPU_MEMORY_TEXTURE_D32F;
memoryType = (info->usage & GPU_TEXTURE_TRANSIENT) ? GPU_MEMORY_TEXTURE_LAZY_D32F : GPU_MEMORY_TEXTURE_D32F;
break;
default:
texture->aspect = VK_IMAGE_ASPECT_COLOR_BIT;
memoryType = GPU_MEMORY_TEXTURE_COLOR;
memoryType = (info->usage & GPU_TEXTURE_TRANSIENT) ? GPU_MEMORY_TEXTURE_LAZY_COLOR : GPU_MEMORY_TEXTURE_COLOR;
break;
}
@ -543,7 +543,7 @@ bool gpu_texture_init(gpu_texture* texture, gpu_texture_info* info) {
vkGetImageMemoryRequirements(state.device, texture->handle, &requirements);
gpu_memory* memory = gpu_allocate(memoryType, requirements, &offset);
VK(vkBindImageMemory(state.device, texture->handle, memory->handle, 0), "Could not bind texture memory") {
VK(vkBindImageMemory(state.device, texture->handle, memory->handle, offset), "Could not bind texture memory") {
vkDestroyImage(state.device, texture->handle, NULL);
gpu_release(memory);
return false;
@ -1257,7 +1257,7 @@ bool gpu_pipeline_init_graphics(gpu_pipeline* pipeline, gpu_pipeline_info* info)
.samples = info->multisample.count,
.resolve = resolve,
.depth.format = convertFormat(info->depth.format, LINEAR),
.depth.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
.depth.layout = info->depth.format ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED,
.depth.load = GPU_LOAD_OP_CLEAR,
.depth.save = GPU_SAVE_OP_DISCARD
};
@ -2445,9 +2445,9 @@ static VkRenderPass getCachedRenderPass(gpu_pass_info* pass, bool compatible) {
VkSubpassDescription subpass = {
.colorAttachmentCount = count,
.pColorAttachments = references + 0,
.pResolveAttachments = pass->resolve ? references + count : NULL,
.pDepthStencilAttachment = depth ? references + pass->count - 1 : NULL
.pColorAttachments = &references[0],
.pResolveAttachments = pass->resolve ? &references[count] : NULL,
.pDepthStencilAttachment = depth ? &references[pass->count - 1] : NULL
};
VkRenderPassMultiviewCreateInfo multiview = {

View File

@ -608,7 +608,7 @@ MAF mat4 mat4_orthographic(mat4 m, float left, float right, float top, float bot
MAF mat4 mat4_perspective(mat4 m, float clipNear, float clipFar, float fovy, float aspect) {
float range = tanf(fovy * .5f) * clipNear;
float sx = (2.f * clipNear) / (range * aspect + range * aspect);
float sy = clipNear / range;
float sy = -clipNear / range;
float sz = -clipFar / (clipFar - clipNear);
float pz = (-clipFar * clipNear) / (clipFar - clipNear);
memset(m, 0, 16 * sizeof(float));

View File

@ -141,6 +141,12 @@ typedef enum {
DEFAULT_FORMAT_COUNT
} DefaultFormat;
typedef struct {
struct { float x, y, z; } position;
uint32_t normal;
struct { uint16_t u, v; } uv;
} ShapeVertex;
typedef struct {
gpu_draw_mode mode;
DefaultShader shader;
@ -306,6 +312,15 @@ bool lovrGraphicsInit(bool debug, bool vsync) {
gpu_clear_buffer(transfers, state.defaultBuffer->gpu, 0, 4096);
gpu_clear_texture(transfers, state.defaultTexture->gpu, (float[4]) { 1.f, 1.f, 1.f, 1.f }, 0, ~0u, 0, ~0u);
state.vertexFormats[VERTEX_SHAPE].gpu = (gpu_vertex_format) {
.bufferCount = 2,
.attributeCount = 3,
.bufferStrides[1] = sizeof(ShapeVertex),
.attributes[0] = { 1, 0, offsetof(ShapeVertex, position), GPU_TYPE_F32x3 },
.attributes[1] = { 1, 1, offsetof(ShapeVertex, normal), GPU_TYPE_UN10x3 },
.attributes[2] = { 1, 2, offsetof(ShapeVertex, uv), GPU_TYPE_UN16x2 }
};
state.vertexFormats[VERTEX_POINT].gpu = (gpu_vertex_format) {
.bufferCount = 2,
.attributeCount = 1,
@ -456,7 +471,8 @@ void lovrGraphicsSubmit(Pass** passes, uint32_t count) {
}
if (state.window) {
state.window->gpu = state.window->renderView = NULL;
state.window->gpu = NULL;
state.window->renderView = NULL;
}
// Allocate a few extra stream handles for any internal passes we sneak in
@ -1308,13 +1324,15 @@ Pass* lovrGraphicsGetPass(PassInfo* info) {
if (canvas->depth.texture) {
target.depth.texture = canvas->depth.texture->renderView;
} else {
} else if (canvas->depth.format) {
target.depth.texture = getAttachment(target.size, main->depth, canvas->depth.format, false, canvas->samples);
}
target.depth.load = target.depth.stencilLoad = (gpu_load_op) canvas->depth.load;
target.depth.save = canvas->depth.texture ? GPU_SAVE_OP_SAVE : GPU_SAVE_OP_DISCARD;
target.depth.clear.depth = canvas->depth.clear;
if (target.depth.texture) {
target.depth.load = target.depth.stencilLoad = (gpu_load_op) canvas->depth.load;
target.depth.save = canvas->depth.texture ? GPU_SAVE_OP_SAVE : GPU_SAVE_OP_DISCARD;
target.depth.clear.depth = canvas->depth.clear;
}
gpu_render_begin(pass->stream, &target);
@ -1992,15 +2010,83 @@ static void lovrPassDraw(Pass* pass, Draw* draw) {
pass->drawCount++;
}
void lovrPassPoints(Pass* pass, uint32_t count, float** vertices) {
void lovrPassPoints(Pass* pass, uint32_t count, float** points) {
lovrPassDraw(pass, &(Draw) {
.mode = GPU_DRAW_POINTS,
.vertex.format = VERTEX_POINT,
.vertex.pointer = (void**) vertices,
.vertex.pointer = (void**) points,
.vertex.count = count
});
}
void lovrPassLine(Pass* pass, uint32_t count, float** points) {
uint16_t* indices;
lovrPassDraw(pass, &(Draw) {
.mode = GPU_DRAW_LINES,
.vertex.format = VERTEX_POINT,
.vertex.pointer = (void**) points,
.vertex.count = count,
.index.pointer = (void**) &indices,
.index.count = 2 * (count - 1)
});
for (uint32_t i = 0; i < count - 1; i++) {
indices[2 * i + 0] = i;
indices[2 * i + 1] = i + 1;
}
}
static inline uint32_t packNormal(float nx, float ny, float nz) {
uint32_t n = 0;
n |= (uint32_t) (nx * 1023.f) << 20;
n |= (uint32_t) (ny * 1023.f) << 10;
n |= (uint32_t) (nz * 1023.f) << 0;
return n;
}
void lovrPassPlane(Pass* pass, float* transform, uint32_t hsegments, uint32_t vsegments) {
ShapeVertex* vertices;
uint16_t* indices;
uint32_t vertexCount = (hsegments + 1) * (vsegments + 1);
uint32_t indexCount = (hsegments * vsegments) * 6;
lovrPassDraw(pass, &(Draw) {
.mode = GPU_DRAW_TRIANGLES,
.transform = transform,
.vertex.format = VERTEX_SHAPE,
.vertex.pointer = (void**) &vertices,
.vertex.count = vertexCount,
.index.pointer = (void**) &indices,
.index.count = indexCount
});
for (uint32_t y = 0, v = 0; y <= vsegments; y++) {
for (uint32_t x = 0; x <= hsegments; x++, v++) {
vertices[v].position.x = -.5f + (float) x / hsegments;
vertices[v].position.y = .5f - (float) y / vsegments;
vertices[v].position.z = 0.f;
vertices[v].normal = packNormal(0.f, 0.f, 1.f);
vertices[v].uv.u = (uint16_t) ((float) x / hsegments * 65535.f);
vertices[v].uv.v = (uint16_t) ((float) y / vsegments * 65535.f);
}
}
uint16_t skip = hsegments + 1;
for (uint32_t y = 0; y < vsegments; y++) {
for (uint32_t x = 0; x < hsegments; x++) {
uint16_t a = ((y + 0) * skip) + x + 0;
uint16_t b = ((y + 0) * skip) + x + 1;
uint16_t c = ((y + 1) * skip) + x + 0;
uint16_t d = ((y + 1) * skip) + x + 1;
uint16_t cell[] = { a, b, c, c, b, d };
memcpy(indices, cell, sizeof(cell));
indices += COUNTOF(cell);
}
}
}
void lovrPassClearBuffer(Pass* pass, Buffer* buffer, uint32_t offset, uint32_t extent) {
if (extent == 0) return;
if (extent == ~0u) extent = buffer->size - offset;

View File

@ -389,6 +389,8 @@ void lovrPassSendBuffer(Pass* pass, const char* name, size_t length, uint32_t sl
void lovrPassSendTexture(Pass* pass, const char* name, size_t length, uint32_t slot, Texture* texture);
void lovrPassSendSampler(Pass* pass, const char* name, size_t length, uint32_t slot, Sampler* sampler);
void lovrPassPoints(Pass* pass, uint32_t count, float** vertices);
void lovrPassLine(Pass* pass, uint32_t count, float** vertices);
void lovrPassPlane(Pass* pass, float* transform, uint32_t hsegments, uint32_t vsegments);
void lovrPassClearBuffer(Pass* pass, Buffer* buffer, uint32_t offset, uint32_t extent);
void lovrPassClearTexture(Pass* pass, Texture* texture, float value[4], uint32_t layer, uint32_t layerCount, uint32_t level, uint32_t levelCount);
void lovrPassCopyDataToBuffer(Pass* pass, void* data, Buffer* buffer, uint32_t offset, uint32_t size);