GNU Radio: Set minimum input/output buffer size for a Python block - gnuradio

I am writing my own GNU Radio block in Python, and I want to set a minimum buffer size for both (or either) the input and output buffers of that block.
Is there a function or piece of code that can do this?

You can only set the minimum output buffer size (that's not a problem; every input buffer is the output buffer of another block), using the gr.block.set_min_output_buffer(port, size) call, for example by doing:
by adding the call
def __init__(self):
gr.sync_block.__init__(self,
name="block_with_buffer",
in_sig=[numpy.float32],
out_sig=[numpy.float32])
self.set_min_output_buffer(2**20)
in your constructor, or
by calling
your_block_handle.set_min_output_buffer(2**20) in whatever python script you're using to set up your flow graph, or
by using GNU Radio Companion's "advanced" tab (in your block's property dialog) to set the minimum output buffer size.
However, GNU Radio forgot to wrap that call in its python block class. Hence, you currently can't use that with python blocks, sorry, only with C++ blocks. I'm currently writing a patch for that; if all goes well, you'll see this on the master branch soon :)

Related

What is the valid way to bind per-object uniform buffers (e.g. camera matrices)?

I have some simple vulkan app which have:
3 command buffers for each swapchain image (#1, #2, #3)
1 uniform buffer with projection matrix data
I want to bind uniform buffer once. i'm using command buffer #1 to bind uniform buffer:
begin();
bindDescriptorSets();
end();
submit();
waitIdle();
reset();
Then i record commands for each swapchain image (3 times):
begin()
bindVertexBuffers()
beginRenderPass()
bindPipeline()
draw()
endRenderPass()
end();
Drawing works as expected, but validation layer logs an error:
[ UNASSIGNED-CoreValidation-DrawState-DescriptorSetNotBound ] Object: 0x1a57aad7910 (Type = 6) | VkPipeline 0x21 uses set #0 but that set is not bound.
If i move the bindDescriptorSets(); line to the second recording block, like this:
begin()
bindDescriptorSets();
bindVertexBuffers()
beginRenderPass()
bindPipeline()
draw()
endRenderPass()
end();
Validation is OK, but there is no difference in rendering.
So, the question is: do i have to bind descriptor sets for each buffer recording? If yes, why does the app work fine when i'm binding descriptor sets once?
I believe it relates to the current state of the Vulkan application. Let's see what specification says about the state:
2.2.1. Queue Operation
Commands recorded in command buffers either perform actions (...), set state (bind pipelines, descriptor sets,
and buffers, set dynamic state, push constants, set render
pass/subpass state), or perform synchronization (...). Some commands
perform more than one of these tasks. State setting commands update
the current state of the command buffer.
Notice I marked in bold that binding a descriptor set is a state command.
You bind descriptor set to a command buffer end that buffer and submit. Next, you start other command buffers. Let's see again what specification tells us about the command buffers:
Command Buffers
Each command buffer manages state independently of other command buffers. There is no inheritance of state across primary
and secondary command buffers, or between secondary command buffers.
When a command buffer begins recording, all state in that command
buffer is undefined.
So the specification and layers tell you that you have to bind descriptors to every command buffer that uses that state. Why it works even with warnings? I don't know, probably your implementation allows it, but I wouldn't recommend to keep it as it is.

vkQueueSubmit() call includes a stageMask with VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT bit set when device does not have geometryShader feature enabled

First of all, I'm a total newbie with Vulkan (I'm using the binding provided by LWJGL). I know I should copy/paste more code, but I don't even know what would be relevant for now (so don't hesitate to ask me some specific piece of code).
I try to make something like that :
Use a ComputeShader to compute a buffer of pixel.
Use vkCmdCopyBufferToImage to directly copy this array into a framebuffer image.
So, no vertex/fragment shaders for now.
I allocated a Compute Pipeline, and a FrameBuffer. I have one {Queue/CommandPool/CommandBuffer} for Computation, and one other for Rendering.
When I try to submit the graphic queue with:
vkQueueSubmit(graphicQueue, renderPipeline.getFrameSubmission().getSubmitInfo(imageIndex));
I obtain the following error message (from validation) :
ERROR OCCURED: Object: VK_NULL_HANDLE (Type = 0) | vkQueueSubmit() call includes a stageMask with VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT bit set when device does not have geometryShader feature enabled. The spec valid usage text states 'If the geometry shaders feature is not enabled, each element of pWaitDstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkSubmitInfo-pWaitDstStageMask-00076)
ERROR OCCURED: Object: VK_NULL_HANDLE (Type = 0) | vkQueueSubmit() call includes a stageMask with VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT and/or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT bit(s) set when device does not have tessellationShader feature enabled. The spec valid usage text states 'If the tessellation shaders feature is not enabled, each element of pWaitDstStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkSubmitInfo-pWaitDstStageMask-00077)
I tried to change the VkSubmitInfo.pWaitDstStageMask to different values (like VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT...) but nothing change.
So, what would be the best pWaitDstStageMask for my use case ?
Ok, I found my problem:
The pWaitDstStageMask must be an array with the same size than pWaitSemaphores.
I only putted 1 stage mask, for 2 semaphores.

Are there conditional blocks in GNU Radio?

I was wondering if there was a way to use If statements and such in Gnu Radio without having to go into the generated code. For example if you have a probe and if the value of said probe is 1, branch off to some blocks, and if the value of the probe is 0, branch off to another set of blocks.
Don't use probes to inspect signals. That is broken by design; if you want some stream to depend on another stream, threshold the "controlling" one (so that it is either 0 or 1) and then multiply with the other.

GNU Radio block with variable number of intputs/outputs

I am currently trying to do the signal processing of multiple channels in parallel using a custom source block. Up to now I created an OOT-source block which streams data for only one channel into one output perfectly fine.
Now I am searching for a way to expand this module so that it can support a higher number of channels ( = outputs of the source block; up to 64) in parallel. Because the protocol used to pull the samples pulls them all at one it is not possible to use more instances of the same source block.
Things I have found so far:
A pdf which seems to explain exactly what to do already but it seems that it is outdated and that this functionality is no longer supported under GNU Radio.
The description of a feature which should be implemented in the future.
Is there are known solution or workaround for this problem?
Look at the add block: It has configurable many inputs!
Now, the trick here is threefold:
define an io_signature as input and output that allows for adjustable numbers. If you use gr_modtool add to create a new block, your io_signatures will be filled with <+MIN_IN+>, <+MAX_IN+>, <+MIN_OUT+> and <+MAX_OUT+>. Adjust these to reflect your actual minimum and maximum in- and output port numbers. If you want to have 1 to infinity inputs, use 1, -1.
in your (general_)work method, check for the number of inputs by doing something like ninputs = input_items.size(), and for the number of outputs by doing noutputs = output_items.size().
(optionally, if you want to use GRC) modify the <sink>/<source> definitions in your block GRC XML:
<sink>
<name>in</name>
<type>complex</type>
<nports>$num_inputs</nports>
</sink>
num_inputs could be a block parameter; compare the add_XX block source code.

How to reset OpenGL program's uniform attribute value to default?

Let's say I have an OpenGL program that has a uniform attribute "diffuseColor". I have set it as following:
GLint location = glGetUniformLocation(handle, "diffuseColor");
glUniform3f(location, 1, 0, 0);
Now I would like to return it to the default value, which is encoded in the shader code. I do not have access to the source code, but I can call OpenGL API functions on the compiled program. Is there a way to read default value and set it with glUniform3f? Or even better, is there a something like glResetUniform3f(GLint loc)?
Uniform initializers are applied upon linking the program. The value can then be read using glGetUniformfv/glGetUniformiv. There is no way to read the initial value of the uniform after you changed the uniform value.
There is no way to reset a single uniform to its initial value, but relinking the program will reset all uniforms in it. Linking a program is a costly operation and should be avoided in between frames.