Pass:clear;

This commit is contained in:
bjorn 2022-05-25 19:45:01 -07:00
parent a5f37f7d7d
commit 6771ff64b5
5 changed files with 54 additions and 3 deletions

View File

@ -234,6 +234,35 @@ static int l_lovrPassSend(lua_State* L) {
return luax_typeerror(L, 3, "Buffer, Texture, Sampler, or number/vector");
}
static int l_lovrPassClear(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
Buffer* buffer = luax_totype(L, 2, Buffer);
if (buffer) {
uint32_t offset = luax_optu32(L, 3, 0);
uint32_t extent = luax_optu32(L, 4, ~0u);
lovrPassClearBuffer(pass, buffer, offset, extent);
return 0;
}
Texture* texture = luax_totype(L, 2, Texture);
if (texture) {
float value[4];
luax_readcolor(L, 3, value);
int index = lua_istable(L, 3) ? 4 : 6;
uint32_t layer = luax_optu32(L, index++, 1) - 1;
uint32_t layerCount = luax_optu32(L, index++, ~0u);
uint32_t level = luax_optu32(L, index++, 1) - 1;
uint32_t levelCount = luax_optu32(L, index++, ~0u);
lovrPassClearTexture(pass, texture, value, layer, layerCount, level, levelCount);
return 0;
}
return luax_typeerror(L, 2, "Buffer or Texture");
}
const luaL_Reg lovrPass[] = {
{ "getType", l_lovrPassGetType },
{ "push", l_lovrPassPush },
@ -258,5 +287,6 @@ const luaL_Reg lovrPass[] = {
{ "setWinding", l_lovrPassSetWinding },
{ "setWireframe", l_lovrPassSetWireframe },
{ "send", l_lovrPassSend },
{ "clear", l_lovrPassClear },
{ NULL, NULL }
};

View File

@ -492,7 +492,7 @@ void gpu_copy_textures(gpu_stream* stream, gpu_texture* src, gpu_texture* dst, u
void gpu_copy_buffer_texture(gpu_stream* stream, gpu_buffer* src, gpu_texture* dst, uint32_t srcOffset, uint16_t dstOffset[4], uint16_t extent[3]);
void gpu_copy_texture_buffer(gpu_stream* stream, gpu_texture* src, gpu_buffer* dst, uint16_t srcOffset[4], uint32_t dstOffset, uint16_t extent[3]);
void gpu_clear_buffer(gpu_stream* stream, gpu_buffer* buffer, uint32_t offset, uint32_t size);
void gpu_clear_texture(gpu_stream* stream, gpu_texture* texture, uint16_t layer, uint16_t layerCount, uint16_t level, uint16_t levelCount, float value[4]);
void gpu_clear_texture(gpu_stream* stream, gpu_texture* texture, float value[4], uint32_t layer, uint32_t layerCount, uint32_t level, uint32_t levelCount);
void gpu_blit(gpu_stream* stream, gpu_texture* src, gpu_texture* dst, uint16_t srcOffset[4], uint16_t dstOffset[4], uint16_t srcExtent[3], uint16_t dstExtent[3], gpu_filter filter);
// Entry

View File

@ -1491,7 +1491,7 @@ void gpu_clear_buffer(gpu_stream* stream, gpu_buffer* buffer, uint32_t offset, u
vkCmdFillBuffer(stream->commands, buffer->handle, buffer->offset + offset, size, 0);
}
void gpu_clear_texture(gpu_stream* stream, gpu_texture* texture, uint16_t layer, uint16_t layerCount, uint16_t level, uint16_t levelCount, float value[4]) {
void gpu_clear_texture(gpu_stream* stream, gpu_texture* texture, float value[4], uint32_t layer, uint32_t layerCount, uint32_t level, uint32_t levelCount) {
VkImageSubresourceRange range = {
.aspectMask = texture->aspect,
.baseMipLevel = level,

View File

@ -241,7 +241,7 @@ bool lovrGraphicsInit(bool debug, bool vsync) {
gpu_stream* transfers = getTransfers();
float white[4] = { 1.f, 1.f, 1.f, 1.f };
gpu_clear_texture(transfers, state.defaultTexture->gpu, 0, 1, 0, 1, white);
gpu_clear_texture(transfers, state.defaultTexture->gpu, white, 0, ~0u, 0, ~0u);
if (!zeros) {
gpu_buffer* scratchpad = tempAlloc(gpu_sizeof_buffer());
@ -1521,6 +1521,25 @@ void lovrPassSendSampler(Pass* pass, const char* name, size_t length, uint32_t s
pass->bindingsDirty = true;
}
void lovrPassClearBuffer(Pass* pass, Buffer* buffer, uint32_t offset, uint32_t extent) {
if (extent == 0) return;
if (extent == ~0u) extent = buffer->size - offset;
lovrCheck(pass->info.type == PASS_TRANSFER, "This function can only be called on a transfer pass");
lovrCheck(!lovrBufferIsTemporary(buffer), "Temporary buffers can not be cleared");
lovrCheck(offset % 4 == 0, "Buffer clear offset must be a multiple of 4");
lovrCheck(extent % 4 == 0, "Buffer clear extent must be a multiple of 4");
lovrCheck(offset + extent <= buffer->size, "Buffer clear range goes past the end of the Buffer");
gpu_clear_buffer(pass->stream, buffer->gpu, offset, extent);
}
void lovrPassClearTexture(Pass* pass, Texture* texture, float value[4], uint32_t layer, uint32_t layerCount, uint32_t level, uint32_t levelCount) {
lovrCheck(pass->info.type == PASS_TRANSFER, "This function can only be called on a transfer pass");
lovrCheck(!texture->info.parent, "Texture views can not be cleared");
lovrCheck(texture->info.type == TEXTURE_3D || layer + layerCount <= texture->info.depth, "Texture clear range exceeds texture layer count");
lovrCheck(level + levelCount <= texture->info.mipmaps, "Texture clear range exceeds texture mipmap count");
gpu_clear_texture(pass->stream, texture->gpu, value, layer, layerCount, level, levelCount);
}
// Helpers
static void* tempAlloc(size_t size) {

View File

@ -372,3 +372,5 @@ void lovrPassSetWireframe(Pass* pass, bool wireframe);
void lovrPassSendBuffer(Pass* pass, const char* name, size_t length, uint32_t slot, Buffer* buffer, uint32_t offset, uint32_t extent);
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 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);